From 18453beda5cfb0fa489e436e4df80cb66174a81a Mon Sep 17 00:00:00 2001 From: Ian Renton Date: Sat, 20 Jun 2026 12:40:06 +0100 Subject: [PATCH 1/2] Check GMA response actually contains a response rather than throwing an exception --- spotproviders/gma.py | 125 +++++++++++++++++++------------------- templates/add_spot.html | 2 +- templates/alerts.html | 2 +- templates/bands.html | 4 +- templates/base.html | 10 +-- templates/conditions.html | 2 +- templates/map.html | 4 +- templates/spots.html | 4 +- templates/status.html | 2 +- 9 files changed, 78 insertions(+), 77 deletions(-) diff --git a/spotproviders/gma.py b/spotproviders/gma.py index 2020871..cfa6f20 100644 --- a/spotproviders/gma.py +++ b/spotproviders/gma.py @@ -24,68 +24,69 @@ class GMA(HTTPSpotProvider): def _http_response_to_spots(self, http_response): new_spots = [] # Iterate through source data - for source_spot in http_response.json()["RCD"]: - # Convert to our spot format - spot = Spot(source=self.name, - dx_call=source_spot["ACTIVATOR"].upper(), - de_call=source_spot["SPOTTER"].upper(), - freq=float(source_spot["QRG"]) * 1000 if (source_spot["QRG"] != "") else None, - # Seen GMA spots with no frequency - mode=source_spot["MODE"].upper() if "<>" not in source_spot["MODE"] else None, - # Filter out some weird mode strings - comment=source_spot["TEXT"], - sig_refs=[SIGRef(id=source_spot["REF"], sig="", name=source_spot["NAME"])], - time=datetime.strptime(source_spot["DATE"] + source_spot["TIME"], "%Y%m%d%H%M").replace( - tzinfo=pytz.UTC).timestamp(), - dx_latitude=float(source_spot["LAT"]) if ( - source_spot["LAT"] and source_spot["LAT"] != "") else None, - # Seen GMA spots with no (or empty) lat/lon - dx_longitude=float(source_spot["LON"]) if ( - source_spot["LON"] and source_spot["LON"] != "") else None) + if "RCD" in http_response.json(): + for source_spot in http_response.json()["RCD"]: + # Convert to our spot format + spot = Spot(source=self.name, + dx_call=source_spot["ACTIVATOR"].upper(), + de_call=source_spot["SPOTTER"].upper(), + freq=float(source_spot["QRG"]) * 1000 if (source_spot["QRG"] != "") else None, + # Seen GMA spots with no frequency + mode=source_spot["MODE"].upper() if "<>" not in source_spot["MODE"] else None, + # Filter out some weird mode strings + comment=source_spot["TEXT"], + sig_refs=[SIGRef(id=source_spot["REF"], sig="", name=source_spot["NAME"])], + time=datetime.strptime(source_spot["DATE"] + source_spot["TIME"], "%Y%m%d%H%M").replace( + tzinfo=pytz.UTC).timestamp(), + dx_latitude=float(source_spot["LAT"]) if ( + source_spot["LAT"] and source_spot["LAT"] != "") else None, + # Seen GMA spots with no (or empty) lat/lon + dx_longitude=float(source_spot["LON"]) if ( + source_spot["LON"] and source_spot["LON"] != "") else None) - # GMA doesn't give what programme (SIG) the reference is for until we separately look it up. - if "REF" in source_spot: - try: - ref_response = SEMI_STATIC_URL_DATA_CACHE.get(self.REF_INFO_URL_ROOT + source_spot["REF"], - headers=HTTP_HEADERS) - # Sometimes this is blank, so handle that - if ref_response.text is not None and ref_response.text != "": - ref_info = ref_response.json() - # If this is POTA, SOTA or WWFF data we already have it through other means, so ignore. POTA and WWFF - # spots come through with reftype=POTA or reftype=WWFF. SOTA is harder to figure out because both SOTA - # and GMA summits come through with reftype=Summit, so we must check for the presence of a "sota" entry - # to determine if it's a SOTA summit. - if spot.sig_refs and "reftype" in ref_info and ref_info["reftype"] not in ["POTA", "WWFF"] and ( - ref_info["reftype"] != "Summit" or "sota" not in ref_info or ref_info["sota"] == ""): - match ref_info["reftype"]: - case "Summit": - spot.sig_refs[0].sig = "GMA" - spot.sig = "GMA" - case "IOTA Island": - spot.sig_refs[0].sig = "IOTA" - spot.sig = "IOTA" - case "Lighthouse (ILLW)": - spot.sig_refs[0].sig = "ILLW" - spot.sig = "ILLW" - case "Lighthouse (ARLHS)": - spot.sig_refs[0].sig = "ARLHS" - spot.sig = "ARLHS" - case "Castle": - spot.sig_refs[0].sig = "WCA" - spot.sig = "WCA" - case "Mill": - spot.sig_refs[0].sig = "MOTA" - spot.sig = "MOTA" - case _: - logging.warning("GMA spot found with ref type " + ref_info[ - "reftype"] + ", developer needs to add support for this!") - spot.sig_refs[0].sig = ref_info["reftype"] - spot.sig = ref_info["reftype"] + # GMA doesn't give what programme (SIG) the reference is for until we separately look it up. + if "REF" in source_spot: + try: + ref_response = SEMI_STATIC_URL_DATA_CACHE.get(self.REF_INFO_URL_ROOT + source_spot["REF"], + headers=HTTP_HEADERS) + # Sometimes this is blank, so handle that + if ref_response.text is not None and ref_response.text != "": + ref_info = ref_response.json() + # If this is POTA, SOTA or WWFF data we already have it through other means, so ignore. POTA and WWFF + # spots come through with reftype=POTA or reftype=WWFF. SOTA is harder to figure out because both SOTA + # and GMA summits come through with reftype=Summit, so we must check for the presence of a "sota" entry + # to determine if it's a SOTA summit. + if spot.sig_refs and "reftype" in ref_info and ref_info["reftype"] not in ["POTA", "WWFF"] and ( + ref_info["reftype"] != "Summit" or "sota" not in ref_info or ref_info["sota"] == ""): + match ref_info["reftype"]: + case "Summit": + spot.sig_refs[0].sig = "GMA" + spot.sig = "GMA" + case "IOTA Island": + spot.sig_refs[0].sig = "IOTA" + spot.sig = "IOTA" + case "Lighthouse (ILLW)": + spot.sig_refs[0].sig = "ILLW" + spot.sig = "ILLW" + case "Lighthouse (ARLHS)": + spot.sig_refs[0].sig = "ARLHS" + spot.sig = "ARLHS" + case "Castle": + spot.sig_refs[0].sig = "WCA" + spot.sig = "WCA" + case "Mill": + spot.sig_refs[0].sig = "MOTA" + spot.sig = "MOTA" + case _: + logging.warning("GMA spot found with ref type " + ref_info[ + "reftype"] + ", developer needs to add support for this!") + spot.sig_refs[0].sig = ref_info["reftype"] + spot.sig = ref_info["reftype"] - # Add to our list. Don't worry about de-duping, removing old spots etc. at this point; other code will do - # that for us. - new_spots.append(spot) - except: - logging.warning("Exception when looking up " + self.REF_INFO_URL_ROOT + source_spot[ - "REF"] + ", ignoring this spot for now") + # Add to our list. Don't worry about de-duping, removing old spots etc. at this point; other code will do + # that for us. + new_spots.append(spot) + except: + logging.warning("Exception when looking up " + self.REF_INFO_URL_ROOT + source_spot[ + "REF"] + ", ignoring this spot for now") return new_spots diff --git a/templates/add_spot.html b/templates/add_spot.html index 996063c..331399e 100644 --- a/templates/add_spot.html +++ b/templates/add_spot.html @@ -76,7 +76,7 @@ - + diff --git a/templates/alerts.html b/templates/alerts.html index f34e327..17c24f4 100644 --- a/templates/alerts.html +++ b/templates/alerts.html @@ -75,7 +75,7 @@ - + diff --git a/templates/bands.html b/templates/bands.html index 7694ad9..aa7281c 100644 --- a/templates/bands.html +++ b/templates/bands.html @@ -77,8 +77,8 @@ - - + + diff --git a/templates/base.html b/templates/base.html index f456c08..90ec0e4 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,6 +1,6 @@ {% extends "skeleton.html" %} {% block head_extra %} - + @@ -10,10 +10,10 @@ - - - - + + + + {% end %} {% block body %}
diff --git a/templates/conditions.html b/templates/conditions.html index 8bc92db..8594097 100644 --- a/templates/conditions.html +++ b/templates/conditions.html @@ -284,7 +284,7 @@
- + diff --git a/templates/map.html b/templates/map.html index b59ead8..3af8f62 100644 --- a/templates/map.html +++ b/templates/map.html @@ -95,8 +95,8 @@ - - + + diff --git a/templates/spots.html b/templates/spots.html index c59face..7c8a4f7 100644 --- a/templates/spots.html +++ b/templates/spots.html @@ -116,8 +116,8 @@ - - + + diff --git a/templates/status.html b/templates/status.html index d666c91..89ef8ec 100644 --- a/templates/status.html +++ b/templates/status.html @@ -59,7 +59,7 @@ - + + diff --git a/templates/alerts.html b/templates/alerts.html index 17c24f4..7c55794 100644 --- a/templates/alerts.html +++ b/templates/alerts.html @@ -75,7 +75,7 @@ - + diff --git a/templates/bands.html b/templates/bands.html index aa7281c..bf6e0d7 100644 --- a/templates/bands.html +++ b/templates/bands.html @@ -77,8 +77,8 @@ - - + + diff --git a/templates/base.html b/templates/base.html index 90ec0e4..385547c 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,6 +1,6 @@ {% extends "skeleton.html" %} {% block head_extra %} - + @@ -10,10 +10,10 @@ - - - - + + + + {% end %} {% block body %}
diff --git a/templates/conditions.html b/templates/conditions.html index 8594097..37432dc 100644 --- a/templates/conditions.html +++ b/templates/conditions.html @@ -284,7 +284,7 @@
- + diff --git a/templates/map.html b/templates/map.html index 3af8f62..8df89d8 100644 --- a/templates/map.html +++ b/templates/map.html @@ -95,8 +95,8 @@ - - + + diff --git a/templates/spots.html b/templates/spots.html index 7c8a4f7..ebe9514 100644 --- a/templates/spots.html +++ b/templates/spots.html @@ -116,8 +116,8 @@ - - + + diff --git a/templates/status.html b/templates/status.html index 89ef8ec..d0a22ef 100644 --- a/templates/status.html +++ b/templates/status.html @@ -59,7 +59,7 @@ - +