mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2025-12-15 16:43:38 +00:00
Improve add spot page warning and server-side validation. #71
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import json
|
||||
import logging
|
||||
import re
|
||||
from datetime import datetime, timedelta
|
||||
from threading import Thread
|
||||
|
||||
@@ -8,7 +9,8 @@ import pytz
|
||||
from bottle import run, request, response, template
|
||||
|
||||
from core.config import MAX_SPOT_AGE, ALLOW_SPOTTING
|
||||
from core.constants import BANDS, ALL_MODES, MODE_TYPES, SIGS, CONTINENTS, SOFTWARE_VERSION
|
||||
from core.constants import BANDS, ALL_MODES, MODE_TYPES, SIGS, CONTINENTS, SOFTWARE_VERSION, UNKNOWN_BAND
|
||||
from core.lookup_helper import lookup_helper
|
||||
from core.prometheus_metrics_handler import page_requests_counter, get_metrics, api_requests_counter
|
||||
from data.spot import Spot
|
||||
|
||||
@@ -138,13 +140,31 @@ class WebServer:
|
||||
json_spot = json.loads(post_data)
|
||||
spot = Spot(**json_spot)
|
||||
|
||||
# Reject if no timestamp or dx_call
|
||||
if not spot.time or not spot.dx_call:
|
||||
# Reject if no timestamp, frequency, dx_call or de_call
|
||||
if not spot.time or not spot.dx_call or not spot.freq or not spot.de_call:
|
||||
response.content_type = 'application/json'
|
||||
response.status = 422
|
||||
return json.dumps("Error - 'time' and 'dx_call' must be provided as a minimum.",
|
||||
return json.dumps("Error - 'time', 'dx_call', 'freq' and 'de_call' must be provided as a minimum.",
|
||||
default=serialize_everything)
|
||||
|
||||
# Reject invalid-looking callsigns
|
||||
if not re.match(r"^[A-Za-z0-9/\-]*$", spot.dx_call):
|
||||
response.content_type = 'application/json'
|
||||
response.status = 422
|
||||
return json.dumps("Error - '" + spot.dx_call + "' does not look like a valid callsign.",
|
||||
default=serialize_everything)
|
||||
if not re.match(r"^[A-Za-z0-9/\-]*$", spot.de_call):
|
||||
response.content_type = 'application/json'
|
||||
response.status = 422
|
||||
return json.dumps("Error - '" + spot.de_call + "' does not look like a valid callsign.",
|
||||
default=serialize_everything)
|
||||
|
||||
# Reject if frequency not in a known band
|
||||
if lookup_helper.infer_band_from_freq(spot.freq) == UNKNOWN_BAND:
|
||||
response.content_type = 'application/json'
|
||||
response.status = 422
|
||||
return json.dumps("Error - Frequency of " + str(spot.freq / 1000.0) + "kHz is not in a known band.", default=serialize_everything)
|
||||
|
||||
# infer missing data, and add it to our database.
|
||||
spot.source = "API"
|
||||
spot.icon = "desktop"
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
% rebase('webpage_base.tpl')
|
||||
|
||||
<div class="alert alert-warning fade show mb-0 mt-4" role="alert">
|
||||
Please note that spots added to Spothole are not currently sent "upstream" to DX clusters or xOTA spotting sites.
|
||||
<div id="add-spot-intro-box" class="permanently-dismissible-box mt-3">
|
||||
<div class="alert alert-primary alert-dismissible fade show" role="alert">
|
||||
<i class="fa-solid fa-circle-info"></i> <strong>Adding spots to Spothole</strong><br/>This page is implemented as a proof of concept for adding spots to the Spothole system. Currently, spots added in this way are only visible within Spothole and are not sent "upstream" to DX clusters or xOTA spotting sites. The functionality might be extended to include this in future if there is demand for it. If you'd like this to be added, please give a thumbs-up on <a href="https://git.ianrenton.com/ian/spothole/issues/70" target="_new" class="alert-link">issue #70</a> or get in touch via email.
|
||||
<button type="button" id="add-spot-intro-box-dismiss" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-3">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
% rebase('webpage_base.tpl')
|
||||
|
||||
<div id="intro-box" class="mt-3">
|
||||
<div id="intro-box" class="permanently-dismissible-box mt-3">
|
||||
<div class="alert alert-primary alert-dismissible fade show" role="alert">
|
||||
<i class="fa-solid fa-circle-info"></i> <strong>What is Spothole?</strong><br/>Spothole is an aggregator of amateur radio spots from DX clusters and outdoor activity programmes. It's free for anyone to use and includes an API that developers can build other applications on. For more information, check out the <a href="/about" class="alert-link">"About" page</a>. If that sounds like nonsense to you, you can visit <a href="/about#faq" class="alert-link">the FAQ section</a> to learn more.
|
||||
<button type="button" id="intro-box-dismiss" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||||
|
||||
@@ -493,7 +493,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/v1/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 may 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
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
/* INTRO/WARNING BOXES */
|
||||
|
||||
#intro-box {
|
||||
.permanently-dismissible-box {
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ function addSpot() {
|
||||
}, 1000);
|
||||
},
|
||||
error: function (result) {
|
||||
showAddSpotError(result.responseText);
|
||||
showAddSpotError(result.responseText.slice(1,-1));
|
||||
}
|
||||
});
|
||||
} catch (error) {
|
||||
@@ -73,8 +73,20 @@ $("#mode").change(function () {
|
||||
$(this).val($(this).val().trim().toUpperCase());
|
||||
});
|
||||
|
||||
// Display the intro box, unless the user has already dismissed it once.
|
||||
function displayIntroBox() {
|
||||
if (localStorage.getItem("add-spot-intro-box-dismissed") == null) {
|
||||
$("#add-spot-intro-box").show();
|
||||
}
|
||||
$("#add-spot-intro-box-dismiss").click(function() {
|
||||
localStorage.setItem("add-spot-intro-box-dismissed", true);
|
||||
});
|
||||
}
|
||||
|
||||
// Startup
|
||||
$(document).ready(function() {
|
||||
// Load settings from settings storage
|
||||
loadSettings();
|
||||
// Display intro box
|
||||
displayIntroBox();
|
||||
});
|
||||
Reference in New Issue
Block a user