mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-05-30 17:35:11 +00:00
Modify the backend so that instead of using the server owner's QRZ & HamQTH credentials, it instead requires them to be provided by the client (if none are provided, the lookups do not occur.)
This commit is contained in:
68
data/spot.py
68
data/spot.py
@@ -12,8 +12,9 @@ from pyhamtools.locator import locator_to_latlong, latlong_to_locator
|
||||
from core.config import MAX_SPOT_AGE
|
||||
from core.constants import MODE_ALIASES
|
||||
from core.geo_utils import lat_lon_to_cq_zone, lat_lon_to_itu_zone
|
||||
from core.lookup_helper import lookup_helper, infer_band_from_freq, infer_mode_from_comment, infer_mode_from_frequency, \
|
||||
infer_mode_type_from_mode
|
||||
from core.lookup_helper import lookup_helper, infer_band_from_freq, infer_mode_from_comment, \
|
||||
infer_mode_from_frequency, infer_mode_type_from_mode
|
||||
from data.lookup_credentials import LookupCredentials
|
||||
from core.sig_utils import populate_sig_ref_info, ANY_SIG_REGEX, get_ref_regex_for_sig
|
||||
from data.sig_ref import SIGRef
|
||||
|
||||
@@ -131,7 +132,7 @@ class Spot:
|
||||
# The ID the source gave it, if any.
|
||||
source_id: str = None
|
||||
|
||||
def infer_missing(self):
|
||||
def infer_missing(self, credentials=None):
|
||||
"""Infer missing parameters where possible"""
|
||||
|
||||
# If we somehow don't have a spot time, set it to zero so it sorts off the bottom of any list but
|
||||
@@ -158,11 +159,11 @@ class Spot:
|
||||
|
||||
# DX country, continent etc. from callsign
|
||||
if self.dx_call and not self.dx_country:
|
||||
self.dx_country = lookup_helper.infer_country_from_callsign(self.dx_call)
|
||||
self.dx_country = lookup_helper.infer_country_from_callsign(self.dx_call, credentials)
|
||||
if self.dx_call and not self.dx_continent:
|
||||
self.dx_continent = lookup_helper.infer_continent_from_callsign(self.dx_call)
|
||||
self.dx_continent = lookup_helper.infer_continent_from_callsign(self.dx_call, credentials)
|
||||
if self.dx_call and not self.dx_dxcc_id:
|
||||
self.dx_dxcc_id = lookup_helper.infer_dxcc_id_from_callsign(self.dx_call)
|
||||
self.dx_dxcc_id = lookup_helper.infer_dxcc_id_from_callsign(self.dx_call, credentials)
|
||||
if self.dx_dxcc_id and not self.dx_flag:
|
||||
self.dx_flag = lookup_helper.get_flag_for_dxcc(self.dx_dxcc_id)
|
||||
|
||||
@@ -192,11 +193,11 @@ class Spot:
|
||||
if self.de_call and any(char.isdigit() for char in self.de_call) and not (
|
||||
self.de_call.startswith("T2") and self.source == "APRS-IS"):
|
||||
if not self.de_country:
|
||||
self.de_country = lookup_helper.infer_country_from_callsign(self.de_call)
|
||||
self.de_country = lookup_helper.infer_country_from_callsign(self.de_call, credentials)
|
||||
if not self.de_continent:
|
||||
self.de_continent = lookup_helper.infer_continent_from_callsign(self.de_call)
|
||||
self.de_continent = lookup_helper.infer_continent_from_callsign(self.de_call, credentials)
|
||||
if not self.de_dxcc_id:
|
||||
self.de_dxcc_id = lookup_helper.infer_dxcc_id_from_callsign(self.de_call)
|
||||
self.de_dxcc_id = lookup_helper.infer_dxcc_id_from_callsign(self.de_call, credentials)
|
||||
if self.de_dxcc_id and not self.de_flag:
|
||||
self.de_flag = lookup_helper.get_flag_for_dxcc(self.de_dxcc_id)
|
||||
|
||||
@@ -306,27 +307,40 @@ class Spot:
|
||||
if self.comment and not self.qrt:
|
||||
self.qrt = "QRT" in self.comment.upper()
|
||||
|
||||
# DX operator details lookup, using QRZ.com. This should be the last resort compared to taking the data from
|
||||
# the actual spotting service, e.g. we don't want to accidentally use a user's QRZ.com home lat/lon instead of
|
||||
# the one from the park reference they're at.
|
||||
# Always create an ID based on a hash of every parameter *except* received_time. This is used as the index
|
||||
# to a map, which as a byproduct avoids us having multiple duplicate copies of the object that are identical
|
||||
# apart from that they were retrieved from the API at different times. Note that the simple Python hash()
|
||||
# function includes a seed randomly generated at runtime; this is therefore not consistent between runs. But we
|
||||
# use diskcache to store our data between runs, so we use SHA256 which does not include this random element.
|
||||
# The ID is computed before the online lookups below so that it is stable regardless of whether credentials
|
||||
# are provided, allowing the enriched API response to be matched to the stored spot by ID.
|
||||
if not self.id:
|
||||
self_copy = copy.deepcopy(self)
|
||||
self_copy.received_time = 0
|
||||
self_copy.received_time_iso = ""
|
||||
self.id = hashlib.sha256(str(self_copy).encode("utf-8")).hexdigest()
|
||||
|
||||
# DX operator details lookup, using QRZ.com/HamQTH. This should be the last resort compared to taking the data
|
||||
# from the actual spotting service, e.g. we don't want to accidentally use a user's QRZ.com home lat/lon
|
||||
# instead of the one from the park reference they're at.
|
||||
if self.dx_call and not self.dx_name:
|
||||
self.dx_name = lookup_helper.infer_name_from_callsign_online_lookup(self.dx_call)
|
||||
self.dx_name = lookup_helper.infer_name_from_callsign_online_lookup(self.dx_call, credentials)
|
||||
if self.dx_call and not self.dx_latitude:
|
||||
latlon = lookup_helper.infer_latlon_from_callsign_online_lookup(self.dx_call)
|
||||
latlon = lookup_helper.infer_latlon_from_callsign_online_lookup(self.dx_call, credentials)
|
||||
if latlon:
|
||||
self.dx_latitude = latlon[0]
|
||||
self.dx_longitude = latlon[1]
|
||||
self.dx_grid = lookup_helper.infer_grid_from_callsign_online_lookup(self.dx_call)
|
||||
self.dx_grid = lookup_helper.infer_grid_from_callsign_online_lookup(self.dx_call, credentials)
|
||||
self.dx_location_source = "HOME QTH"
|
||||
|
||||
# Determine a "QTH" string. If we have a SIG ref, pick the first one and turn it into a suitable stirng,
|
||||
# Determine a "QTH" string. If we have a SIG ref, pick the first one and turn it into a suitable string,
|
||||
# otherwise see what they have set on an online lookup service.
|
||||
if self.sig_refs and len(self.sig_refs) > 0:
|
||||
self.dx_qth = self.sig_refs[0].id
|
||||
if self.sig_refs[0].name:
|
||||
self.dx_qth = self.dx_qth + " " + self.sig_refs[0].name
|
||||
else:
|
||||
self.dx_qth = lookup_helper.infer_qth_from_callsign_online_lookup(self.dx_call)
|
||||
self.dx_qth = lookup_helper.infer_qth_from_callsign_online_lookup(self.dx_call, credentials)
|
||||
|
||||
# Last resort for getting a DX position, use the DXCC entity.
|
||||
if self.dx_call and not self.dx_latitude:
|
||||
@@ -352,12 +366,12 @@ class Spot:
|
||||
if self.dx_latitude:
|
||||
self.dx_cq_zone = lat_lon_to_cq_zone(self.dx_latitude, self.dx_longitude)
|
||||
elif self.dx_call:
|
||||
self.dx_cq_zone = lookup_helper.infer_cq_zone_from_callsign(self.dx_call)
|
||||
self.dx_cq_zone = lookup_helper.infer_cq_zone_from_callsign(self.dx_call, credentials)
|
||||
if not self.dx_itu_zone:
|
||||
if self.dx_latitude:
|
||||
self.dx_itu_zone = lat_lon_to_itu_zone(self.dx_latitude, self.dx_longitude)
|
||||
elif self.dx_call:
|
||||
self.dx_itu_zone = lookup_helper.infer_itu_zone_from_callsign(self.dx_call)
|
||||
self.dx_itu_zone = lookup_helper.infer_itu_zone_from_callsign(self.dx_call, credentials)
|
||||
|
||||
# DX Location is "good" if it is from a spot, or from QRZ if the callsign doesn't contain a slash, so the operator
|
||||
# is likely at home.
|
||||
@@ -369,13 +383,13 @@ class Spot:
|
||||
# DE with no digits and APRS servers starting "T2" are not things we can look up location for
|
||||
if self.de_call and 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.
|
||||
# DE operator position lookup, using QRZ.com/HamQTH.
|
||||
if not self.de_latitude:
|
||||
latlon = lookup_helper.infer_latlon_from_callsign_online_lookup(self.de_call)
|
||||
latlon = lookup_helper.infer_latlon_from_callsign_online_lookup(self.de_call, credentials)
|
||||
if latlon:
|
||||
self.de_latitude = latlon[0]
|
||||
self.de_longitude = latlon[1]
|
||||
self.de_grid = lookup_helper.infer_grid_from_callsign_online_lookup(self.de_call)
|
||||
self.de_grid = lookup_helper.infer_grid_from_callsign_online_lookup(self.de_call, credentials)
|
||||
|
||||
# Last resort for getting a DE position, use the DXCC entity.
|
||||
if not self.de_latitude:
|
||||
@@ -385,16 +399,6 @@ class Spot:
|
||||
self.de_longitude = latlon[1]
|
||||
self.de_grid = lookup_helper.infer_grid_from_callsign_dxcc(self.de_call)
|
||||
|
||||
# Always create an ID based on a hash of every parameter *except* received_time. This is used as the index
|
||||
# to a map, which as a byproduct avoids us having multiple duplicate copies of the object that are identical
|
||||
# apart from that they were retrieved from the API at different times. Note that the simple Python hash()
|
||||
# function includes a seed randomly generated at runtime; this is therefore not consistent between runs. But we
|
||||
# use diskcache to store our data between runs, so we use SHA256 which does not include this random element.
|
||||
self_copy = copy.deepcopy(self)
|
||||
self_copy.received_time = 0
|
||||
self_copy.received_time_iso = ""
|
||||
self.id = hashlib.sha256(str(self_copy).encode("utf-8")).hexdigest()
|
||||
|
||||
def to_json(self):
|
||||
"""JSON serialise"""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user