Refactor of caching & data storage part 11 #118

This commit is contained in:
Ian Renton
2026-08-02 12:38:33 +01:00
parent 2e6d8e4b4a
commit cee9188538
8 changed files with 108 additions and 41 deletions
+6 -1
View File
@@ -257,11 +257,16 @@ callsign-data-providers:
enabled: true
- class: "ClublogXML"
enabled: false
enabled: true
# API key for Clublog to look up information. Required in order to enable this provider. You will need to request
# one via their helpdesk portal if you want to use callsign lookups from Clublog.
clublog-api-key: ""
- class: "ClublogAPI"
enabled: true
# API key for Clublog to look up information. Required in order to enable this provider.
clublog-api-key: ""
# Maximum time to keep spots and alerts in the system before deleting them. By default, one hour for spots and one week
# for alerts.
+28 -1
View File
@@ -5,6 +5,7 @@ from pyhamtools.frequency import freq_to_band
from core.constants import UNKNOWN_BAND, BANDS, CW_MODES, PHONE_MODES, DATA_MODES, MODE_ALIASES, ALL_MODES
from core.data_store import DATA_STORE
from data.callsign import Callsign
def safe_json_dumps(obj):
@@ -76,4 +77,30 @@ def get_flag_for_dxcc(dxcc):
"""Get an emoji flag for a given DXCC entity ID"""
dxcc_data = DATA_STORE.dxcc_data[dxcc] if dxcc in DATA_STORE.dxcc_data else None
return dxcc_data["flag"] if dxcc_data else None
return dxcc_data["flag"] if dxcc_data else None
def get_callsign_object_from_pyhamtools_callinfo(callsign, callinfo):
"""Utility function to take the data provided by a PyHamTools CallInfo object and populate our own Callsign data
object from it"""
home_call = callinfo.get_homecall(callsign)
data = callinfo.get_all()
country = data["country"] if "country" in data else None
dxcc_id = data["adif"] if "adif" in data else None
continent = data["continent"] if "continent" in data else None
cq_zone = data["cqz"] if "cqz" in data else None
itu_zone = data["ituz"] if "ituz" in data else None
lat = float(data["latitude"]) if "latitude" in data else None
lon = float(data["longitude"]) if "longitude" in data else None
return Callsign(call=callsign,
home_call=home_call,
country=country,
dxcc_id=dxcc_id,
continent=continent,
cq_zone=cq_zone,
itu_zone=itu_zone,
latitude=lat,
longitude=lon)
+1 -1
View File
@@ -11,7 +11,7 @@ class Callsign:
# Callsign as spotted
call: str
# "Home" call, i.e. with any prefixes and suffixes stripped off
home_call: str
home_call: str | None = None
# Operator name
name : str | None = None
# QTH (location), free text
@@ -0,0 +1,25 @@
import logging
from datetime import datetime
from threading import Thread, Event
import pytz
from requests import ReadTimeout
from requests.exceptions import ConnectionError, ConnectTimeout
from core.constants import HTTP_HEADERS
from core.url_data_cache import URLDataCache
from providers.callsigndata.callsign_data_provider import CallsignDataProvider
class APIQueryCallsignDataProvider(CallsignDataProvider):
"""Generic callsign data provider class for providers that fetch their data from the web on-demand using an API."""
def __init__(self, name, provider_config):
""" Set up the provider."""
super().__init__(name, provider_config)
def start(self):
pass
def stop(self):
pass
+43
View File
@@ -0,0 +1,43 @@
import logging
from datetime import datetime
import pytz
from pyhamtools import LookupLib, Callinfo
from core.utils import get_callsign_object_from_pyhamtools_callinfo
from data.callsign import Callsign
from providers.callsigndata.api_query_callsign_data_provider import APIQueryCallsignDataProvider
class ClublogAPI(APIQueryCallsignDataProvider):
"""Callsign data provider for Clublog's API."""
_callinfo = None
def __init__(self, provider_config):
# API key required for this provider
self._api_key = provider_config.get("api-key", "")
if self._api_key != "":
lookuplib = LookupLib(lookuptype="clublogapi", apikey=self._api_key)
self._callinfo = Callinfo(lookuplib)
else:
provider_config["enabled"] = False
logging.warning(
"Clublog XML callsign data provider configured but no api key was provided, this has been disabled.")
super().__init__("Clublog API", provider_config)
def lookup(self, callsign, lookup_credentials):
callsign_data = Callsign(call=callsign)
try:
callsign_data = get_callsign_object_from_pyhamtools_callinfo(callsign, self._callinfo)
self.status = "OK"
self.last_update_time = datetime.now(pytz.UTC)
except Exception as e:
self.status = "Error"
logging.error("Exception when looking up data from Clublog API", e, exc_info=True)
return callsign_data
+2 -18
View File
@@ -3,6 +3,7 @@ import logging
from pyhamtools import LookupLib, Callinfo
from core.utils import get_callsign_object_from_pyhamtools_callinfo
from data.callsign import Callsign
from providers.callsigndata.file_download_callsign_data_provider import FileDownloadCallsignDataProvider
@@ -48,21 +49,4 @@ class ClublogXML(FileDownloadCallsignDataProvider):
return False
def lookup(self, callsign, lookup_credentials):
# Lookup credentials are not required for this source.
# Lat/lon will only be centre of country or capital city from this source
ll = self._callinfo.get_lat_long(callsign)
lat = None
lon = None
if ll and "latitude" in ll and "longitude" in ll:
lat = float(ll["latitude"])
lon = float(ll["longitude"])
return Callsign(call=callsign,
home_call=self._callinfo.get_homecall(callsign),
country=self._callinfo.get_country_name(callsign),
dxcc_id=self._callinfo.get_adif_id(callsign),
continent=self._callinfo.get_continent(callsign),
cq_zone=self._callinfo.get_cqz(callsign),
itu_zone=self._callinfo.get_ituz(callsign),
latitude=lat,
longitude=lon)
return get_callsign_object_from_pyhamtools_callinfo(callsign, self._callinfo)
+2 -18
View File
@@ -2,6 +2,7 @@ import logging
from pyhamtools import LookupLib, Callinfo
from core.utils import get_callsign_object_from_pyhamtools_callinfo
from data.callsign import Callsign
from providers.callsigndata.file_download_callsign_data_provider import FileDownloadCallsignDataProvider
@@ -28,21 +29,4 @@ class CountryFiles(FileDownloadCallsignDataProvider):
return False
def lookup(self, callsign, lookup_credentials):
# Lookup credentials are not required for this source.
# Lat/lon will only be centre of country or capital city from this source
ll = self._callinfo.get_lat_long(callsign)
lat = None
lon = None
if ll and "latitude" in ll and "longitude" in ll:
lat = float(ll["latitude"])
lon = float(ll["longitude"])
return Callsign(call=callsign,
home_call=self._callinfo.get_homecall(callsign),
country=self._callinfo.get_country_name(callsign),
dxcc_id=self._callinfo.get_adif_id(callsign),
continent=self._callinfo.get_continent(callsign),
cq_zone=self._callinfo.get_cqz(callsign),
itu_zone=self._callinfo.get_ituz(callsign),
latitude=lat,
longitude=lon)
return get_callsign_object_from_pyhamtools_callinfo(callsign, self._callinfo)
@@ -12,8 +12,7 @@ from providers.callsigndata.callsign_data_provider import CallsignDataProvider
class FileDownloadCallsignDataProvider(CallsignDataProvider):
"""Generic static reference data provider class for providers that fetch their data from the web by downloading a
file."""
"""Generic callsign data provider class for providers that fetch their data from the web by downloading a file."""
def __init__(self, name, provider_config, url, cache_file_path, poll_interval):
""" Set up the provider, note poll_interval is in *days*."""