from webserver.handlers.api.compatibility.compatibility import ( CompatibilityWrapper, rename_keys_and_values, translate_json_body, ) from webserver.handlers.api.compatibility.v2_compatibility import ( V2APIAlertsHandler, V2APIAlertsStreamHandler, V2APIDxStatsHandler, V2APILookupCallHandler, V2APILookupGridHandler, V2APILookupSigRefHandler, V2APIOptionsHandler, V2APISolarConditionsHandler, V2APISpotHandler, V2APISpotsHandler, V2APISpotsStreamHandler, V2APIStatusHandler, ) # QRZ/HamQTH credentials were provided as query parameters in v1, but as headers in v2 _V1_QUERY_PARAMS_TO_V2_HEADERS = { "qrz_username": "X-QRZ-Username", "qrz_password": "X-QRZ-Password", "qrz_session_key": "X-QRZ-Session-Key", "hamqth_username": "X-HamQTH-Username", "hamqth_password": "X-HamQTH-Password", "hamqth_session_id": "X-HamQTH-Session-ID", } # DX location source of "GRID" from a v2 response becomes "SPOT" to a v1 client. _V2_TO_V1_RESPONSE_VALUES = { "dx_location_source": {"GRID": "SPOT"}, } class V1CompatibilityWrapper(CompatibilityWrapper): """Translates v1 requests to v2 on the way in, and v2 responses to v1 on the way out. This logic captures the majority of changes needed for each endpoint.""" def translate_request(self): """This one is a bit more than a simple translation of query params beceause we also need to move some query params to instead be headers.""" for param, header in _V1_QUERY_PARAMS_TO_V2_HEADERS.items(): if header in self.request.headers: continue value = self.get_query_argument(param, default=None) if value: self.request.headers[header] = value super().translate_request() def translate_response_object(self, obj): obj = super().translate_response_object(obj) return rename_keys_and_values(obj, {}, _V2_TO_V1_RESPONSE_VALUES) class V1APISpotsHandler(V1CompatibilityWrapper, V2APISpotsHandler): """No special handling for this, the compatibility wrapper will handle translation to and from the later version.""" class V1APISpotsStreamHandler(V1CompatibilityWrapper, V2APISpotsStreamHandler): """No special handling for this, the compatibility wrapper will handle translation to and from the later version.""" class V1APIAlertsHandler(V1CompatibilityWrapper, V2APIAlertsHandler): """No special handling for this, the compatibility wrapper will handle translation to and from the later version.""" class V1APIAlertsStreamHandler(V1CompatibilityWrapper, V2APIAlertsStreamHandler): """No special handling for this, the compatibility wrapper will handle translation to and from the later version.""" class V1APISolarConditionsHandler(V1CompatibilityWrapper, V2APISolarConditionsHandler): """No special handling for this, the compatibility wrapper will handle translation to and from the later version.""" class V1APIDxStatsHandler(V1CompatibilityWrapper, V2APIDxStatsHandler): """No special handling for this, the compatibility wrapper will handle translation to and from the later version.""" class V1APIOptionsHandler(V1CompatibilityWrapper, V2APIOptionsHandler): """No special handling for this, the compatibility wrapper will handle translation to and from the later version.""" class V1APIStatusHandler(V1CompatibilityWrapper, V2APIStatusHandler): """No special handling for this, the compatibility wrapper will handle translation to and from the later version.""" class V1APILookupCallHandler(V1CompatibilityWrapper, V2APILookupCallHandler): """No special handling for this, the compatibility wrapper will handle translation to and from the later version.""" class V1APILookupSigRefHandler(V1CompatibilityWrapper, V2APILookupSigRefHandler): """No special handling for this, the compatibility wrapper will handle translation to and from the later version.""" class V1APILookupGridHandler(V1CompatibilityWrapper, V2APILookupGridHandler): """No special handling for this, the compatibility wrapper will handle translation to and from the later version.""" class V1APISpotHandler(V1CompatibilityWrapper, V2APISpotHandler): """Some special handling required for this one, the v1 add spot call took its data in from query parameters, but in v2 we changed that to using a request body with the data in, so we need to recreate that here before we pass on handling to the v2 call.""" def translate_request(self): def translate(body): if isinstance(body, dict): return {"spot": body} return body translate_json_body(self.request, translate) super().translate_request()