diff --git a/core/lookup_helper.py b/core/lookup_helper.py index 5a575cf..fcce0ed 100644 --- a/core/lookup_helper.py +++ b/core/lookup_helper.py @@ -141,7 +141,7 @@ class LookupHelper: try: # Start with the basic country-files.com-based decoder. country = self.CALL_INFO_BASIC.get_country_name(call) - except KeyError as e: + except (KeyError, ValueError) as e: country = None # Couldn't get anything from basic call info database, try QRZ.com if not country: @@ -170,7 +170,7 @@ class LookupHelper: try: # Start with the basic country-files.com-based decoder. dxcc = self.CALL_INFO_BASIC.get_adif_id(call) - except KeyError as e: + except (KeyError, ValueError) as e: dxcc = None # Couldn't get anything from basic call info database, try QRZ.com if not dxcc: @@ -198,7 +198,7 @@ class LookupHelper: try: # Start with the basic country-files.com-based decoder. continent = self.CALL_INFO_BASIC.get_continent(call) - except KeyError as e: + except (KeyError, ValueError) as e: continent = None # Couldn't get anything from basic call info database, try Clublog data if not continent: @@ -221,7 +221,7 @@ class LookupHelper: try: # Start with the basic country-files.com-based decoder. cqz = self.CALL_INFO_BASIC.get_cqz(call) - except KeyError as e: + except (KeyError, ValueError) as e: cqz = None # Couldn't get anything from basic call info database, try QRZ.com if not cqz: @@ -249,7 +249,7 @@ class LookupHelper: try: # Start with the basic country-files.com-based decoder. ituz = self.CALL_INFO_BASIC.get_ituz(call) - except KeyError as e: + except (KeyError, ValueError) as e: ituz = None # Couldn't get anything from basic call info database, try QRZ.com if not ituz: @@ -273,13 +273,13 @@ class LookupHelper: data = self.LOOKUP_LIB_QRZ.lookup_callsign(callsign=call) self.QRZ_CALLSIGN_DATA_CACHE.add(call, data, expire=604800) # 1 week in seconds return data - except KeyError: + except (KeyError, ValueError): # QRZ had no info for the call, but maybe it had prefixes or suffixes. Try again with the base call. try: data = self.LOOKUP_LIB_QRZ.lookup_callsign(callsign=callinfo.Callinfo.get_homecall(call)) self.QRZ_CALLSIGN_DATA_CACHE.add(call, data, expire=604800) # 1 week in seconds return data - except KeyError: + except (KeyError, ValueError): # QRZ had no info for the call, that's OK. Cache a None so we don't try to look this up again self.QRZ_CALLSIGN_DATA_CACHE.add(call, None, expire=604800) # 1 week in seconds return None @@ -296,13 +296,13 @@ class LookupHelper: data = self.LOOKUP_LIB_CLUBLOG_API.lookup_callsign(callsign=call) self.CLUBLOG_CALLSIGN_DATA_CACHE.add(call, data, expire=604800) # 1 week in seconds return data - except KeyError: + except (KeyError, ValueError): # Clublog had no info for the call, but maybe it had prefixes or suffixes. Try again with the base call. try: data = self.LOOKUP_LIB_CLUBLOG_API.lookup_callsign(callsign=callinfo.Callinfo.get_homecall(call)) self.CLUBLOG_CALLSIGN_DATA_CACHE.add(call, data, expire=604800) # 1 week in seconds return data - except KeyError: + except (KeyError, ValueError): # Clublog had no info for the call, that's OK. Cache a None so we don't try to look this up again self.CLUBLOG_CALLSIGN_DATA_CACHE.add(call, None, expire=604800) # 1 week in seconds return None @@ -319,7 +319,7 @@ class LookupHelper: try: data = self.LOOKUP_LIB_CLUBLOG_XML.lookup_callsign(callsign=call) return data - except KeyError: + except (KeyError, ValueError): # Clublog had no info for the call, that's OK. Cache a None so we don't try to look this up again self.CLUBLOG_CALLSIGN_DATA_CACHE.add(call, None, expire=604800) # 1 week in seconds return None diff --git a/data/spot.py b/data/spot.py index 84e4db0..9264417 100644 --- a/data/spot.py +++ b/data/spot.py @@ -41,9 +41,8 @@ class Spot: dx_cq_zone: int = None # ITU zone of the DX operator dx_itu_zone: int = None - # If this is an APRS spot, what SSID was the DX operator using? - # This is a string not an int for now, as I often see non-numeric ones somehow - dx_aprs_ssid: str = None + # If this is an APRS/Packet/etc spot, what SSID was the DX operator using? + dx_ssid: str = None # Maidenhead grid locator for the DX. This could be from a geographical reference e.g. POTA, or just from the # country dx_grid: str = None @@ -68,6 +67,8 @@ class Spot: de_flag: str = None # Continent of the spotter de_continent: str = None + # If this is an APRS/Packet/etc spot, what SSID was the spotter/receiver using? + de_ssid: str = None # Maidenhead grid locator for the spotter. This is not going to be from a xOTA reference so it will likely just be # a QRZ or DXCC lookup. If the spotter is also portable, this is probably wrong, but it's good enough for some # simple mapping. @@ -157,7 +158,10 @@ class Spot: # Clean up DX call if it has an SSID or -# from RBN if self.dx_call and "-" in self.dx_call: - self.dx_call = self.dx_call.split("-")[0] + split = self.dx_call.split("-") + self.dx_call = split[0] + if len(split) > 1 and split[1] != "#": + self.dx_ssid = split[1] # DX country, continent, zones etc. from callsign if self.dx_call and not self.dx_country: @@ -175,7 +179,10 @@ class Spot: # Clean up spotter call if it has an SSID or -# from RBN if self.de_call and "-" in self.de_call: - self.de_call = self.de_call.split("-")[0] + split = self.de_call.split("-") + self.de_call = split[0] + if len(split) > 1 and split[1] != "#": + self.de_ssid = split[1] # If we have a spotter of "RBNHOLE", we should have the actual spotter callsign in the comment, so extract it. # RBNHole posts come from a number of providers, so it's dealt with here in the generic spot handling code. @@ -192,8 +199,8 @@ class Spot: self.de_call = sotamat_call_match.group(1).upper() # Spotter country, continent, zones etc. from callsign. - # DE of "RBNHOLE" and "SOTAMAT" are not things we can look up location for - if self.de_call != "RBNHOLE" and self.de_call != "SOTAMAT": + # DE call with no digits, or APRS servers starting "T2" are not things we can look up location for + if any(char.isdigit() for char in self.de_call) and not (self.de_call.startswith("T2") and self.source == "APRS-IS"): if self.de_call and not self.de_country: self.de_country = lookup_helper.infer_country_from_callsign(self.de_call) if self.de_call and not self.de_continent: @@ -290,8 +297,8 @@ class Spot: self.dx_location_good = self.dx_location_source == "SPOT" or self.dx_location_source == "WAB/WAI GRID" or ( self.dx_location_source == "QRZ" and not "/" in self.dx_call) - # DE of "RBNHOLE" and "SOTAMAT" are not things we can look up location for - if self.de_call != "RBNHOLE" and self.de_call != "SOTAMAT": + # DE with no digits and APRS servers starting "T2" are not things we can look up location for + if any(char.isdigit() for char in self.de_call) and not (self.de_call.startswith("T2") and self.source == "APRS-IS"): # DE operator position lookup, using QRZ.com. if self.de_call and not self.de_latitude: latlon = lookup_helper.infer_latlon_from_callsign_qrz(self.de_call) diff --git a/spotproviders/aprsis.py b/spotproviders/aprsis.py index 5581088..1ddfa30 100644 --- a/spotproviders/aprsis.py +++ b/spotproviders/aprsis.py @@ -39,11 +39,15 @@ class APRSIS(SpotProvider): # Split SSID in "from" call and store separately from_parts = data["from"].split("-") dx_call = from_parts[0] - dx_aprs_ssid = from_parts[1] if len(from_parts) > 1 else None + dx_ssid = from_parts[1] if len(from_parts) > 1 else None + via_parts = data["via"].split("-") + de_call = via_parts[0] + de_ssid = via_parts[1] if len(via_parts) > 1 else None spot = Spot(source="APRS-IS", dx_call=dx_call, - dx_aprs_ssid=dx_aprs_ssid, - de_call=data["via"], + dx_ssid=dx_ssid, + de_call=de_call, + de_ssid=de_ssid, comment=data["comment"] if "comment" in data else None, dx_latitude=data["latitude"] if "latitude" in data else None, dx_longitude=data["longitude"] if "longitude" in data else None, diff --git a/webassets/apidocs/openapi.yml b/webassets/apidocs/openapi.yml index f0ed686..30322d8 100644 --- a/webassets/apidocs/openapi.yml +++ b/webassets/apidocs/openapi.yml @@ -551,10 +551,10 @@ components: type: integer description: ITU zone of the DX operator example: 14 - dx_aprs_ssid: + dx_ssid: type: string - description: If this is an APRS spot, what SSID was the DX operator using? - example: "" + description: If this is an APRS/Packet/etc. spot, what SSID was the DX operator/sender using? + example: "7" dx_grid: type: string description: Maidenhead grid locator for the DX spot. This could be from a geographical reference e.g. POTA, or just from the country @@ -609,6 +609,10 @@ components: type: integer description: DXCC ID of the spotter example: 235 + de_ssid: + type: string + description: If this is an APRS/Packet/etc. spot, what SSID was the receiver using? + example: "9" de_grid: type: string description: Maidenhead grid locator for the spotter. This is not going to be from a xOTA reference so it will likely just be a QRZ or DXCC lookup. If the spotter is also portable, this is probably wrong, but it's good enough for some simple mapping. diff --git a/webassets/js/bands.js b/webassets/js/bands.js index ecbde3a..3810774 100644 --- a/webassets/js/bands.js +++ b/webassets/js/bands.js @@ -142,7 +142,7 @@ function updateBands() { // Now each spot is tagged with how far down the div it should go, add them to the DOM. spotList.forEach(s => { - bandSpotsDiv.append(`