From 1a1743d11c62d7a80eae99dcac20c69e8bf87088 Mon Sep 17 00:00:00 2001 From: Ian Renton Date: Fri, 18 Sep 2026 18:38:35 +0100 Subject: [PATCH] ruff fixes --- core/activity_lookup_helper.py | 2 +- core/geo_utils.py | 4 ++-- data/spot.py | 4 ++-- providers/alert/wota.py | 4 ++-- providers/callsigndata/hamqth.py | 2 +- providers/callsigndata/qrz.py | 2 +- providers/solarconditions/noaa3dayforecast.py | 4 +++- providers/spot/dxcluster.py | 2 +- providers/spot/parksnpeaks.py | 3 ++- providers/spot/rbn.py | 2 +- providers/spot/sota.py | 3 ++- providers/spot/tiles.py | 3 ++- providers/spot/websocket_spot_provider.py | 2 +- providers/spot/wota.py | 6 ++++-- providers/spot/xota.py | 1 - telnetserver/telnetserver.py | 4 +++- webserver/handlers/api/v1_compatability.py | 5 +++++ webserver/sse_broadcaster.py | 2 +- 18 files changed, 34 insertions(+), 21 deletions(-) diff --git a/core/activity_lookup_helper.py b/core/activity_lookup_helper.py index 10183f1..1e6674f 100644 --- a/core/activity_lookup_helper.py +++ b/core/activity_lookup_helper.py @@ -84,7 +84,7 @@ def get_activity_ref_info(activity_name, ref_id): activity_ref.latitude = ll[0] activity_ref.longitude = ll[1] except Exception: - logger.warning("Invalid lat/lon received for WAB/WAI reference") + logger.warning("Invalid lat/lon received for WAB/WAI reference", exc_info=True) return activity_ref elif activity_name.upper() == ActivityName.BOTA: diff --git a/core/geo_utils.py b/core/geo_utils.py index ee6fffa..d8cf28c 100644 --- a/core/geo_utils.py +++ b/core/geo_utils.py @@ -1,6 +1,6 @@ import logging import re -from math import floor +from math import floor, isnan from pyproj import Transformer from shapely.geometry import Point, Polygon @@ -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]): + if any(isnan(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/data/spot.py b/data/spot.py index 515e606..855c689 100644 --- a/data/spot.py +++ b/data/spot.py @@ -414,12 +414,12 @@ class Spot: self.dx_latitude = ll[0] self.dx_longitude = ll[1] except Exception: - logger.debug("Invalid grid received for spot") + logger.debug("Invalid grid received for spot", exc_info=True) 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 Exception: - logger.debug("Invalid lat/lon received for spot") + logger.debug("Invalid lat/lon received for spot", exc_info=True) # QRT comment detection if self.comment and not self.qrt: diff --git a/providers/alert/wota.py b/providers/alert/wota.py index 698e429..e9ce74b 100644 --- a/providers/alert/wota.py +++ b/providers/alert/wota.py @@ -53,7 +53,7 @@ class WOTA(HTTPAlertProvider): if len(ref_split) > 1: ref_name = str(ref_split[1]) except Exception: - logger.warning(f"Could not parse WOTA alert title: {source_alert.description}") + logger.warning(f"Could not parse WOTA alert title: {source_alert.description}", exc_info=True) # Pick apart the description comment = None @@ -64,7 +64,7 @@ class WOTA(HTTPAlertProvider): if len(desc_split) > 1: comment = desc_split[1].strip() except Exception: - logger.warning(f"Could not parse WOTA alert description: {source_alert.description}") + logger.warning(f"Could not parse WOTA alert description: {source_alert.description}", exc_info=True) time = datetime.strptime(source_alert.pub_date.content, self.RSS_DATE_TIME_FORMAT).astimezone(pytz.UTC) diff --git a/providers/callsigndata/hamqth.py b/providers/callsigndata/hamqth.py index bfe567e..41c8051 100644 --- a/providers/callsigndata/hamqth.py +++ b/providers/callsigndata/hamqth.py @@ -61,7 +61,7 @@ class HamQTH(APIQueryCallsignDataProvider): logger.debug("HamQTH login details incorrect, failed to look up with HamQTH.") return None except Exception: - logger.error("Exception when getting HamQTH session key") + logger.exception("Exception when getting HamQTH session key") return None if not session_id: diff --git a/providers/callsigndata/qrz.py b/providers/callsigndata/qrz.py index 4ed570c..64ecfa0 100644 --- a/providers/callsigndata/qrz.py +++ b/providers/callsigndata/qrz.py @@ -57,7 +57,7 @@ class QRZ(APIQueryCallsignDataProvider): logger.debug("QRZ.com login details incorrect, failed to look up with QRZ.") return None except Exception: - logger.error("Exception when getting QRZ.com session key") + logger.exception("Exception when getting QRZ.com session key") return None if not session_key: diff --git a/providers/solarconditions/noaa3dayforecast.py b/providers/solarconditions/noaa3dayforecast.py index 184dcb7..9620cd9 100644 --- a/providers/solarconditions/noaa3dayforecast.py +++ b/providers/solarconditions/noaa3dayforecast.py @@ -118,7 +118,9 @@ class NOAA3dayForecast(HTTPSolarConditionsProvider): column_dates = [] for month_str, day_str in date_matches: try: - column_dates.append(datetime.strptime(f"{day_str} {month_str} {year}", "%d %b %Y").date()) + column_dates.append( + datetime.strptime(f"{day_str} {month_str} {year}", "%d %b %Y").replace(tzinfo=timezone.utc).date() + ) except ValueError: logger.warning(f"NOAA K-index forecast: could not parse date: {month_str} {day_str} {year}") return None diff --git a/providers/spot/dxcluster.py b/providers/spot/dxcluster.py index eb537df..48b5bed 100644 --- a/providers/spot/dxcluster.py +++ b/providers/spot/dxcluster.py @@ -84,7 +84,7 @@ class DXCluster(SpotProvider): telnet_output = self._telnet.read_until("\n".encode("latin-1")) match = self._spot_line_pattern.match(telnet_output.decode("latin-1")) if match: - spot_time = datetime.strptime(match.group(5), "%H%MZ") + spot_time = datetime.strptime(match.group(5), "%H%MZ").replace(tzinfo=pytz.UTC) spot_datetime = datetime.combine( datetime.now(pytz.UTC).date(), spot_time.time(), diff --git a/providers/spot/parksnpeaks.py b/providers/spot/parksnpeaks.py index d03a012..dc9f2c0 100644 --- a/providers/spot/parksnpeaks.py +++ b/providers/spot/parksnpeaks.py @@ -1,6 +1,7 @@ import logging import re from datetime import datetime +from typing import ClassVar import pytz import requests @@ -20,7 +21,7 @@ class ParksNPeaks(HTTPSpotProvider): POLL_INTERVAL_SEC = 120 SPOTS_URL = "https://www.parksnpeaks.org/api/ALL" SUBMIT_URL = "https://www.parksnpeaks.org/api/SPOT/" - SUBMITTABLE_ACTIVITIES = [ + SUBMITTABLE_ACTIVITIES: ClassVar[list[ActivityName]] = [ ActivityName.POTA, ActivityName.SOTA, ActivityName.WWFF, diff --git a/providers/spot/rbn.py b/providers/spot/rbn.py index 7923b9e..eee0773 100644 --- a/providers/spot/rbn.py +++ b/providers/spot/rbn.py @@ -69,7 +69,7 @@ class RBN(SpotProvider): telnet_output = self._telnet.read_until("\n".encode("latin-1")) match = self._LINE_PATTERN.match(telnet_output.decode("latin-1")) if match: - spot_time = datetime.strptime(match.group(5), "%H%MZ") + spot_time = datetime.strptime(match.group(5), "%H%MZ").replace(tzinfo=pytz.UTC) spot_datetime = datetime.combine( datetime.now(pytz.UTC).date(), spot_time.time(), diff --git a/providers/spot/sota.py b/providers/spot/sota.py index 1fccbae..07d527e 100644 --- a/providers/spot/sota.py +++ b/providers/spot/sota.py @@ -1,5 +1,6 @@ import logging from datetime import datetime +from typing import ClassVar import requests from requests.exceptions import ConnectionError, ConnectTimeout, ReadTimeout @@ -24,7 +25,7 @@ class SOTA(HTTPSpotProvider): SPOTS_URL = "https://api-db2.sota.org.uk/api/spots/60/all/all" SUBMIT_URL = "https://api-db2.sota.org.uk/api/spots" - VALID_MODES = ["AM", "CW", "Data", "DV", "FM", "SSB"] + VALID_MODES: ClassVar[list[str]] = ["AM", "CW", "Data", "DV", "FM", "SSB"] def __init__(self, provider_config): super().__init__("SOTA", provider_config, self.EPOCH_URL, self.POLL_INTERVAL_SEC) diff --git a/providers/spot/tiles.py b/providers/spot/tiles.py index f74dbee..8e4e19c 100644 --- a/providers/spot/tiles.py +++ b/providers/spot/tiles.py @@ -1,5 +1,6 @@ import logging from datetime import datetime +from typing import ClassVar import requests @@ -18,7 +19,7 @@ class Tiles(HTTPSpotProvider): POLL_INTERVAL_SEC = 120 SPOTS_URL = "https://icneuzxitdqtofutxbla.supabase.co/functions/v1/spots?active_hours=24" SUBMIT_URL = "https://icneuzxitdqtofutxbla.supabase.co/functions/v1/self-spot" - VALID_MODES = [ + VALID_MODES: ClassVar[list[str]] = [ "SSB", "CW", "FT8", diff --git a/providers/spot/websocket_spot_provider.py b/providers/spot/websocket_spot_provider.py index 5c5af61..13e460c 100644 --- a/providers/spot/websocket_spot_provider.py +++ b/providers/spot/websocket_spot_provider.py @@ -81,7 +81,7 @@ class WebsocketSpotProvider(SpotProvider): self._ws.close() except Exception: # No problem, we were getting rid of this object anyway. - pass + logger.debug(f"Exception while closing socket in {self.name}", exc_info=True) self._ws = None if not self._stop_event.is_set(): self._stop_event.wait(timeout=5) # Wait before trying to reconnect diff --git a/providers/spot/wota.py b/providers/spot/wota.py index 3026bd7..52a6f46 100644 --- a/providers/spot/wota.py +++ b/providers/spot/wota.py @@ -54,7 +54,7 @@ class WOTA(HTTPSpotProvider): if len(ref_split) > 1: ref_name = str(ref_split[1]) except Exception: - logger.warning(f"Could not parse WOTA spot title: {source_spot.title}") + logger.warning(f"Could not parse WOTA spot title: {source_spot.title}", exc_info=True) # Pick apart the description freq_hz = None @@ -75,7 +75,9 @@ class WOTA(HTTPSpotProvider): if len(desc_split) > 2: spotter = desc_split[2].replace("Spotted by ", "").replace(".", "").upper().strip() except Exception: - logger.warning(f"Could not parse WOTA spot description: {source_spot.description}") + logger.warning( + f"Could not parse WOTA spot description: {source_spot.description}", exc_info=True + ) time = datetime.strptime(source_spot.pub_date.content, self.RSS_DATE_TIME_FORMAT).astimezone( pytz.UTC diff --git a/providers/spot/xota.py b/providers/spot/xota.py index a8544aa..292b794 100644 --- a/providers/spot/xota.py +++ b/providers/spot/xota.py @@ -17,7 +17,6 @@ class XOTA(WebsocketSpotProvider): is why we also provide a sig_ref_prefix in our config. This is applied to the reference ID, so e.g. "T-01" at C3 might become "C3 T-01". This allows us to provide location lookups for TOTA at several conferences.""" - LOCATION_DATA = {} ACTIVITY = None def __init__(self, provider_config): diff --git a/telnetserver/telnetserver.py b/telnetserver/telnetserver.py index 57996ea..0ba3ec2 100644 --- a/telnetserver/telnetserver.py +++ b/telnetserver/telnetserver.py @@ -155,7 +155,8 @@ class TelnetServer: writer.close() await writer.wait_closed() except Exception: - pass + # No problem, we were disconnecting this client anyway. + logger.debug("Exception while closing telnet client connection", exc_info=True) self._clients.clear() def publish(self, spot: Spot): @@ -178,6 +179,7 @@ class TelnetServer: writer.write(encoded_line) await writer.drain() except Exception: + logger.debug("Exception while writing to telnet client, assuming it disconnected", exc_info=True) disconnected_clients.add(writer) # Clean up any disconnected connections caught during writing diff --git a/webserver/handlers/api/v1_compatability.py b/webserver/handlers/api/v1_compatability.py index 1fed156..c855830 100644 --- a/webserver/handlers/api/v1_compatability.py +++ b/webserver/handlers/api/v1_compatability.py @@ -1,7 +1,11 @@ +import logging + import tornado from tornado.httpclient import AsyncHTTPClient from tornado.httputil import HTTPHeaders +logger = logging.getLogger(__name__) + _LEGACY_PARAM_TO_HEADER_MAP = { "qrz_username": "X-QRZ-Username", "qrz_password": "X-QRZ-Password", @@ -41,6 +45,7 @@ class V1RedirectHandler(tornado.web.RequestHandler): request_timeout=10.0, ) except Exception as e: + logger.exception("Exception when proxying legacy v1 API request") raise tornado.web.HTTPError(502, reason=str(e)) self.set_status(response.code, response.reason) diff --git a/webserver/sse_broadcaster.py b/webserver/sse_broadcaster.py index adc84dc..12b512f 100644 --- a/webserver/sse_broadcaster.py +++ b/webserver/sse_broadcaster.py @@ -42,5 +42,5 @@ class SSEBroadcaster: handler.callback(value) except Exception: # Connection probably dropped, ignore and de-register the handler to stop getting future items. - logger.debug("Failed to push to an SSE client; dropping it") + logger.debug("Failed to push to an SSE client; dropping it", exc_info=True) self.unregister(handler)