From 277743dac7ce40672bf01d1b6ff522a3e72ab7c5 Mon Sep 17 00:00:00 2001 From: Ian Renton Date: Thu, 9 Oct 2025 15:35:29 +0100 Subject: [PATCH] Version API and add spot_allowed to options call. Closes #35 --- server/webserver.py | 14 +++++++------- webassets/apidocs/openapi.yml | 12 ++++++++---- webassets/js/alerts.js | 4 ++-- webassets/js/spots.js | 4 ++-- webassets/js/status.js | 2 +- 5 files changed, 20 insertions(+), 16 deletions(-) diff --git a/server/webserver.py b/server/webserver.py index c022819..97ee13c 100644 --- a/server/webserver.py +++ b/server/webserver.py @@ -29,11 +29,11 @@ class WebServer: self.status = "Starting" # Routes for API calls - bottle.get("/api/spots")(lambda: self.serve_api(self.get_spot_list_with_filters())) - bottle.get("/api/alerts")(lambda: self.serve_api(self.get_alert_list_with_filters())) - bottle.get("/api/options")(lambda: self.serve_api(self.get_options())) - bottle.get("/api/status")(lambda: self.serve_api(self.status_data)) - bottle.post("/api/spot")(lambda: self.accept_spot()) + bottle.get("/api/v1/spots")(lambda: self.serve_api(self.get_spot_list_with_filters())) + bottle.get("/api/v1/alerts")(lambda: self.serve_api(self.get_alert_list_with_filters())) + bottle.get("/api/v1/options")(lambda: self.serve_api(self.get_options())) + bottle.get("/api/v1/status")(lambda: self.serve_api(self.status_data)) + bottle.post("/api/v1/spot")(lambda: self.accept_spot()) # Routes for templated pages bottle.get("/")(lambda: self.serve_template('webpage_spots')) bottle.get("/alerts")(lambda: self.serve_template('webpage_alerts')) @@ -103,7 +103,6 @@ class WebServer: spot.icon = "desktop" spot.infer_missing() self.spots.add(spot.id, spot, expire=MAX_SPOT_AGE) - print(spot) response.content_type = 'application/json' response.set_header('Cache-Control', 'no-store') @@ -238,7 +237,8 @@ class WebServer: "alert_sources": list( map(lambda p: p["name"], filter(lambda p: p["enabled"], self.status_data["alert_providers"]))), "continents": CONTINENTS, - "max_spot_age": MAX_SPOT_AGE} + "max_spot_age": MAX_SPOT_AGE, + "spot_allowed": ALLOW_SPOTTING} # If spotting to this server is enabled, "API" is another valid spot source even though it does not come from # one of our proviers. if ALLOW_SPOTTING: diff --git a/webassets/apidocs/openapi.yml b/webassets/apidocs/openapi.yml index 99d396c..6de802d 100644 --- a/webassets/apidocs/openapi.yml +++ b/webassets/apidocs/openapi.yml @@ -10,9 +10,9 @@ info: license: name: The Unlicense url: https://unlicense.org/#the-unlicense - version: 0.1 + version: 1 servers: - - url: https://spothole.app/api + - url: https://spothole.app/api/v1 paths: /spots: get: @@ -389,8 +389,12 @@ paths: example: "EU" max_spot_age: type: integer - description: The maximum age, in seconds, of any spot before it will be deleted by the system. When querying the /api/spots endpoint and providing a "max_age" or "since" parameter, there is no point providing a number larger than this, because the system drops all spots older than this. + description: The maximum age, in seconds, of any spot before it will be deleted by the system. When querying the /api/v1/spots endpoint and providing a "max_age" or "since" parameter, there is no point providing a number larger than this, because the system drops all spots older than this. example: 3600 + spot_allowed: + type: boolean + description: Whether the POST /spot call, to add spots to the server directly via its API, is permitted on this server. + example: true /spot: @@ -398,7 +402,7 @@ paths: tags: - spots summary: Add a spot - description: "Supply a new spot object, which will be added to the system. Currently, this will not be reported up the chain to a cluster, POTA, SOTA etc. This will be introduced in a future version. cURL example: `curl --request POST --header \"Content-Type: application/json\" --data '{\"dx_call\":\"M0TRT\",\"time\":1760019539, \"freq\":14200000, \"comment\":\"Test spot please ignore\", \"de_call\":\"M0TRT\"}' https://spothole.app/api/spot`" + description: "Supply a new spot object, which will be added to the system. Currently, this will not be reported up the chain to a cluster, POTA, SOTA etc. This will be introduced in a future version. cURL example: `curl --request POST --header \"Content-Type: application/json\" --data '{\"dx_call\":\"M0TRT\",\"time\":1760019539, \"freq\":14200000, \"comment\":\"Test spot please ignore\", \"de_call\":\"M0TRT\"}' https://spothole.app/api/v1/spot`" operationId: spot requestBody: description: The JSON spot object diff --git a/webassets/js/alerts.js b/webassets/js/alerts.js index 87e99a2..b2eed44 100644 --- a/webassets/js/alerts.js +++ b/webassets/js/alerts.js @@ -6,7 +6,7 @@ var alerts = [] // Load alerts and populate the table. function loadAlerts() { - $.getJSON('/api/alerts' + buildQueryString(), function(jsonData) { + $.getJSON('/api/v1/alerts' + buildQueryString(), function(jsonData) { // Store last updated time lastUpdateTime = moment.utc(); updateRefreshDisplay(); @@ -177,7 +177,7 @@ function addAlertRowsToTable(tbody, alerts) { // Load server options. Once a successful callback is made from this, we then query alerts. function loadOptions() { - $.getJSON('/api/options', function(jsonData) { + $.getJSON('/api/v1/options', function(jsonData) { // Store options options = jsonData; diff --git a/webassets/js/spots.js b/webassets/js/spots.js index 92489c2..659fe04 100644 --- a/webassets/js/spots.js +++ b/webassets/js/spots.js @@ -6,7 +6,7 @@ var spots = [] // Load spots and populate the table. function loadSpots() { - $.getJSON('/api/spots' + buildQueryString(), function(jsonData) { + $.getJSON('/api/v1/spots' + buildQueryString(), function(jsonData) { // Store last updated time lastUpdateTime = moment.utc(); updateRefreshDisplay(); @@ -155,7 +155,7 @@ function updateTable() { // Load server options. Once a successful callback is made from this, we then query spots and set up the timer to query // spots repeatedly. function loadOptions() { - $.getJSON('/api/options', function(jsonData) { + $.getJSON('/api/v1/options', function(jsonData) { // Store options options = jsonData; diff --git a/webassets/js/status.js b/webassets/js/status.js index 9b30611..b5d47cf 100644 --- a/webassets/js/status.js +++ b/webassets/js/status.js @@ -1,6 +1,6 @@ // Load server status function loadStatus() { - $.getJSON('/api/status', function(jsonData) { + $.getJSON('/api/v1/status', function(jsonData) { $("#status-container").empty(); $("#status-container").append(generateStatusCard("Server Information", [ `Software Version: ${jsonData["software-version"]}`,