From 76b0ec24b7df41a1f23e91f0e7b2cc892ec18fe6 Mon Sep 17 00:00:00 2001 From: Ian Renton Date: Fri, 3 Apr 2026 21:47:35 +0100 Subject: [PATCH] Hide conditions page entries if data isn't available --- server/handlers/pagetemplate.py | 7 +++++-- server/webserver.py | 32 +++++++++++++++++--------------- spothole.py | 3 ++- templates/about.html | 2 +- templates/add_spot.html | 4 ++-- templates/alerts.html | 4 ++-- templates/bands.html | 6 +++--- templates/base.html | 10 ++++++---- templates/conditions.html | 8 ++++++-- templates/map.html | 6 +++--- templates/spots.html | 6 +++--- templates/status.html | 4 ++-- webassets/js/conditions.js | 5 +++-- 13 files changed, 55 insertions(+), 42 deletions(-) diff --git a/server/handlers/pagetemplate.py b/server/handlers/pagetemplate.py index 3f18926..39adc06 100644 --- a/server/handlers/pagetemplate.py +++ b/server/handlers/pagetemplate.py @@ -11,9 +11,11 @@ from core.prometheus_metrics_handler import page_requests_counter class PageTemplateHandler(tornado.web.RequestHandler): """Handler for all HTML pages generated from templates""" - def initialize(self, template_name, web_server_metrics): + def initialize(self, template_name, web_server_metrics, has_hamqsl=False, has_noaa_forecast=False): self._template_name = template_name self._web_server_metrics = web_server_metrics + self._has_hamqsl = has_hamqsl + self._has_noaa_forecast = has_noaa_forecast def get(self): # Metrics @@ -24,4 +26,5 @@ class PageTemplateHandler(tornado.web.RequestHandler): # Load named template, and provide variables used in templates self.render(self._template_name + ".html", software_version=SOFTWARE_VERSION, allow_spotting=ALLOW_SPOTTING, - web_ui_options=WEB_UI_OPTIONS, baseurl = BASE_URL, current_path=self.request.path) \ No newline at end of file + web_ui_options=WEB_UI_OPTIONS, baseurl=BASE_URL, current_path=self.request.path, + has_hamqsl=self._has_hamqsl, has_noaa_forecast=self._has_noaa_forecast) \ No newline at end of file diff --git a/server/webserver.py b/server/webserver.py index af259ca..a942895 100644 --- a/server/webserver.py +++ b/server/webserver.py @@ -21,7 +21,7 @@ from server.handlers.pagetemplate import PageTemplateHandler class WebServer: """Provides the public-facing web server.""" - def __init__(self, spots, alerts, solar_conditions, status_data, port): + def __init__(self, spots, alerts, solar_conditions, status_data, solar_condition_providers, port): """Constructor""" self._spots = spots @@ -30,6 +30,7 @@ class WebServer: self._sse_spot_queues = [] self._sse_alert_queues = [] self._status_data = status_data + self._solar_condition_providers = solar_condition_providers self._port = port self._shutdown_event = asyncio.Event() self.web_server_metrics = { @@ -53,6 +54,12 @@ class WebServer: async def _start_inner(self): """Start method (async). Sets up the Tornado application.""" + provider_classes = [type(p).__name__ for p in self._solar_condition_providers if p.enabled] + has_hamqsl = "HamQSL" in provider_classes + has_noaa_forecast = "NOAA3dayForecast" in provider_classes + page_opts = {"web_server_metrics": self.web_server_metrics, "has_hamqsl": has_hamqsl, + "has_noaa_forecast": has_noaa_forecast} + app = tornado.web.Application([ # Routes for API calls (r"/api/v1/spots", APISpotsHandler, {"spots": self._spots, "web_server_metrics": self.web_server_metrics}), @@ -74,20 +81,15 @@ class WebServer: (r"/api/v1/lookup/grid", APILookupGridHandler, {"web_server_metrics": self.web_server_metrics}), (r"/api/v1/spot", APISpotHandler, {"spots": self._spots, "web_server_metrics": self.web_server_metrics}), # Routes for templated pages - (r"/", PageTemplateHandler, {"template_name": "spots", "web_server_metrics": self.web_server_metrics}), - (r"/map", PageTemplateHandler, {"template_name": "map", "web_server_metrics": self.web_server_metrics}), - (r"/bands", PageTemplateHandler, {"template_name": "bands", "web_server_metrics": self.web_server_metrics}), - (r"/alerts", PageTemplateHandler, - {"template_name": "alerts", "web_server_metrics": self.web_server_metrics}), - (r"/add-spot", PageTemplateHandler, - {"template_name": "add_spot", "web_server_metrics": self.web_server_metrics}), - (r"/conditions", PageTemplateHandler, - {"template_name": "conditions", "web_server_metrics": self.web_server_metrics}), - (r"/status", PageTemplateHandler, - {"template_name": "status", "web_server_metrics": self.web_server_metrics}), - (r"/about", PageTemplateHandler, {"template_name": "about", "web_server_metrics": self.web_server_metrics}), - (r"/apidocs", PageTemplateHandler, - {"template_name": "apidocs", "web_server_metrics": self.web_server_metrics}), + (r"/", PageTemplateHandler, {"template_name": "spots", **page_opts}), + (r"/map", PageTemplateHandler, {"template_name": "map", **page_opts}), + (r"/bands", PageTemplateHandler, {"template_name": "bands", **page_opts}), + (r"/alerts", PageTemplateHandler, {"template_name": "alerts", **page_opts}), + (r"/add-spot", PageTemplateHandler, {"template_name": "add_spot", **page_opts}), + (r"/conditions", PageTemplateHandler, {"template_name": "conditions", **page_opts}), + (r"/status", PageTemplateHandler, {"template_name": "status", **page_opts}), + (r"/about", PageTemplateHandler, {"template_name": "about", **page_opts}), + (r"/apidocs", PageTemplateHandler, {"template_name": "apidocs", **page_opts}), # Route for Prometheus metrics (r"/metrics", PrometheusMetricsHandler), # Default route to serve from "webassets" diff --git a/spothole.py b/spothole.py index 8a2fe1f..4e917ce 100644 --- a/spothole.py +++ b/spothole.py @@ -97,7 +97,8 @@ if __name__ == '__main__': lookup_helper.start() # Set up web server - web_server = WebServer(spots=spots, alerts=alerts, solar_conditions=solar_conditions, status_data=status_data, port=WEB_SERVER_PORT) + web_server = WebServer(spots=spots, alerts=alerts, solar_conditions=solar_conditions, status_data=status_data, + solar_condition_providers=solar_condition_providers, port=WEB_SERVER_PORT) # Fetch, set up and start spot providers for entry in config["spot-providers"]: diff --git a/templates/about.html b/templates/about.html index 6e89918..ed34c2c 100644 --- a/templates/about.html +++ b/templates/about.html @@ -67,7 +67,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 90c6ff8..77ab339 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 0782e4b..020d48d 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 62be938..f3882a9 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 091f2fc..1761767 100644 --- a/templates/base.html +++ b/templates/base.html @@ -47,10 +47,10 @@ - - - - + + + + @@ -72,7 +72,9 @@ {% if allow_spotting %} {% end %} + {% if has_hamqsl or has_noaa_forecast %} + {% end %} diff --git a/templates/conditions.html b/templates/conditions.html index ef08d66..ad7a7f2 100644 --- a/templates/conditions.html +++ b/templates/conditions.html @@ -1,6 +1,7 @@ {% extends "base.html" %} {% block content %} +{% if has_hamqsl %}
Propagation Conditions @@ -129,7 +130,9 @@
Data from HamQSL.com.
+{% end %} +{% if has_noaa_forecast %}
Forecast @@ -166,6 +169,7 @@
+{% end %}
@@ -223,8 +227,8 @@
- - + + diff --git a/templates/map.html b/templates/map.html index 49737a2..8476368 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 63e1574..2250615 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 d37c08a..997c997 100644 --- a/templates/status.html +++ b/templates/status.html @@ -59,8 +59,8 @@ - - + + diff --git a/webassets/js/conditions.js b/webassets/js/conditions.js index eecd1bc..99e1072 100644 --- a/webassets/js/conditions.js +++ b/webassets/js/conditions.js @@ -84,7 +84,7 @@ function loadSolarConditions() { const kIndex = jsonData.k_index; if (kIndex !== null && kIndex !== undefined) { applySwClass('sw-geomag-vals', 'sw-geomag-desc', - kIndex < 5 ? 'bg-success-subtle' : kIndex < 7 ? 'bg-warning-subtle' : 'bg-danger-subtle'); + kIndex < 5 ? 'bg-success-subtle' : kIndex < 6 ? 'bg-warning-subtle' : 'bg-danger-subtle'); } const xRay = jsonData.x_ray; @@ -142,7 +142,7 @@ function renderKIndexForecast(data) { const withAlpha = hex => tinycolor(hex).setAlpha(0.8).toRgbString(); const colors = entries.map(e => e.kp < 4.5 ? withAlpha(style.getPropertyValue('--bs-success').trim()) - : e.kp < 6.5 ? withAlpha(style.getPropertyValue('--bs-warning').trim()) + : e.kp < 5.5 ? withAlpha(style.getPropertyValue('--bs-warning').trim()) : withAlpha(style.getPropertyValue('--bs-danger').trim()) ); const textColor = style.getPropertyValue('--bs-body-color').trim() || '#666'; @@ -225,6 +225,7 @@ function renderKIndexForecast(data) { datasets: [{ data: entries.map(e => e.kp), backgroundColor: colors, + hoverBackgroundColor: colors, borderWidth: 0, }] },