diff --git a/providers/callsigndata/hamqth.py b/providers/callsigndata/hamqth.py index 56a7821..0f62e39 100644 --- a/providers/callsigndata/hamqth.py +++ b/providers/callsigndata/hamqth.py @@ -1,6 +1,7 @@ import logging import urllib.parse from datetime import datetime, timedelta +from xml.parsers.expat import ExpatError import pytz import xmltodict @@ -60,6 +61,9 @@ class HamQTH(APIQueryCallsignDataProvider): # Log this failure at debug level only, not our problem if user entered the wrong password. logger.debug("HamQTH login details incorrect, failed to look up with HamQTH.") return None + except ExpatError: + logger.warning("HamQTH provided blank or malformed content when trying to authenticate") + return None except Exception: logger.exception("Exception when getting HamQTH session key") return None diff --git a/providers/callsigndata/qrz.py b/providers/callsigndata/qrz.py index 821e0f6..f3134a7 100644 --- a/providers/callsigndata/qrz.py +++ b/providers/callsigndata/qrz.py @@ -1,6 +1,7 @@ import logging import urllib.parse from datetime import datetime, timedelta +from xml.parsers.expat import ExpatError import pytz import xmltodict @@ -56,6 +57,9 @@ class QRZ(APIQueryCallsignDataProvider): # Log this failure at debug level only, not our problem if user entered the wrong password. logger.debug("QRZ.com login details incorrect, failed to look up with QRZ.") return None + except ExpatError: + logger.warning("QRZ.com provided blank or malformed content when trying to authenticate") + return None except Exception: logger.exception("Exception when getting QRZ.com session key") return None diff --git a/templates/add_spot.html b/templates/add_spot.html index 294d7c7..25106fb 100644 --- a/templates/add_spot.html +++ b/templates/add_spot.html @@ -77,7 +77,7 @@ - + diff --git a/templates/alerts.html b/templates/alerts.html index 3009080..0910d8f 100644 --- a/templates/alerts.html +++ b/templates/alerts.html @@ -85,7 +85,7 @@ - + diff --git a/templates/bands.html b/templates/bands.html index 65e5ec0..7a4cec5 100644 --- a/templates/bands.html +++ b/templates/bands.html @@ -76,8 +76,8 @@ - - + + diff --git a/templates/base.html b/templates/base.html index 42b53cb..7d6b222 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,6 +1,6 @@ {% extends "skeleton.html" %} {% block head_extra %} - + @@ -16,10 +16,10 @@ window.fetchEventSource = fetchEventSource; - - - - + + + + {% end %} {% block body %}
Spothole is a utility to aggregate "spots" from amateur radio DX clusters and xOTA spotting sites, and provide an + open JSON API as well as a website to browse the data.
+While there are several other web-based interfaces to DX clusters, and sites that aggregate spots from various + outdoor activity programmes for amateur radio, Spothole differentiates itself by supporting a larger number of + data sources, and by being "API first" rather than just providing a web front-end. This allows other software to + be built on top of it.
+The API is deliberately well-defined with an OpenAPI specification and API documentation. The API delivers spots in a consistent format regardless of the data + source, freeing developers from needing to know how each individual data source presents its data.
+Spothole itself is also open source, Public Domain licenced code that anyone can take and modify. The source code is here.
+The software was written by Ian Renton, MØTRT with code contributions by + Steven, M1SDH. The full list of thanks due to others can be found at the bottom of this page.
+This server is running Spothole version {{software_version}}.
+ +{% end %} diff --git a/templates/help/accuracy.html b/templates/help/accuracy.html new file mode 100644 index 0000000..611f797 --- /dev/null +++ b/templates/help/accuracy.html @@ -0,0 +1,17 @@ +{% extends "help_page.html" %} +{% block help_content %} + +Please note that the data coming out of Spothole is only as good as the data going in. People mis-hear and make + typos when spotting callsigns all the time. There are also plenty of cases where Spothole's data, particularly + location data, may be inaccurate. For example, there are POTA parks that span multiple US states, countries that + span multiple CQ zones, portable operators with no requirement to sign /P, etc. If you are doing something where + accuracy is important, such as contesting, you should not rely on Spothole's data to fill in any gaps in your + log.
+In the Spothole user interface, under "Your Data", you can enter your credentials for QRZ.com and/or HamQTH if + you have them. This allows Spothole to augment its data with lookups from these services. See the following + section, Privacy, for details of how these are handled. If you are looking at the map and see lots of spots in + the geographic centre of countries, allowing these lookups will help. For QRZ.com a paid account is required to + look up operator locations.
+ +{% end %} diff --git a/templates/help/faq.html b/templates/help/faq.html new file mode 100644 index 0000000..6ae62bb --- /dev/null +++ b/templates/help/faq.html @@ -0,0 +1,123 @@ +{% extends "help_page.html" %} +{% block help_content %} + +This is a tool for amateur ("ham") radio users. Many amateur radio operators like to make contacts with others + who are doing something more interesting than sitting in their home "shack", such as people in rarely-seen + countries, remote islands, or on mountaintops. Such operators are often "spotted", i.e. when someone speaks to + them, they will put the details such as their operating frequency into an online system, to let others know + where to find them. A DX Cluster is one type of those systems. Most outdoor radio awards programmes, such as + "Parks on the Air" (POTA) have their own websites for posting spots.
+Spothole is an "aggregator" for those spots, so it checks lots of different services for data, and brings it all + together in one place. So no matter what kinds of interesting spots you are looking for, you can find them + here.
+As well as spots, it also provides a similar feed of "alerts". This is where amateur radio users who are going to + interesting places soon will announce their intentions.
+In amateur radio terminology, the "DX" contact is the "interesting" one that is using the frequency shown and + looking for callers. They might be on a remote island or just in a local park, but either way it's interesting + enough that someone has "spotted" them. The callsign listed under "DE" is the person who entered the spot of the + "DX" operator. "Modes" are the type of communication they are using. For example you might see "CW" which is + Morse Code, or voice "modes" like SSB or FM, or more exotic "data" modes which are used for computer-to-computer + communication.
+Spothole can retrieve spots from: Telnet-based DX clusters, the + Reverse Beacon Network (RBN), the APRS Internet Service (APRS-IS), POTA, + SOTA, WWFF, GMA, WWBOTA, HEMA, Parks 'n' Peaks, ZLOTA, WOTA, LLOTA, WWTOTA, Tiles on the Air, the UK + Packet Repeater Network, and any site based on the xOTA + software by nischu.
+Spothole can retrieve alerts from: NG3K, POTA, + SOTA, WWFF, Parks 'n' Peaks, WOTA and + BOTA. It also fetches contest dates from + WA7BNM Contest Calendar and RSGB contest calendars.
+Spothole can retrieve solar and propagation condition data from HamQSL, the + NOAA Space Weather Prediction Center, the Lowell GIRO Data Center and prop.kc2g.com + by KC2G.
+Spothole can also perform lookups for callsign data on behalf of the user from QRZ.com and HamQTH.
+Note that the server owner has not necessarily enabled all these data sources. In particular it is common to + disable RBN, to avoid the server being swamped with FT8 traffic, and to disable APRS-IS and UK Packet Net so + that the server only displays stations where there is likely to be an operator physically present for a QSO.
+Between the various data sources, the following activities / special interest groups are supported: Contests, + DXpeditions, Aeronautical Mobile, Maritime Mobile, EME/Moonbounce, Amateur Satellite, QRP, Parks on the Air + (POTA), Summits on the Air (SOTA), Worldwide Flora & Fauna (WWFF), Global Mountain Activity (GMA), Worldwide + Bunkers on the Air (WWBOTA), HuMPs Excluding Marilyns Award (HEMA), Islands on the Air (IOTA), Mills on the Air + (MOTA), the Amateur Radio Lighthouse Society (ARLHS), International Lighthouse Lightship Weekend (ILLW), Silos + on the Air (SIOTA), World Castles Award (WCA), New Zealand on the Air (ZLOTA), Keith Roget Memorial National + Parks Award (KRMNPA), South Australia National Parks and Conservation Parks Award (SANPCPA), Wainwrights on the + Air (WOTA), Beaches on the Air (BOTA), Lagos y Lagunas On the Air (LLOTA), Towers on the Air, Tiles on + the Air, Worked All Britain (WAB), Worked All Ireland (WAI), Diploma Municipios de España (DME), Diploma + Faros de España (FEA), Diploma Muesos de España (DMUE), Diploma Castillos de España (DCE), Diploma Monumentos y + Vestigios de España (DMVE), Diploma Estaciones de Ferrocarril de España (DEFE), Diploma Teatri Musei e Belle + Arti (DTMBA), British Inland Waterways on the Air (BIWOTA), Castles on the Air (COTA), Polish Gmina Award (PGA), + Diplôme des Moulins de France (DMF), RaDAR Rally, and Toilets on the Air.
+As of the time of writing in August 2026, I think Spothole captures most radio programmes that have a + defined, downloadable reference list, and almost certainly those that have a spotting/alerting API. If you know + of one I've missed, please let me know!
+Mostly, but not quite. While POTA spots generally come from the POTA source and so on, there are a few + exceptions:
+Spothole's web interface exists not just for the end user, but also as a reference implementation for the API, so + I have chosen to demonstrate both methods of filtering.
+It's probably not? But it's nice to have choice.
+I think it's got three key advantages over those sites:
+Spothole is a Progressive Web App, which means you can install it on an Android or iOS device by opening the site + in Chrome or Safari respectively, and clicking "Install" on the pop-up panel. It'll only prompt you once, so if + you dismiss the prompt and change your mind, you'll find an Install / Add to Home Screen option on your + browser's menu.
+Installing Spothole on your phone is completely optional, the website works exactly the same way as the "app" + does.
+To avoid putting too much load on the various servers that Spothole connects to, the Spothole server only polls + them once every two minutes for spots, and once every 30 minutes for alerts. (Some sources, such as DX clusters, + RBN, APRS-IS and WWBOTA use a non-polling mechanism, and their updates will therefore arrive more quickly.) Then + if you are using the web interface, that has its own rate at which it fetches the data from Spothole. This is + instant for the main spots list, with new spots appearing immediately at the top of the list, while the map and + bands displays update once a minute, and the alerts display updates once every 5 minutes. So you could be + waiting around three minutes to see a newly added spot, or 40 minutes to see a newly added alert.
+Spothole's source code is licenced under the Public Domain. You can write a Spothole client, run your own server, + modify it however you like, you can claim you wrote it and charge people £1000 for a copy, I don't really mind. + (Please don't do the last one. But if you're using my code for something cool, it would be nice to hear from + you!)
+Currently, exit, and nothing else. Support for some DXSpider-like commands may be added to Spothole
+ in due course, but at the moment if you want to add Spothole as a telnet cluster data source to your desktop
+ logging application, that application must handle filtering itself.
Spothole collects no data about you on a permanent basis. All spots and alerts are "timed out" and deleted from + the system after a set interval, which by default is one hour for spots and one week for alerts.
+Settings you select from Spothole's menus are sent to the server, in order to provide the data with the requested + filters. They are also stored in your browser's local storage, so that your preferences are remembered between + sessions.
+The data you provide can optionally include your login credentials for QRZ.com and HamQTH. You can provide these + in the "Your Data" menu of most pages. If you do, Spothole will augment the data it produces with lookups from + these + services, which can for example provide more accurate markers on the map tab, and operator names when you mouse + over a DX callsign. Spothole will still work fine if you don't provide these. The values you enter are sent to + Spothole via HTTPS so are protected in transit, though of course you do have to trust Spothole with this + sensitive data in order to use this feature.
+Any data you send as part of a query, such as your QRZ or HamQTH credentials, is used only for the lifetime of + that + query and is not saved anywhere apart from your own device.
+Spothole uses no trackers, no ads, and no cookies.
+ {% if len(web_ui_options["support_button_html"]) > 0 %} +Caveat: The owner of this server has chosen to inject their own content into the "spots" page. + This is designed for a "donate" or "support this server" button. The functionality of this injected content is + the responsibility of the server owner, rather than the Spothole software.
+ {% end %} +Spothole is open source, so you can audit the code if you + like.
+ +{% end %} diff --git a/templates/help/thanks.html b/templates/help/thanks.html new file mode 100644 index 0000000..e3c26e6 --- /dev/null +++ b/templates/help/thanks.html @@ -0,0 +1,22 @@ +{% extends "help_page.html" %} +{% block help_content %} + +This project would not have been possible without those volunteers who have taken it upon themselves to run DX + clusters, xOTA programmes, DXpedition lists, callsign lookup databases, solar conditions and propagation + modelling software, and other online tools on which Spothole's data is based. The vast majority of these are not + profit-seeking and are made purely for the love of the hobby and to help others in the community. Spothole is + standing on the shoulders of giants, who deserve a huge amount of thanks for all the work they put in.
+The following people have specifically helped develop Spothole either by contributing code, requesting features, + or helping squash bugs: Steven M1SDH, Dan S50U, Matt W1CDN, Norby LX1NO, Andrew VK3ARR, Mario DL4MFM, Mark M5TEA, + Michael G7VJR, Rob G7LAS, Ed DD5LP, Raph F4LUB, Luc ON7KEC, Richard GD4OFB, Daniel PY2TDB, Alan VK1AO, + Andrew WK1AD, Ullrich DF5WC, Wayne N3CDF, Jonathan G4IVV, Erik N2EPE, Sorin YO9TSN, Matt HB9HWI, Priit ES1TEB, + Leigh KG7WED, Jouni OH3CUF, Onno VK6FLAB, and Bruce WA7BNM. (If I've forgotten you, let me know!)
+Spothole is also dependent on a number of Python libraries, such as pyhamtools, and many JavaScript + libraries, as well as the Font Awesome icon set and flag icons from the Noto Color Emoji set, and MIT-licenced + GeoJSON files for CQ and ITU zones from HA8TKS.
+The project's name was suggested by Harm DK4HAA.
+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 %} diff --git a/templates/help/using.html b/templates/help/using.html new file mode 100644 index 0000000..294c260 --- /dev/null +++ b/templates/help/using.html @@ -0,0 +1,44 @@ +{% extends "help_page.html" %} +{% block help_content %} + +There are a number of different ways to use Spothole, depending on what you want to do with it and your level of + technical skill:
+{{ telnet_server_address }} and port {{ telnet_server_port }}. You can also access
+ it from a terminal with telnet {{ telnet_server_address }} {{ telnet_server_port }}.
+