Refactor of caching & data storage part 16 #118

This commit is contained in:
Ian Renton
2026-08-03 22:15:29 +01:00
parent 27d73c27d6
commit 459d999f57
14 changed files with 93 additions and 55 deletions
+4 -22
View File
@@ -8,15 +8,15 @@ import tornado
from tornado import httputil
from tornado.web import Application
from core.call_lookup_helper import get_call_info
from core.constants import SIGS
from core.geo_utils import lat_lon_for_grid_sw_corner_plus_size, lat_lon_to_cq_zone, lat_lon_to_itu_zone
from core.prometheus_metrics_handler import api_requests_counter
from core.sig_utils import get_ref_regex_for_sig
from core.sig_lookup_helper import populate_missing_sig_ref_info
from core.sig_utils import get_ref_regex_for_sig
from core.utils import safe_json_dumps
from data.lookup_credentials import extract_credentials
from data.sig_ref import SIGRef
from data.spot import Spot
class APILookupCallHandler(tornado.web.RequestHandler):
@@ -45,27 +45,9 @@ class APILookupCallHandler(tornado.web.RequestHandler):
if "call" in query_params.keys():
call = str(query_params.get("call")).upper()
if re.match(r"^[A-Z0-9/\-]*$", call):
# Take the callsign, make a "fake spot" so we can run infer_missing() on it, then repack the
# resulting data in the correct way for the API response.
credentials = extract_credentials(query_params)
fake_spot = Spot(dx_call=call)
fake_spot.infer_missing(credentials)
data = {
"call": call,
"name": fake_spot.dx_name,
"qth": fake_spot.dx_qth,
"country": fake_spot.dx_country,
"flag": fake_spot.dx_flag,
"continent": fake_spot.dx_continent,
"dxcc_id": fake_spot.dx_dxcc_id,
"cq_zone": fake_spot.dx_cq_zone,
"itu_zone": fake_spot.dx_itu_zone,
"grid": fake_spot.dx_grid,
"latitude": fake_spot.dx_latitude,
"longitude": fake_spot.dx_longitude,
"location_source": fake_spot.dx_location_source
}
self.write(safe_json_dumps(data))
callsign_data = get_call_info(call, credentials)
self.write(safe_json_dumps(callsign_data))
else:
self.write(safe_json_dumps("Error - '" + call + "' does not look like a valid callsign."))
+5 -2
View File
@@ -11,6 +11,9 @@ class SSEBroadcaster:
def __init__(self):
self._handlers = set()
self._lock = threading.Lock()
self._loop = None
def bind_to_web_server_loop(self):
self._loop = IOLoop.current()
def register(self, handler):
@@ -22,9 +25,9 @@ class SSEBroadcaster:
self._handlers.discard(handler)
def publish(self, value):
self._loop.add_callback(self._fan_out, value)
self._loop.add_callback(self._broadcast, value)
def _fan_out(self, value):
def _broadcast(self, value):
with self._lock:
handlers = list(self._handlers)
for handler in handlers:
+5
View File
@@ -1,6 +1,7 @@
import asyncio
import logging
import os
import threading
import tornado
from tornado.web import StaticFileHandler
@@ -61,6 +62,10 @@ class WebServer:
async def _start_inner(self):
"""Start method (async). Sets up the Tornado application."""
# Bind the SSE broadcasters to the web server's loop, so they fire correctly
self._spot_broadcaster.bind_to_web_server_loop()
self._alert_broadcaster.bind_to_web_server_loop()
# Prepare a list of common arguments that are passed in to every API & page handler. This is just a basic thing
# to avoid copy-pasting the same thing to every route declaration below.
handler_opts = {"web_server_metrics": self.web_server_metrics}