From a6e54f524d297b8c0ade3a60a610a24f0cef889b Mon Sep 17 00:00:00 2001 From: Ian Renton Date: Sat, 15 Aug 2026 08:43:19 +0100 Subject: [PATCH] More ruff linter fixes --- core/config.py | 3 +- core/geo_utils.py | 4 +- core/live_data_cache.py | 2 +- core/sig_lookup_helper.py | 2 +- core/status_reporter.py | 54 +++++------------------ core/utils.py | 14 +++--- data/alert.py | 2 +- data/spot.py | 15 ++++--- providers/callsigndata/hamqth.py | 8 ++-- providers/callsigndata/qrz.py | 6 +-- providers/sigrefdata/arlhs.py | 2 +- providers/sigrefdata/gma.py | 2 +- providers/sigrefdata/illw.py | 2 +- providers/sigrefdata/mota.py | 2 +- providers/sigrefdata/pota.py | 4 +- providers/sigrefdata/siota.py | 4 +- providers/sigrefdata/sota.py | 2 +- providers/sigrefdata/towers.py | 2 +- providers/sigrefdata/wca.py | 2 +- providers/sigrefdata/wwbota.py | 2 +- providers/sigrefdata/wwff.py | 2 +- providers/spot/dxcluster.py | 8 ++-- providers/spot/gma.py | 2 +- providers/spot/rbn.py | 2 +- providers/spot/spot_provider.py | 2 +- providers/spot/ukpacketnet.py | 8 ++-- providers/spot/websocket_spot_provider.py | 4 +- providers/spot/wota.py | 5 +-- providers/spot/xota.py | 2 +- server/handlers/api/alerts.py | 6 +-- server/handlers/api/dxstats.py | 2 +- server/handlers/api/lookups.py | 2 +- server/handlers/api/options.py | 32 +++----------- server/handlers/api/spots.py | 6 +-- spothole.py | 5 --- 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 +- 43 files changed, 99 insertions(+), 153 deletions(-) diff --git a/core/config.py b/core/config.py index 6e6d998..5371c2c 100644 --- a/core/config.py +++ b/core/config.py @@ -1,6 +1,7 @@ import importlib import logging import os +import sys import yaml @@ -11,7 +12,7 @@ if not os.path.isfile("config.yml"): logger.error( "Your config file is missing. Ensure you have copied config-example.yml to config.yml and updated it according to your needs." ) - exit() + sys.exit() # Load config with open("config.yml") as f: diff --git a/core/geo_utils.py b/core/geo_utils.py index 8c32131..ee6fffa 100644 --- a/core/geo_utils.py +++ b/core/geo_utils.py @@ -73,7 +73,7 @@ def lat_lon_for_grid_sw_corner(grid): """Convert a Maidenhead grid reference of arbitrary precision to the lat/long of the southwest corner of the square. Returns None if the grid format is invalid.""" - lat, lon, lat_cell_size, lon_cell_size = lat_lon_for_grid_sw_corner_plus_size(grid) + lat, lon, _lat_cell_size, _lon_cell_size = lat_lon_for_grid_sw_corner_plus_size(grid) if lat is not None and lon is not None: return [lat, lon] else: @@ -156,7 +156,7 @@ def lat_lon_for_grid_sw_corner_plus_size(grid): lat -= 90.0 # Return None values on maths errors - if any(x != x for x in [lat, lon, lat_cell_size, lon_cell_size]): # NaN check + if any(x != x for x in [lat, lon, lat_cell_size, lon_cell_size]): return None, None, None, None return lat, lon, lat_cell_size, lon_cell_size diff --git a/core/live_data_cache.py b/core/live_data_cache.py index 57526df..725cb4d 100644 --- a/core/live_data_cache.py +++ b/core/live_data_cache.py @@ -71,7 +71,7 @@ class LiveDataCache: data = [(k, v, time.time()) for k, v in self._cache.items()] try: self._disk_cache.set("snapshot", data) - except Exception as e: + except Exception: logger.exception(f"Failed to write snapshot to {self._snapshot_dir}") def _load_snapshot(self): diff --git a/core/sig_lookup_helper.py b/core/sig_lookup_helper.py index 5388b4b..5c2c2fe 100644 --- a/core/sig_lookup_helper.py +++ b/core/sig_lookup_helper.py @@ -60,7 +60,7 @@ def get_sig_ref_info(sig, ref_id): sig_ref.grid = latlong_to_locator(ll[0], ll[1], 6) sig_ref.latitude = ll[0] sig_ref.longitude = ll[1] - except: + except Exception: logger.warning("Invalid lat/lon received for WAB/WAI reference") return sig_ref diff --git a/core/status_reporter.py b/core/status_reporter.py index 73597ef..8cff552 100644 --- a/core/status_reporter.py +++ b/core/status_reporter.py @@ -54,9 +54,7 @@ class StatusReporter: DATA_STORE.status_data["mem_use_mb"] = round(psutil.Process(os.getpid()).memory_info().rss / (1024 * 1024), 3) DATA_STORE.status_data["num_spots"] = len(DATA_STORE.spots.values()) DATA_STORE.status_data["num_alerts"] = len(DATA_STORE.alerts.values()) - DATA_STORE.status_data["spot_providers"] = list( - map( - lambda p: { + DATA_STORE.status_data["spot_providers"] = [{ "name": p.name, "enabled": p.enabled, "enabled_by_default_in_web_ui": p.enabled_by_default_in_web_ui, @@ -67,52 +65,32 @@ class StatusReporter: "last_spot": p.last_spot_time.replace(tzinfo=pytz.UTC).timestamp() if p.last_spot_time.year > 2000 else 0, - }, - DATA_PROVIDERS.spot_providers, - ) - ) - DATA_STORE.status_data["alert_providers"] = list( - map( - lambda p: { + } for p in DATA_PROVIDERS.spot_providers] + DATA_STORE.status_data["alert_providers"] = [{ "name": p.name, "enabled": p.enabled, "status": p.status, "last_updated": p.last_update_time.replace(tzinfo=pytz.UTC).timestamp() if p.last_update_time.year > 2000 else 0, - }, - DATA_PROVIDERS.alert_providers, - ) - ) - DATA_STORE.status_data["solar_condition_providers"] = list( - map( - lambda p: { + } for p in DATA_PROVIDERS.alert_providers] + DATA_STORE.status_data["solar_condition_providers"] = [{ "name": p.name, "enabled": p.enabled, "status": p.status, "last_updated": p.last_update_time.replace(tzinfo=pytz.UTC).timestamp() if p.last_update_time.year > 2000 else 0, - }, - DATA_PROVIDERS.solar_condition_providers, - ) - ) - DATA_STORE.status_data["static_data_providers"] = list( - map( - lambda p: { + } for p in DATA_PROVIDERS.solar_condition_providers] + DATA_STORE.status_data["static_data_providers"] = [{ "name": p.name, "enabled": p.enabled, "status": p.status, "last_updated": p.last_update_time.replace(tzinfo=pytz.UTC).timestamp() if p.last_update_time.year > 2000 else 0, - }, - DATA_PROVIDERS.static_data_providers, - ) - ) - DATA_STORE.status_data["sig_ref_data_providers"] = list( - map( - lambda p: { + } for p in DATA_PROVIDERS.static_data_providers] + DATA_STORE.status_data["sig_ref_data_providers"] = [{ "sig_name": p.sig_name, "enabled": p.enabled, "status": p.status, @@ -120,13 +98,8 @@ class StatusReporter: if p.last_update_time.year > 2000 else 0, "reference_count": p.reference_count, - }, - DATA_PROVIDERS.sig_ref_data_providers, - ) - ) - DATA_STORE.status_data["callsign_data_providers"] = list( - map( - lambda p: { + } for p in DATA_PROVIDERS.sig_ref_data_providers] + DATA_STORE.status_data["callsign_data_providers"] = [{ "name": p.name, "enabled": p.enabled, "status": p.status, @@ -134,10 +107,7 @@ class StatusReporter: if p.last_update_time.year > 2000 else 0, "lookup_count": p.lookup_count, - }, - DATA_PROVIDERS.callsign_data_providers, - ) - ) + } for p in DATA_PROVIDERS.callsign_data_providers] DATA_STORE.status_data["cleanup"] = { "status": CLEANUP_TIMER.status, "last_ran": CLEANUP_TIMER.last_cleanup_time.replace(tzinfo=pytz.UTC).timestamp() diff --git a/core/utils.py b/core/utils.py index 895423a..70c0744 100644 --- a/core/utils.py +++ b/core/utils.py @@ -32,7 +32,7 @@ def infer_mode_from_comment(comment): for mode in ALL_MODES: if mode in comment.upper(): return mode - for mode in MODE_ALIASES.keys(): + for mode in MODE_ALIASES: if mode in comment.upper(): return MODE_ALIASES[mode] return None @@ -101,7 +101,7 @@ def infer_mode_from_frequency(freq): def get_flag_for_dxcc(dxcc): """Get an emoji flag for a given DXCC entity ID""" - dxcc_data = DATA_STORE.dxcc_data[dxcc] if dxcc in DATA_STORE.dxcc_data else None + dxcc_data = DATA_STORE.dxcc_data.get(dxcc, None) return dxcc_data["flag"] if dxcc_data else None @@ -113,11 +113,11 @@ def get_callsign_object_from_pyhamtools_callinfo(callsign, callinfo): home_call = callinfo.get_homecall(callsign) data = callinfo.get_all(callsign) - country = data["country"] if "country" in data else None - dxcc_id = data["adif"] if "adif" in data else None - continent = data["continent"] if "continent" in data else None - cq_zone = data["cqz"] if "cqz" in data else None - itu_zone = data["ituz"] if "ituz" in data else None + country = data.get("country", None) + dxcc_id = data.get("adif", None) + continent = data.get("continent", None) + cq_zone = data.get("cqz", None) + itu_zone = data.get("ituz", None) lat = float(data["latitude"]) if "latitude" in data else None lon = float(data["longitude"]) if "longitude" in data else None grid = None diff --git a/data/alert.py b/data/alert.py index 9074f8c..40c71f7 100644 --- a/data/alert.py +++ b/data/alert.py @@ -127,7 +127,7 @@ class Alert: # DX operator name lookup, using QRZ.com/HamQTH. if self.dx_calls and not self.dx_names: - self.dx_names = list(map(lambda c: get_call_info(c, credentials).name, self.dx_calls)) + self.dx_names = [get_call_info(c, credentials).name for c in self.dx_calls] except Exception: logger.exception("Exception while inferring missing data from spot") diff --git a/data/spot.py b/data/spot.py index 5d0e8a3..dbcadde 100644 --- a/data/spot.py +++ b/data/spot.py @@ -4,6 +4,7 @@ import logging import re from dataclasses import dataclass from datetime import datetime, timedelta +from math import isnan import pytz from pyhamtools.locator import latlong_to_locator, locator_to_latlong @@ -229,7 +230,7 @@ class Spot: self.de_flag = get_flag_for_dxcc(self.de_dxcc_id) # Remove NaNs in frequency - if self.freq and self.freq == float("nan"): + if self.freq and isnan(self.freq): self.freq = None # Band from frequency @@ -364,12 +365,12 @@ class Spot: ll = locator_to_latlong(self.dx_grid) self.dx_latitude = ll[0] self.dx_longitude = ll[1] - except: + except Exception: logger.debug("Invalid grid received for spot") if self.dx_latitude and self.dx_longitude and not self.dx_grid: try: self.dx_grid = latlong_to_locator(self.dx_latitude, self.dx_longitude, 8) - except: + except Exception: logger.debug("Invalid lat/lon received for spot") # QRT comment detection @@ -438,12 +439,12 @@ class Spot: self.de_call and any(char.isdigit() for char in str(self.de_call)) and not (self.de_call.startswith("T2") and self.source == "APRS-IS") + and not self.de_latitude ): # DE operator location lookup - if not self.de_latitude: - self.de_latitude = de_call_info.latitude - self.de_longitude = de_call_info.longitude - self.de_grid = de_call_info.grid + self.de_latitude = de_call_info.latitude + self.de_longitude = de_call_info.longitude + self.de_grid = de_call_info.grid except Exception: logger.exception("Exception while inferring missing data from spot") diff --git a/providers/callsigndata/hamqth.py b/providers/callsigndata/hamqth.py index 1ac0257..33366b7 100644 --- a/providers/callsigndata/hamqth.py +++ b/providers/callsigndata/hamqth.py @@ -139,10 +139,10 @@ class HamQTH(APIQueryCallsignDataProvider): return Callsign( call=callsign, home_call=callinfo.Callinfo.get_homecall(callsign), - name=data["nick"] if "nick" in data else None, - qth=data["qth"] if "qth" in data else None, - country=data["country"] if "country" in data else None, - continent=data["continent"] if "continent" in data else None, + name=data.get("nick", None), + qth=data.get("qth", None), + country=data.get("country", None), + continent=data.get("continent", None), latitude=lat, longitude=lon, grid=grid, diff --git a/providers/callsigndata/qrz.py b/providers/callsigndata/qrz.py index b9ed558..8243136 100644 --- a/providers/callsigndata/qrz.py +++ b/providers/callsigndata/qrz.py @@ -161,9 +161,9 @@ class QRZ(APIQueryCallsignDataProvider): call=callsign, home_call=callinfo.Callinfo.get_homecall(callsign), name=name, - qth=data["addr2"] if "addr2" in data else None, - country=data["country"] if "country" in data else None, - continent=data["continent"] if "continent" in data else None, + qth=data.get("addr2", None), + country=data.get("country", None), + continent=data.get("continent", None), latitude=lat, longitude=lon, grid=grid, diff --git a/providers/sigrefdata/arlhs.py b/providers/sigrefdata/arlhs.py index 3fd2163..1a060c6 100644 --- a/providers/sigrefdata/arlhs.py +++ b/providers/sigrefdata/arlhs.py @@ -26,7 +26,7 @@ class ARLHS(FileDownloadSIGRefDataProvider): SIGRef( sig=self.SIG, id=ref_id, - name=row["Name"] if "Name" in row else None, + name=row.get("Name", None), ref_type="Lighthouse", url=f"https://www.cqgma.org/zinfo.php?ref={ref_id}", latitude=float(row["Latitude"]) if "Latitude" in row and row["Latitude"] != "" else None, diff --git a/providers/sigrefdata/gma.py b/providers/sigrefdata/gma.py index 3c47cbb..4d7f3e6 100644 --- a/providers/sigrefdata/gma.py +++ b/providers/sigrefdata/gma.py @@ -25,7 +25,7 @@ class GMA(FileDownloadSIGRefDataProvider): SIGRef( sig=self.SIG, id=ref_id, - name=row["Name"] if "Name" in row else None, + name=row.get("Name", None), ref_type="Summit", url=f"https://www.cqgma.org/zinfo.php?ref={ref_id}", latitude=float(row["Latitude"]) if "Latitude" in row and row["Latitude"] != "" else None, diff --git a/providers/sigrefdata/illw.py b/providers/sigrefdata/illw.py index 59b3c0d..6c77d35 100644 --- a/providers/sigrefdata/illw.py +++ b/providers/sigrefdata/illw.py @@ -26,7 +26,7 @@ class ILLW(FileDownloadSIGRefDataProvider): SIGRef( sig=self.SIG, id=ref_id, - name=row["Name"] if "Name" in row else None, + name=row.get("Name", None), ref_type="Lighthouse", url=f"https://www.cqgma.org/zinfo.php?ref={ref_id}", latitude=float(row["Latitude"]) if "Latitude" in row and row["Latitude"] != "" else None, diff --git a/providers/sigrefdata/mota.py b/providers/sigrefdata/mota.py index 745b400..eb88f40 100644 --- a/providers/sigrefdata/mota.py +++ b/providers/sigrefdata/mota.py @@ -25,7 +25,7 @@ class MOTA(FileDownloadSIGRefDataProvider): SIGRef( sig=self.SIG, id=ref_id, - name=row["Name"] if "Name" in row else None, + name=row.get("Name", None), ref_type="Mill", url=f"https://www.cqgma.org/zinfo.php?ref={ref_id}", latitude=float(row["Latitude"]) if "Latitude" in row and row["Latitude"] != "" else None, diff --git a/providers/sigrefdata/pota.py b/providers/sigrefdata/pota.py index a5f12c0..b639ecb 100644 --- a/providers/sigrefdata/pota.py +++ b/providers/sigrefdata/pota.py @@ -25,10 +25,10 @@ class POTA(FileDownloadSIGRefDataProvider): SIGRef( sig=self.SIG, id=ref_id, - name=row["name"] if "name" in row else None, + name=row.get("name", None), ref_type="Park", url=f"https://pota.app/#/park/{ref_id}", - grid=row["grid"] if "grid" in row else None, + grid=row.get("grid", None), latitude=float(row["latitude"]) if "latitude" in row and row["latitude"] != "" else None, longitude=float(row["longitude"]) if "longitude" in row and row["longitude"] != "" else None, ) diff --git a/providers/sigrefdata/siota.py b/providers/sigrefdata/siota.py index d120138..fc042d0 100644 --- a/providers/sigrefdata/siota.py +++ b/providers/sigrefdata/siota.py @@ -25,9 +25,9 @@ class SIOTA(FileDownloadSIGRefDataProvider): SIGRef( sig=self.SIG, id=ref_id, - name=row["NAME"] if "NAME" in row else None, + name=row.get("NAME", None), ref_type="Silo", - grid=row["LOCATOR"] if "LOCATOR" in row else None, + grid=row.get("LOCATOR", None), latitude=float(row["LAT"]) if "LAT" in row else None, longitude=float(row["LNG"]) if "LNG" in row else None, ) diff --git a/providers/sigrefdata/sota.py b/providers/sigrefdata/sota.py index 1b95ff7..60b1a9d 100644 --- a/providers/sigrefdata/sota.py +++ b/providers/sigrefdata/sota.py @@ -29,7 +29,7 @@ class SOTA(FileDownloadSIGRefDataProvider): ref = SIGRef( sig=self.SIG, id=ref_id, - name=row["SummitName"] if "SummitName" in row else None, + name=row.get("SummitName", None), ref_type="Summit", url=f"https://www.sotadata.org.uk/en/summit/{ref_id}", latitude=latitude, diff --git a/providers/sigrefdata/towers.py b/providers/sigrefdata/towers.py index 708cb51..226da38 100644 --- a/providers/sigrefdata/towers.py +++ b/providers/sigrefdata/towers.py @@ -25,7 +25,7 @@ class Towers(FileDownloadSIGRefDataProvider): SIGRef( sig=self.SIG, id=ref_id, - name=row["Nazev"] if "Nazev" in row else None, + name=row.get("Nazev", None), ref_type="Tower", url=f"https://wwtota.com/seznam/karta_rozhledny.php?ref={ref_id}", grid=row["Lokator"] if "Lokator" in row and row["Lokator"] != "" else None, diff --git a/providers/sigrefdata/wca.py b/providers/sigrefdata/wca.py index 5359376..4f41737 100644 --- a/providers/sigrefdata/wca.py +++ b/providers/sigrefdata/wca.py @@ -44,7 +44,7 @@ class WCA(FileDownloadSIGRefDataProvider): SIGRef( sig=self.SIG, id=ref_id, - name=row["CLEAN NAME"] if "CLEAN NAME" in row else None, + name=row.get("CLEAN NAME", None), ref_type="Castle", url=f"https://www.cqgma.org/zinfo.php?ref={ref_id}", latitude=latitude, diff --git a/providers/sigrefdata/wwbota.py b/providers/sigrefdata/wwbota.py index c73db52..ae6fa21 100644 --- a/providers/sigrefdata/wwbota.py +++ b/providers/sigrefdata/wwbota.py @@ -25,7 +25,7 @@ class WWBOTA(FileDownloadSIGRefDataProvider): SIGRef( sig=self.SIG, id=ref_id, - name=row["Name"] if "Name" in row else None, + name=row.get("Name", None), ref_type="Bunker", url=f"https://bunkerwiki.org/?s={ref_id}" if ref_id.startswith("B/G") else None, grid=row["Locator"] if "Locator" in row and row["Locator"] != "" else None, diff --git a/providers/sigrefdata/wwff.py b/providers/sigrefdata/wwff.py index 0a2707e..86f3652 100644 --- a/providers/sigrefdata/wwff.py +++ b/providers/sigrefdata/wwff.py @@ -25,7 +25,7 @@ class WWFF(FileDownloadSIGRefDataProvider): SIGRef( sig=self.SIG, id=ref_id, - name=row["name"] if "name" in row else None, + name=row.get("name", None), ref_type="Park", url=f"https://wwff.co/directory/?showRef={ref_id}", grid=row["iaruLocator"] if "iaruLocator" in row and row["iaruLocator"] != "-" else None, diff --git a/providers/spot/dxcluster.py b/providers/spot/dxcluster.py index 769967c..25273a7 100644 --- a/providers/spot/dxcluster.py +++ b/providers/spot/dxcluster.py @@ -30,15 +30,15 @@ class DXCluster(SpotProvider): def __init__(self, provider_config): """Constructor requires hostname and port""" - name = provider_config["name"] if "name" in provider_config else "Cluster" + name = provider_config.get("name", "Cluster") super().__init__(name, provider_config) self._hostname = provider_config["host"] self._port = provider_config["port"] - self._login_prompt = provider_config["login_prompt"] if "login_prompt" in provider_config else "login:" + self._login_prompt = provider_config.get("login_prompt", "login:") self._login_callsign = ( - provider_config["login_callsign"] if "login_callsign" in provider_config else SERVER_OWNER_CALLSIGN + provider_config.get("login_callsign", SERVER_OWNER_CALLSIGN) ) - self._allow_rbn_spots = provider_config["allow_rbn_spots"] if "allow_rbn_spots" in provider_config else False + self._allow_rbn_spots = provider_config.get("allow_rbn_spots", False) self._spot_line_pattern = ( self._LINE_PATTERN_ALLOW_RBN if self._allow_rbn_spots else self._LINE_PATTERN_EXCLUDE_RBN ) diff --git a/providers/spot/gma.py b/providers/spot/gma.py index 3322400..13b341b 100644 --- a/providers/spot/gma.py +++ b/providers/spot/gma.py @@ -148,7 +148,7 @@ class GMA(HTTPSpotProvider): logger.warning( f"GMA API returned a malformed response when looking up ref {source_spot['REF']}" ) - except: + except Exception: logger.exception( f"Exception when looking up {self.REF_INFO_URL_ROOT}{source_spot['REF']}, ignoring this spot for now" ) diff --git a/providers/spot/rbn.py b/providers/spot/rbn.py index 3f79b72..684f278 100644 --- a/providers/spot/rbn.py +++ b/providers/spot/rbn.py @@ -26,7 +26,7 @@ class RBN(SpotProvider): def __init__(self, provider_config): """Constructor requires port number.""" - name = provider_config["name"] if "name" in provider_config else "RBN" + name = provider_config.get("name", "RBN") super().__init__(name, provider_config) self._port = provider_config["port"] self._telnet = None diff --git a/providers/spot/spot_provider.py b/providers/spot/spot_provider.py index 18d4cce..5cc5685 100644 --- a/providers/spot/spot_provider.py +++ b/providers/spot/spot_provider.py @@ -39,7 +39,7 @@ class SpotProvider: spot.infer_missing() self._add_spot(spot) if spots: - self.last_spot_time = datetime.fromtimestamp(max(map(lambda s: s.time, spots)), pytz.UTC) + self.last_spot_time = datetime.fromtimestamp(max(s.time for s in 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/providers/spot/ukpacketnet.py b/providers/spot/ukpacketnet.py index fcc7f1e..9a6b788 100644 --- a/providers/spot/ukpacketnet.py +++ b/providers/spot/ukpacketnet.py @@ -20,7 +20,7 @@ class UKPacketNet(HTTPSpotProvider): new_spots = [] # Iterate through source data nodes = http_response.json()["nodes"] - for callsign, node in nodes.items(): + for node in nodes.values(): # The node corresponse to the spotter here. It has an "mheard" section which indicates which nodes it has # recently heard, which will be our "DX". But "mheard" stations are not necessarily over RF, they could be # via the internet, so we also need to look up the "port" on which the station was heard, and check that it @@ -34,7 +34,7 @@ class UKPacketNet(HTTPSpotProvider): # This is another packet station heard over RF, so we are good to create a Spot object. # First build a "full" comment combining some of the extra info - comment = listed_port["comment"] if "comment" in listed_port else "" + comment = listed_port.get("comment", "") comment = f"{comment} {listed_port['mode']}" if "mode" in listed_port else comment comment = ( f"{comment} {listed_port['modulation']}" if "modulation" in listed_port else comment @@ -82,7 +82,7 @@ class UKPacketNet(HTTPSpotProvider): time=datetime.strptime(heard["lastHeard"], "%Y-%m-%d %H:%M:%S") .replace(tzinfo=pytz.UTC) .timestamp(), - de_grid=node["location"]["locator"] if "locator" in node["location"] else None, + de_grid=node["location"].get("locator", None), de_latitude=node["location"]["coords"]["lat"], de_longitude=node["location"]["coords"]["lon"], ) @@ -99,7 +99,7 @@ class UKPacketNet(HTTPSpotProvider): for spot in new_spots: if spot.dx_call in nodes: spot.dx_grid = ( - nodes[spot.dx_call]["location"]["locator"] if "locator" in nodes[spot.dx_call]["location"] else None + nodes[spot.dx_call]["location"].get("locator", None) ) spot.dx_latitude = nodes[spot.dx_call]["location"]["coords"]["lat"] spot.dx_longitude = nodes[spot.dx_call]["location"]["coords"]["lon"] diff --git a/providers/spot/websocket_spot_provider.py b/providers/spot/websocket_spot_provider.py index 868dd5e..564a419 100644 --- a/providers/spot/websocket_spot_provider.py +++ b/providers/spot/websocket_spot_provider.py @@ -64,9 +64,9 @@ class WebsocketSpotProvider(SpotProvider): except Exception: logger.exception(f"Exception processing message from Websocket Spot Provider ({self.name})") - except Exception as e: + except Exception: self.status = "Error" - logger.exception(f"Exception in Websocket Spot Provider ({self.name})", e) + logger.exception(f"Exception in Websocket Spot Provider ({self.name})") else: self.status = "Disconnected" sleep(5) # Wait before trying to reconnect diff --git a/providers/spot/wota.py b/providers/spot/wota.py index 95becc3..de9e6bb 100644 --- a/providers/spot/wota.py +++ b/providers/spot/wota.py @@ -19,7 +19,6 @@ class WOTA(HTTPSpotProvider): POLL_INTERVAL_SEC = 120 SPOTS_URL = "https://www.wota.org.uk/spots_rss.php" - LIST_URL = "https://www.wota.org.uk/mapping/data/summits.json" RSS_DATE_TIME_FORMAT = "%a, %d %b %Y %H:%M:%S %z" def __init__(self, provider_config): @@ -83,8 +82,8 @@ class WOTA(HTTPSpotProvider): ) new_spots.append(spot) - except Exception as e: - logger.error("Exception parsing WOTA spot", e) + except Exception: + logger.exception("Exception parsing WOTA spot") return new_spots def can_submit_spot(self, sig): diff --git a/providers/spot/xota.py b/providers/spot/xota.py index 39a8d47..122d298 100644 --- a/providers/spot/xota.py +++ b/providers/spot/xota.py @@ -20,7 +20,7 @@ class XOTA(WebsocketSpotProvider): SIG = None def __init__(self, provider_config): - name = provider_config["name"] if "name" in provider_config else "xOTA" + name = provider_config.get("name", "xOTA") super().__init__(name, provider_config, provider_config["url"]) self.SIG = str(provider_config["sig"]) if "sig" in provider_config else None self._sig_ref_prefix = str(provider_config["sig_ref_prefix"]) if "sig_ref_prefix" in provider_config else "" diff --git a/server/handlers/api/alerts.py b/server/handlers/api/alerts.py index 181b6c4..2e999e3 100644 --- a/server/handlers/api/alerts.py +++ b/server/handlers/api/alerts.py @@ -150,7 +150,7 @@ def get_alert_list_with_filters(all_alerts, query): alerts.append(a) alerts = sorted(alerts, key=lambda alert: alert.start_time if alert and alert.start_time else 0) alerts = list(filter(lambda alert: alert_allowed_by_query(alert, query), alerts)) - if "limit" in query.keys(): + if "limit" in query: alerts = alerts[: int(query.get("limit"))] return alerts @@ -159,7 +159,7 @@ def alert_allowed_by_query(alert, query): """Given URL query params and an alert, figure out if the alert "passes" the requested filters or is rejected. The list of query parameters and their function is defined in the API docs.""" - for k in query.keys(): + for k in query: match k: case "received_since": since = datetime.fromtimestamp(float(query.get(k)), pytz.UTC) @@ -172,7 +172,7 @@ def alert_allowed_by_query(alert, query): # the alert is a dxpedition, it also always passes the check. if alert.is_dxpedition and ( query.get("dxpeditions_skip_max_duration_check").upper() == "TRUE" - if "dxpeditions_skip_max_duration_check" in query.keys() + if "dxpeditions_skip_max_duration_check" in query else False ): continue diff --git a/server/handlers/api/dxstats.py b/server/handlers/api/dxstats.py index e452e68..239088f 100644 --- a/server/handlers/api/dxstats.py +++ b/server/handlers/api/dxstats.py @@ -47,7 +47,7 @@ class APIDxStatsHandler(tornado.web.RequestHandler): one_hour_ago = (datetime.now(pytz.UTC) - timedelta(hours=1)).timestamp() counts = Counter() - for key in self._spots.keys(): + for key in self._spots: spot = self._spots.get(key) if spot is None: continue diff --git a/server/handlers/api/lookups.py b/server/handlers/api/lookups.py index c726db7..ccc06ed 100644 --- a/server/handlers/api/lookups.py +++ b/server/handlers/api/lookups.py @@ -108,7 +108,7 @@ class APILookupSIGRefHandler(tornado.web.RequestHandler): if "sig" in query_params and "id" in query_params: sig = str(query_params.get("sig")).upper() ref_id = str(query_params.get("id")).upper() - if sig in list(map(lambda p: p.name.upper(), SIGS)): + if sig in [p.name.upper() for p in SIGS]: if not get_ref_regex_for_sig(sig) or re.match(get_ref_regex_for_sig(sig), ref_id): data = populate_missing_sig_ref_info(SIGRef(id=ref_id, sig=sig)) self.write(safe_json_dumps(data)) diff --git a/server/handlers/api/options.py b/server/handlers/api/options.py index 9cc3960..d4923b4 100644 --- a/server/handlers/api/options.py +++ b/server/handlers/api/options.py @@ -62,36 +62,16 @@ class APIOptionsHandler(tornado.web.RequestHandler): # Spot/alert sources are filtered for only ones that are enabled in config, no point letting the user toggle # things that aren't even available. - spot_providers: list = list( - map( - lambda p: p["name"], - filter(lambda p: p["enabled"], self._status_data["spot_providers"]), - ) - ) - alert_providers = list( - map( - lambda p: p["name"], - filter(lambda p: p["enabled"], self._status_data["alert_providers"]), - ) - ) - callsign_data_providers = list( - map( - lambda p: p["name"], - filter( + spot_providers: list = [p["name"] for p in filter(lambda p: p["enabled"], self._status_data["spot_providers"])] + alert_providers = [p["name"] for p in filter(lambda p: p["enabled"], self._status_data["alert_providers"])] + callsign_data_providers = [p["name"] for p in filter( lambda p: p["enabled"], self._status_data["callsign_data_providers"], - ), - ) - ) - spot_providers_enabled_by_default = list( - map( - lambda p: p["name"], - filter( + )] + spot_providers_enabled_by_default = [p["name"] for p in filter( lambda p: p["enabled"] and p["enabled_by_default_in_web_ui"], self._status_data["spot_providers"], - ), - ) - ) + )] # If spotting to this server is enabled, "API" is another valid spot source even though it does not come from # one of our providers. diff --git a/server/handlers/api/spots.py b/server/handlers/api/spots.py index dee0577..5dfb180 100644 --- a/server/handlers/api/spots.py +++ b/server/handlers/api/spots.py @@ -153,7 +153,7 @@ def get_spot_list_with_filters(all_spots, query): spots.append(s) spots = sorted(spots, key=lambda spot: spot.time if spot and spot.time else 0, reverse=True) spots = list(filter(lambda spot: spot_allowed_by_query(spot, query), spots)) - if "limit" in query.keys(): + if "limit" in query: spots = spots[: int(query.get("limit"))] # Ensure only the latest spot of each callsign-SSID combo is present in the list. This relies on the @@ -163,7 +163,7 @@ def get_spot_list_with_filters(all_spots, query): # This is a special consideration for the geo map and band map views (and Field Spotter) because while # duplicates are fine in the main spot list (e.g. different cluster spots of the same DX) this doesn't # work well for the other views. - if "dedupe" in query.keys(): + if "dedupe" in query: dedupe = query.get("dedupe").upper() == "TRUE" if dedupe: spots_temp = [] @@ -182,7 +182,7 @@ def spot_allowed_by_query(spot, query): """Given URL query params and a spot, figure out if the spot "passes" the requested filters or is rejected. The list of query parameters and their function is defined in the API docs.""" - for k in query.keys(): + for k in query: match k: case "since": since = datetime.fromtimestamp(int(query.get(k)), pytz.UTC).timestamp() diff --git a/spothole.py b/spothole.py index 7b5a8ce..55f82b5 100644 --- a/spothole.py +++ b/spothole.py @@ -14,15 +14,10 @@ from server.webserver import WEB_SERVER logger = logging.getLogger(__name__) -# Globals -run = True - def shutdown(_signum=None, _frame=None): """Shutdown function""" - global run - logger.info("Stopping program...") WEB_SERVER.stop() DATA_PROVIDERS.stop() diff --git a/templates/add_spot.html b/templates/add_spot.html index 0128cde..def3887 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 f896921..46cbe2c 100644 --- a/templates/alerts.html +++ b/templates/alerts.html @@ -82,7 +82,7 @@ - + diff --git a/templates/bands.html b/templates/bands.html index f02f153..8072c1f 100644 --- a/templates/bands.html +++ b/templates/bands.html @@ -79,8 +79,8 @@ - - + + diff --git a/templates/base.html b/templates/base.html index 338c005..b5c2b1a 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,6 +1,6 @@ {% extends "skeleton.html" %} {% block head_extra %} - + @@ -15,10 +15,10 @@ window.fetchEventSource = fetchEventSource; - - - - + + + + {% end %} {% block body %}
diff --git a/templates/conditions.html b/templates/conditions.html index bf3ce1e..dcb8c0e 100644 --- a/templates/conditions.html +++ b/templates/conditions.html @@ -284,7 +284,7 @@
- + diff --git a/templates/map.html b/templates/map.html index 1225bb9..59d3276 100644 --- a/templates/map.html +++ b/templates/map.html @@ -112,8 +112,8 @@ - - + + diff --git a/templates/spots.html b/templates/spots.html index dee1e1c..1f0311c 100644 --- a/templates/spots.html +++ b/templates/spots.html @@ -118,8 +118,8 @@ - - + + diff --git a/templates/status.html b/templates/status.html index d4e2b6c..544e8eb 100644 --- a/templates/status.html +++ b/templates/status.html @@ -86,7 +86,7 @@ - +