mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2025-12-15 08:33:38 +00:00
Add Spot page to allow sig and sig_ref entries. Closes #71
This commit is contained in:
@@ -24,11 +24,11 @@ SIGS = [
|
||||
SIG(name="SIOTA", description="Silos on the Air", icon="wheat-awn", ref_regex=r"[A-Z]{2}\-[A-Z]{3}\d"),
|
||||
SIG(name="WCA", description="World Castles Award", icon="chess-rook", ref_regex=r"[A-Z0-9]{1,3}\-\d+"),
|
||||
SIG(name="ZLOTA", description="New Zealand on the Air", icon="kiwi-bird", ref_regex=r"ZL[A-Z]/[A-Z]{2}\-\d+"),
|
||||
SIG(name="WOTA", description="Wainwrights on the Air", icon="w", ref_regex=r"[A-Z]{3}-[0-9]{2}"),
|
||||
SIG(name="BOTA", description="Beaches on the Air", icon="water"),
|
||||
SIG(name="KRMNPA", description="Keith Roget Memorial National Parks Award", icon="earth-oceania", ref_regex=r""),
|
||||
SIG(name="WAB", description="Worked All Britain", icon="table-cells-large", ref_regex=r"[A-Z]{1,2}[0-9]{2}"),
|
||||
SIG(name="WAI", description="Worked All Ireland", icon="table-cells-large", ref_regex=r"[A-Z][0-9]{2}"),
|
||||
SIG(name="WOTA", description="Wainwrights on the Air", icon="w", ref_regex=r"[A-Z]{3}-[0-9]{2}"),
|
||||
SIG(name="BOTA", description="Beaches on the Air", icon="water")
|
||||
SIG(name="WAI", description="Worked All Ireland", icon="table-cells-large", ref_regex=r"[A-Z][0-9]{2}")
|
||||
]
|
||||
|
||||
# Modes. Note "DIGI" and "DIGITAL" are also supported but are normalised into "DATA".
|
||||
|
||||
@@ -12,6 +12,8 @@ from core.config import MAX_SPOT_AGE, ALLOW_SPOTTING
|
||||
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 core.sig_utils import get_ref_regex_for_sig
|
||||
from data.sig_ref import SIGRef
|
||||
from data.spot import Spot
|
||||
|
||||
|
||||
@@ -140,6 +142,14 @@ class WebServer:
|
||||
json_spot = json.loads(post_data)
|
||||
spot = Spot(**json_spot)
|
||||
|
||||
# Converting to a spot object this way won't have coped with sig_ref objects, so fix that. (Would be nice to
|
||||
# redo this in a functional style)
|
||||
if spot.sig_refs:
|
||||
real_sig_refs = []
|
||||
for dict_obj in spot.sig_refs:
|
||||
real_sig_refs.append(json.loads(json.dumps(dict_obj), object_hook=lambda d: SIGRef(**d)))
|
||||
spot.sig_refs = real_sig_refs
|
||||
|
||||
# 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'
|
||||
@@ -171,6 +181,13 @@ class WebServer:
|
||||
response.status = 422
|
||||
return json.dumps("Error - '" + spot.dx_grid + "' does not look like a valid Maidenhead grid.", default=serialize_everything)
|
||||
|
||||
# Reject if sig_ref format incorrect for sig
|
||||
print(spot.sig_refs[0])
|
||||
if spot.sig and spot.sig_refs and len(spot.sig_refs) > 0 and spot.sig_refs[0].id and get_ref_regex_for_sig(spot.sig) and not re.match(get_ref_regex_for_sig(spot.sig), spot.sig_refs[0].id):
|
||||
response.content_type = 'application/json'
|
||||
response.status = 422
|
||||
return json.dumps("Error - '" + spot.sig_refs[0].id + "' does not look like a valid reference for " + spot.sig + ".", default=serialize_everything)
|
||||
|
||||
# infer missing data, and add it to our database.
|
||||
spot.source = "API"
|
||||
if not spot.sig:
|
||||
|
||||
@@ -24,21 +24,31 @@
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label for="freq" class="form-label">Frequency (kHz) *</label>
|
||||
<input type="text" class="form-control" id="freq" placeholder="14100" style="max-width: 8em;">
|
||||
<input type="text" class="form-control" id="freq" placeholder="e.g. 14100" style="max-width: 8em;">
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label for="mode" class="form-label">Mode</label>
|
||||
<select id="mode" class="storeable-select form-select" style="max-width: 6em;">
|
||||
<select id="mode" class="form-select">
|
||||
<option value="" selected></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label for="sig" class="form-label">SIG</label>
|
||||
<select id="sig" class="form-select">
|
||||
<option value="" selected></option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label for="sig-ref" class="form-label">SIG Reference</label>
|
||||
<input type="text" class="form-control" id="sig-ref" placeholder="e.g. GB-0001" style="max-width: 8em;">
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label for="dx-grid" class="form-label">DX Grid</label>
|
||||
<input type="text" class="form-control" id="dx-grid" placeholder="AA00aa" style="max-width: 8em;">
|
||||
<input type="text" class="form-control" id="dx-grid" placeholder="e.g. AA00aa" style="max-width: 8em;">
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label for="comment" class="form-label">Comment</label>
|
||||
<input type="text" class="form-control" id="comment" placeholder="59 TNX QSO 73" style="max-width: 12em;">
|
||||
<input type="text" class="form-control" id="comment" placeholder="e.g. 59 TNX QSO 73" style="max-width: 12em;">
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<label for="de-call" class="form-label">Your Call *</label>
|
||||
@@ -46,10 +56,10 @@
|
||||
</div>
|
||||
<div class="col-auto">
|
||||
<button type="button" class="btn btn-primary" style="margin-top: 2em;" onclick="addSpot();">Spot</button>
|
||||
<span id="result-good"></span>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<div id="result-good"></div>
|
||||
<div id="result-bad"></div>
|
||||
|
||||
<p class="small mt-4 mb-1">* Required field</p>
|
||||
|
||||
@@ -13,6 +13,14 @@ function loadOptions() {
|
||||
}));
|
||||
});
|
||||
|
||||
// Populate SIG drop-down
|
||||
$.each(options["sigs"], function (i, sig) {
|
||||
$('#sig').append($('<option>', {
|
||||
value: sig.name,
|
||||
text : sig.name
|
||||
}));
|
||||
});
|
||||
|
||||
// Load settings from settings storage now all the controls are available
|
||||
loadSettings();
|
||||
});
|
||||
@@ -28,6 +36,8 @@ function addSpot() {
|
||||
var dx = $("#dx-call").val().toUpperCase();
|
||||
var freqStr = $("#freq").val();
|
||||
var mode = $("#mode")[0].value;
|
||||
var sig = $("#sig")[0].value;
|
||||
var sigRef = $("#sig-ref").val();
|
||||
var dxGrid = $("#dx-grid").val();
|
||||
var comment = $("#comment").val();
|
||||
var de = $("#de-call").val().toUpperCase();
|
||||
@@ -48,6 +58,12 @@ function addSpot() {
|
||||
if (mode != "") {
|
||||
spot["mode"] = mode;
|
||||
}
|
||||
if (sig != "") {
|
||||
spot["sig"] = sig;
|
||||
}
|
||||
if (sigRef != "") {
|
||||
spot["sig_refs"] = [{id: sigRef}];
|
||||
}
|
||||
if (dxGrid != "") {
|
||||
spot["dx_grid"] = dxGrid;
|
||||
}
|
||||
@@ -68,7 +84,7 @@ function addSpot() {
|
||||
type : 'POST',
|
||||
timeout: 10000,
|
||||
success: async function (result) {
|
||||
$("#result-good").html("<button type='button' class='btn btn-success' style='margin-top: 2em;'><i class='fa-solid fa-check'></i> OK</button>");
|
||||
$("#result-good").html("<div class='alert alert-success fade show mb-0 mt-4' role='alert'><i class='fa-solid fa-check'></i> Spot submitted. Returning you to the spots list...</div>");
|
||||
$("#result-bad").html("");
|
||||
setTimeout(() => {
|
||||
$("#result-good").hide();
|
||||
|
||||
Reference in New Issue
Block a user