Strict adherence to canonical ActivityNames, to avoid the problem where Spothole was giving out activities like ["Towers", "TOWERS"]. All uses of ActivityName should now be canonical not arbitrary strings, and attempts to convert unknown strings to activitynames will be logged for me to check out.

This commit is contained in:
Ian Renton
2026-09-25 09:16:53 +01:00
parent 7417140a3d
commit 760c2412d3
17 changed files with 144 additions and 145 deletions
+20 -11
View File
@@ -1,13 +1,17 @@
import json
import logging
from datetime import datetime
import pytz
from core.enums import Mode
from core.activity_utils import get_activity_by_name
from core.enums import ActivityName, Mode
from data.activity_ref import ActivityRef
from data.spot import Spot
from providers.spot.websocket_spot_provider import WebsocketSpotProvider
logger = logging.getLogger(__name__)
class XOTA(WebsocketSpotProvider):
"""Spot provider for servers based on the "xOTA" software at https://github.com/nischu/xOTA/
@@ -17,12 +21,17 @@ class XOTA(WebsocketSpotProvider):
is why we also provide an activity_ref_prefix in our config. This is applied to the reference ID, so e.g. "T-01"
at C3 might become "C3 T-01". This allows us to provide location lookups for TOTA at several conferences."""
ACTIVITY = None
ACTIVITY: ActivityName | None = None
def __init__(self, provider_config):
name = provider_config.get("name", "xOTA")
super().__init__(name, provider_config, provider_config["url"])
self.ACTIVITY = str(provider_config["activity"]) if "activity" in provider_config else None
found_activity = get_activity_by_name(provider_config.get("activity"))
self.ACTIVITY = found_activity.name if found_activity else None
if not self.ACTIVITY:
logger.error(
"XOTA provider has no activity reference, this is a config problem - your config needs to specify a known activity type!"
)
self._activity_ref_prefix = (
str(provider_config["activity_ref_prefix"]) if "activity_ref_prefix" in provider_config else ""
)
@@ -31,20 +40,20 @@ class XOTA(WebsocketSpotProvider):
string = b.decode("utf-8")
source_spot = json.loads(string)
ref_id = f"{self._activity_ref_prefix} {source_spot['reference']['title']}"
activity = self.ACTIVITY
activities = []
activity_refs = []
if activity is not None:
activities = [activity]
activity_refs = [ActivityRef(id=ref_id, activity=activity, url=source_spot["reference"]["website"])]
spot = Spot(
source=self.name,
source_id=source_spot["id"],
dx_call=source_spot["stationCallSign"].upper(),
freq=float(source_spot["freq"]) * 1000,
mode=Mode.from_name(source_spot["mode"].upper()),
activities=[self.ACTIVITY] if self.ACTIVITY else [],
activity_refs=[
ActivityRef(
id=ref_id,
activity=self.ACTIVITY or "",
url=source_spot["reference"]["website"],
)
],
activities=activities,
activity_refs=activity_refs,
time=datetime.now(pytz.UTC).timestamp(),
qrt=source_spot["state"] != "active",
)