mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-09-21 14:57:42 +00:00
Partial fix for mypy issues
This commit is contained in:
@@ -51,12 +51,12 @@ class APISpotsHandler(tornado.web.RequestHandler):
|
||||
# Fetch all spots matching the query, then optionally enrich with online data
|
||||
credentials = extract_credentials(self.request.headers)
|
||||
fields = [f.strip() for f in query_params["fields"].split(",")] if "fields" in query_params else []
|
||||
data = get_spot_list_with_filters(self._spots, query_params)
|
||||
assert self._spots is not None, "initialize() must be called before get()"
|
||||
spots = get_spot_list_with_filters(self._spots, query_params)
|
||||
if credentials:
|
||||
data = self._enrich(data, credentials)
|
||||
spots = self._enrich(spots, credentials)
|
||||
# Filter for only the required fields, if necessary
|
||||
if fields:
|
||||
data = filter_fields(data, fields)
|
||||
data: list[Spot] | list[dict[str, Any]] = filter_fields(spots, fields) if fields else spots
|
||||
self.write(safe_json_dumps(data))
|
||||
self.set_status(200)
|
||||
except ValueError as e:
|
||||
@@ -105,6 +105,7 @@ class APISpotsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
||||
|
||||
# Register to handle new spots arriving. The callback() method will get called with the new spot as an
|
||||
# argument.
|
||||
assert self._sse_spot_broadcaster is not None, "initialize() must be called before open()"
|
||||
self._sse_spot_broadcaster.register(self)
|
||||
|
||||
except Exception:
|
||||
@@ -114,6 +115,7 @@ class APISpotsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
||||
def close(self) -> None:
|
||||
"""When the user closes the socket, deregister ourselves from the spot broadcaster"""
|
||||
|
||||
assert self._sse_spot_broadcaster is not None, "initialize() must be called before close()"
|
||||
self._sse_spot_broadcaster.unregister(self)
|
||||
super().close()
|
||||
|
||||
@@ -122,15 +124,15 @@ class APISpotsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
||||
|
||||
try:
|
||||
# If the new spot matches our param filters, send it to the client. If not, ignore it.
|
||||
assert self._query_params is not None, "open() must be called before callback()"
|
||||
if spot_allowed_by_query(spot, self._query_params):
|
||||
# Add lookup data if we have credentials
|
||||
if self._credentials:
|
||||
spot = copy.deepcopy(spot)
|
||||
spot.infer_missing(self._credentials)
|
||||
# Filter fields returned if necessary
|
||||
if self._fields:
|
||||
spot = filter_fields([spot], self._fields)[0]
|
||||
self.write_message(msg=safe_json_dumps(spot))
|
||||
output: Spot | dict[str, Any] = filter_fields([spot], self._fields)[0] if self._fields else spot
|
||||
self.write_message(msg=safe_json_dumps(output))
|
||||
except Exception:
|
||||
logger.exception("Exception in SSE callback, connection will be closed")
|
||||
self.close()
|
||||
@@ -152,7 +154,7 @@ def get_spot_list_with_filters(all_spots: LiveDataCache, query: dict[str, str])
|
||||
spots = sorted(spots, key=lambda spot: spot.time if spot and spot.time else 0, reverse=True)
|
||||
spots = list(filter(lambda spot: spot_allowed_by_query(spot, query), spots))
|
||||
if "limit" in query:
|
||||
spots = spots[: int(query.get("limit"))]
|
||||
spots = spots[: int(query["limit"])]
|
||||
|
||||
# Ensure only the latest spot of each callsign-SSID combo is present in the list. This relies on the
|
||||
# list being in reverse time order, so if any future change allows re-ordering the list, that should
|
||||
@@ -162,7 +164,7 @@ def get_spot_list_with_filters(all_spots: LiveDataCache, query: dict[str, str])
|
||||
# duplicates are fine in the main spot list (e.g. different cluster spots of the same DX) this doesn't
|
||||
# work well for the other views.
|
||||
if "dedupe" in query:
|
||||
dedupe = query.get("dedupe").upper() == "TRUE"
|
||||
dedupe = query["dedupe"].upper() == "TRUE"
|
||||
if dedupe:
|
||||
spots_temp = []
|
||||
already_seen = []
|
||||
@@ -183,26 +185,26 @@ def spot_allowed_by_query(spot: Spot, query: dict[str, str]) -> bool:
|
||||
for k in query:
|
||||
match k:
|
||||
case "since":
|
||||
since = datetime.fromtimestamp(int(query.get(k)), pytz.UTC).timestamp()
|
||||
since = datetime.fromtimestamp(int(query[k]), pytz.UTC).timestamp()
|
||||
if not spot.time or spot.time <= since:
|
||||
return False
|
||||
case "max_age":
|
||||
max_age = int(query.get(k))
|
||||
max_age = int(query[k])
|
||||
since = (datetime.now(pytz.UTC) - timedelta(seconds=max_age)).timestamp()
|
||||
if not spot.time or spot.time <= since:
|
||||
return False
|
||||
case "received_since":
|
||||
since = datetime.fromtimestamp(float(query.get(k)), pytz.UTC).timestamp()
|
||||
since = datetime.fromtimestamp(float(query[k]), pytz.UTC).timestamp()
|
||||
if not spot.received_time or spot.received_time <= since:
|
||||
return False
|
||||
case "source":
|
||||
sources = query.get(k).split(",")
|
||||
sources = query[k].split(",")
|
||||
if not spot.source or spot.source not in sources:
|
||||
return False
|
||||
case "sig":
|
||||
# If a list of activities is provided, the spot must have an activity and it must match one of them.
|
||||
# The special activity "NO_SIG", when supplied in the list, matches spots with no activity.
|
||||
activities = query.get(k).split(",")
|
||||
activities = query[k].split(",")
|
||||
include_no_activity = "NO_SIG" in activities
|
||||
if not spot.sig and not include_no_activity:
|
||||
return False
|
||||
@@ -211,56 +213,56 @@ def spot_allowed_by_query(spot: Spot, query: dict[str, str]) -> bool:
|
||||
case "needs_sig":
|
||||
# If true, an activity is required, regardless of what it is, it just can't be missing. Mutually
|
||||
# exclusive with supplying the special "NO_SIG" parameter to the "sig" query param.
|
||||
needs_activity = query.get(k).upper() == "TRUE"
|
||||
needs_activity = query[k].upper() == "TRUE"
|
||||
if needs_activity and not spot.sig:
|
||||
return False
|
||||
case "needs_sig_ref":
|
||||
# If true, at least one activity ref is required, regardless of what it is, it just can't be missing.
|
||||
needs_activity_ref = query.get(k).upper() == "TRUE"
|
||||
needs_activity_ref = query[k].upper() == "TRUE"
|
||||
if needs_activity_ref and (not spot.sig_refs or len(spot.sig_refs) == 0):
|
||||
return False
|
||||
case "band":
|
||||
bands = query.get(k).split(",")
|
||||
bands = query[k].split(",")
|
||||
if not spot.band or spot.band not in bands:
|
||||
return False
|
||||
case "mode":
|
||||
modes = query.get(k).split(",")
|
||||
modes = query[k].split(",")
|
||||
if not spot.mode or spot.mode not in modes:
|
||||
return False
|
||||
case "mode_type":
|
||||
mode_types = query.get(k).split(",")
|
||||
mode_types = query[k].split(",")
|
||||
if not spot.mode_type or spot.mode_type not in mode_types:
|
||||
return False
|
||||
case "dx_continent":
|
||||
dxconts = query.get(k).split(",")
|
||||
dxconts = query[k].split(",")
|
||||
if not spot.dx_continent or spot.dx_continent not in dxconts:
|
||||
return False
|
||||
case "de_continent":
|
||||
deconts = query.get(k).split(",")
|
||||
deconts = query[k].split(",")
|
||||
if not spot.de_continent or spot.de_continent not in deconts:
|
||||
return False
|
||||
case "comment_includes":
|
||||
comment_includes = query.get(k).strip()
|
||||
comment_includes = query[k].strip()
|
||||
if not spot.comment or comment_includes.upper() not in spot.comment.upper():
|
||||
return False
|
||||
case "dx_call_includes":
|
||||
dx_call_includes = query.get(k).strip()
|
||||
dx_call_includes = query[k].strip()
|
||||
if not spot.dx_call or dx_call_includes.upper() not in spot.dx_call.upper():
|
||||
return False
|
||||
case "text_includes":
|
||||
text_includes = query.get(k).strip()
|
||||
text_includes = query[k].strip()
|
||||
if (not spot.dx_call or text_includes.upper() not in spot.dx_call.upper()) and (
|
||||
not spot.comment or text_includes.upper() not in spot.comment.upper()
|
||||
):
|
||||
return False
|
||||
case "allow_qrt":
|
||||
# If false, spots that are flagged as QRT are not returned.
|
||||
prevent_qrt = query.get(k).upper() == "FALSE"
|
||||
prevent_qrt = query[k].upper() == "FALSE"
|
||||
if prevent_qrt and spot.qrt:
|
||||
return False
|
||||
case "needs_good_location":
|
||||
# If true, spots require a "good" location to be returned
|
||||
needs_good_location = query.get(k).upper() == "TRUE"
|
||||
needs_good_location = query[k].upper() == "TRUE"
|
||||
if needs_good_location and not spot.dx_location_good:
|
||||
return False
|
||||
return True
|
||||
|
||||
Reference in New Issue
Block a user