diff --git a/core/config.py b/core/config.py index 77ca810..64265f2 100644 --- a/core/config.py +++ b/core/config.py @@ -10,7 +10,8 @@ if not os.path.isfile("config.yml"): exit() # Load config -config = yaml.safe_load(open("config.yml")) +with open("config.yml") as f: + config = yaml.safe_load(f) logging.info("Loaded config.") MAX_SPOT_AGE = config["max-spot-age-sec"] @@ -23,7 +24,7 @@ WEB_UI_OPTIONS = config["web-ui-options"] # For ease of config, each spot provider owns its own config about whether it should be enabled by default in the web UI # but for consistency we provide this to the front-end in web-ui-options because it has no impact outside of the web UI. WEB_UI_OPTIONS["spot-providers-enabled-by-default"] = [p["name"] for p in config["spot-providers"] if p["enabled"] and ( - "enabled-by-default-in-web-ui" not in p or p["enabled-by-default-in-web-ui"] == True)] + "enabled-by-default-in-web-ui" not in p or p["enabled-by-default-in-web-ui"])] # If spotting to this server is enabled, "API" is another valid spot source even though it does not come from # one of our proviers. We set that to also be enabled by default. if ALLOW_SPOTTING: diff --git a/core/constants.py b/core/constants.py index 02719eb..72d7fe5 100644 --- a/core/constants.py +++ b/core/constants.py @@ -19,7 +19,7 @@ SIGS = [ SIG(name="WWBOTA", description="Worldwide Bunkers on the Air", ref_regex=r"B\/[A-Z0-9]{1,3}\-\d{3,4}"), SIG(name="HEMA", description="HuMPs Excluding Marilyns Award", ref_regex=r"[A-Z0-9]{1,3}\/[A-Z]{3}\-\d{3}"), SIG(name="IOTA", description="Islands on the Air", ref_regex=r"[A-Z]{2}\-\d{3}"), - SIG(name="MOTA", description="Mills on the Air", ref_regex=r"X\d{4-6}"), + SIG(name="MOTA", description="Mills on the Air", ref_regex=r"X\d{4,6}"), SIG(name="ARLHS", description="Amateur Radio Lighthouse Society", ref_regex=r"[A-Z]{3}\-\d{3,4}"), SIG(name="ILLW", description="International Lighthouse & Lightship Weekend", ref_regex=r"[A-Z]{2}\d{4}"), SIG(name="SIOTA", description="Silos on the Air", ref_regex=r"[A-Z]{2}\-[A-Z]{3}\d"), diff --git a/core/lookup_helper.py b/core/lookup_helper.py index b7dce69..7f68d27 100644 --- a/core/lookup_helper.py +++ b/core/lookup_helper.py @@ -103,7 +103,7 @@ class LookupHelper: logging.error("Could not download DXCC data, flags and similar data may be missing!") # Precompile regex matches for DXCCs to improve efficiency when iterating through them - for dxcc in self._dxcc_data.values(): + for dxcc in (self._dxcc_data.values() if self._dxcc_data else []): dxcc["_prefixRegexCompiled"] = re.compile(dxcc["prefixRegex"]) def _download_country_files_cty_plist(self): diff --git a/core/status_reporter.py b/core/status_reporter.py index 8ee8e97..31e272e 100644 --- a/core/status_reporter.py +++ b/core/status_reporter.py @@ -86,6 +86,6 @@ class StatusReporter: "page_access_count": self._web_server.web_server_metrics["page_access_counter"]} # Update Prometheus metrics - memory_use_gauge.set(psutil.Process(os.getpid()).memory_info().rss * 1024) + memory_use_gauge.set(psutil.Process(os.getpid()).memory_info().rss) spots_gauge.set(len(self._spots)) alerts_gauge.set(len(self._alerts)) diff --git a/server/handlers/api/alerts.py b/server/handlers/api/alerts.py index 0faf28e..cd1dfd2 100644 --- a/server/handlers/api/alerts.py +++ b/server/handlers/api/alerts.py @@ -155,8 +155,8 @@ def alert_allowed_by_query(alert, query): # Check the duration if end_time is provided. If end_time is not provided, assume the activation is # "short", i.e. it always passes this check. If dxpeditions_skip_max_duration_check is true and # the alert is a dxpedition, it also always passes the check. - if alert.is_dxpedition and (bool(query.get( - "dxpeditions_skip_max_duration_check")) if "dxpeditions_skip_max_duration_check" in query.keys() else False): + if alert.is_dxpedition and (query.get( + "dxpeditions_skip_max_duration_check").upper() == "TRUE" if "dxpeditions_skip_max_duration_check" in query.keys() else False): continue if alert.end_time and alert.start_time and alert.end_time - alert.start_time > max_duration: return False diff --git a/server/handlers/api/spots.py b/server/handlers/api/spots.py index 1993821..75f2387 100644 --- a/server/handlers/api/spots.py +++ b/server/handlers/api/spots.py @@ -241,7 +241,7 @@ def spot_allowed_by_query(spot, query): case "allow_qrt": # If false, spots that are flagged as QRT are not returned. prevent_qrt = query.get(k).upper() == "FALSE" - if prevent_qrt and spot.qrt and spot.qrt == True: + if prevent_qrt and spot.qrt: return False case "needs_good_location": # If true, spots require a "good" location to be returned diff --git a/spotproviders/dxcluster.py b/spotproviders/dxcluster.py index 4d49f2c..8f19a0f 100644 --- a/spotproviders/dxcluster.py +++ b/spotproviders/dxcluster.py @@ -16,13 +16,11 @@ class DXCluster(SpotProvider): """Spot provider for a DX Cluster. Hostname, port, login_prompt, login_callsign and allow_rbn_spots are provided in config. See config-example.yml for examples.""" - _CALLSIGN_PATTERN = "([a-z|0-9|/]+)" - _FREQUENCY_PATTERN = "([0-9|.]+)" _LINE_PATTERN_EXCLUDE_RBN = re.compile( - "^DX de " + _CALLSIGN_PATTERN + ":\\s+" + _FREQUENCY_PATTERN + "\\s+" + _CALLSIGN_PATTERN + "\\s+(.*)\\s+(\\d{4}Z)", + r"^DX de ([a-z0-9/]+):\s+([0-9.]+)\s+([a-z0-9/]+)\s+(.*)\s+(\d{4}Z)", re.IGNORECASE) _LINE_PATTERN_ALLOW_RBN = re.compile( - "^DX de " + _CALLSIGN_PATTERN + "-?#?:\\s+" + _FREQUENCY_PATTERN + "\\s+" + _CALLSIGN_PATTERN + "\\s+(.*)\\s+(\\d{4}Z)", + r"^DX de ([a-z0-9/]+)-?#?:\s+([0-9.]+)\s+([a-z0-9/]+)\s+(.*)\s+(\d{4}Z)", re.IGNORECASE) def __init__(self, provider_config): @@ -74,7 +72,7 @@ class DXCluster(SpotProvider): match = self._spot_line_pattern.match(telnet_output.decode("latin-1")) if match: spot_time = datetime.strptime(match.group(5), "%H%MZ") - spot_datetime = datetime.combine(datetime.today(), spot_time.time()).replace(tzinfo=pytz.UTC) + spot_datetime = datetime.combine(datetime.now(pytz.UTC).date(), spot_time.time(), tzinfo=pytz.UTC) spot = Spot(source=self.name, dx_call=match.group(3), de_call=match.group(1), diff --git a/spotproviders/rbn.py b/spotproviders/rbn.py index 468a252..e264732 100644 --- a/spotproviders/rbn.py +++ b/spotproviders/rbn.py @@ -16,10 +16,8 @@ class RBN(SpotProvider): """Spot provider for the Reverse Beacon Network. Connects to a single port, if you want both CW/RTTY (port 7000) and FT8 (port 7001) you need to instantiate two copies of this. The port is provided as an argument to the constructor.""" - _CALLSIGN_PATTERN = "([a-z|0-9|/]+)" - _FREQUENCY_PATTERM = "([0-9|.]+)" _LINE_PATTERN = re.compile( - "^DX de " + _CALLSIGN_PATTERN + "-.*:\\s+" + _FREQUENCY_PATTERM + "\\s+" + _CALLSIGN_PATTERN + "\\s+(.*)\\s+(\\d{4}Z)", + r"^DX de ([a-z0-9/]+)-.*:\s+([0-9.]+)\s+([a-z0-9/]+)\s+(.*)\s+(\d{4}Z)", re.IGNORECASE) def __init__(self, provider_config): @@ -65,7 +63,7 @@ class RBN(SpotProvider): match = self._LINE_PATTERN.match(telnet_output.decode("latin-1")) if match: spot_time = datetime.strptime(match.group(5), "%H%MZ") - spot_datetime = datetime.combine(datetime.today(), spot_time.time()).replace(tzinfo=pytz.UTC) + spot_datetime = datetime.combine(datetime.now(pytz.UTC).date(), spot_time.time(), tzinfo=pytz.UTC) spot = Spot(source=self.name, dx_call=match.group(3), de_call=match.group(1), diff --git a/spotproviders/spot_provider.py b/spotproviders/spot_provider.py index 334f642..7647d6f 100644 --- a/spotproviders/spot_provider.py +++ b/spotproviders/spot_provider.py @@ -44,7 +44,8 @@ class SpotProvider: # Fill in any blanks and add to the list spot.infer_missing() self._add_spot(spot) - self.last_spot_time = datetime.fromtimestamp(max(map(lambda s: s.time, spots)), pytz.UTC) + if spots: + self.last_spot_time = datetime.fromtimestamp(max(map(lambda s: s.time, spots)), pytz.UTC) def _submit(self, spot): """Submit a single spot retrieved from the provider. This will be added to the list regardless of its age. Spots diff --git a/templates/about.html b/templates/about.html index 12207ed..cab4e61 100644 --- a/templates/about.html +++ b/templates/about.html @@ -66,7 +66,7 @@
This software is dedicated to the memory of Tom G1PJB, SK, a friend and colleague who sadly passed away around the time I started writing it in Autumn 2025. I was looking forward to showing it to you when it was done.
- + {% end %} \ No newline at end of file diff --git a/templates/add_spot.html b/templates/add_spot.html index 8d367b6..404e681 100644 --- a/templates/add_spot.html +++ b/templates/add_spot.html @@ -69,8 +69,8 @@ - - + + {% end %} \ No newline at end of file diff --git a/templates/alerts.html b/templates/alerts.html index 6e8d5df..7f3d25c 100644 --- a/templates/alerts.html +++ b/templates/alerts.html @@ -56,8 +56,8 @@ - - + + {% end %} \ No newline at end of file diff --git a/templates/bands.html b/templates/bands.html index 86b88a9..c06443c 100644 --- a/templates/bands.html +++ b/templates/bands.html @@ -62,9 +62,9 @@ - - - + + + {% end %} \ No newline at end of file diff --git a/templates/base.html b/templates/base.html index c55b01c..60da102 100644 --- a/templates/base.html +++ b/templates/base.html @@ -46,10 +46,10 @@ crossorigin="anonymous"> - - - - + + + + diff --git a/templates/map.html b/templates/map.html index 3783320..a855055 100644 --- a/templates/map.html +++ b/templates/map.html @@ -70,9 +70,9 @@ - - - + + + {% end %} \ No newline at end of file diff --git a/templates/spots.html b/templates/spots.html index 2ff3151..ad75b5e 100644 --- a/templates/spots.html +++ b/templates/spots.html @@ -87,9 +87,9 @@ - - - + + + {% end %} \ No newline at end of file diff --git a/templates/status.html b/templates/status.html index cdcdbb8..ab5e176 100644 --- a/templates/status.html +++ b/templates/status.html @@ -3,8 +3,8 @@ - - + + {% end %} \ No newline at end of file