mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2025-12-15 16:43: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="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="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="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="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="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="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")
|
|
||||||
]
|
]
|
||||||
|
|
||||||
# Modes. Note "DIGI" and "DIGITAL" are also supported but are normalised into "DATA".
|
# 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.constants import BANDS, ALL_MODES, MODE_TYPES, SIGS, CONTINENTS, SOFTWARE_VERSION, UNKNOWN_BAND
|
||||||
from core.lookup_helper import lookup_helper
|
from core.lookup_helper import lookup_helper
|
||||||
from core.prometheus_metrics_handler import page_requests_counter, get_metrics, api_requests_counter
|
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
|
from data.spot import Spot
|
||||||
|
|
||||||
|
|
||||||
@@ -140,6 +142,14 @@ class WebServer:
|
|||||||
json_spot = json.loads(post_data)
|
json_spot = json.loads(post_data)
|
||||||
spot = Spot(**json_spot)
|
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
|
# 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:
|
if not spot.time or not spot.dx_call or not spot.freq or not spot.de_call:
|
||||||
response.content_type = 'application/json'
|
response.content_type = 'application/json'
|
||||||
@@ -171,6 +181,13 @@ class WebServer:
|
|||||||
response.status = 422
|
response.status = 422
|
||||||
return json.dumps("Error - '" + spot.dx_grid + "' does not look like a valid Maidenhead grid.", default=serialize_everything)
|
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.
|
# infer missing data, and add it to our database.
|
||||||
spot.source = "API"
|
spot.source = "API"
|
||||||
if not spot.sig:
|
if not spot.sig:
|
||||||
|
|||||||
@@ -24,21 +24,31 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<label for="freq" class="form-label">Frequency (kHz) *</label>
|
<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>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<label for="mode" class="form-label">Mode</label>
|
<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>
|
<option value="" selected></option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</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">
|
<div class="col-auto">
|
||||||
<label for="dx-grid" class="form-label">DX Grid</label>
|
<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>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<label for="comment" class="form-label">Comment</label>
|
<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>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<label for="de-call" class="form-label">Your Call *</label>
|
<label for="de-call" class="form-label">Your Call *</label>
|
||||||
@@ -46,10 +56,10 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<button type="button" class="btn btn-primary" style="margin-top: 2em;" onclick="addSpot();">Spot</button>
|
<button type="button" class="btn btn-primary" style="margin-top: 2em;" onclick="addSpot();">Spot</button>
|
||||||
<span id="result-good"></span>
|
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
<div id="result-good"></div>
|
||||||
<div id="result-bad"></div>
|
<div id="result-bad"></div>
|
||||||
|
|
||||||
<p class="small mt-4 mb-1">* Required field</p>
|
<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
|
// Load settings from settings storage now all the controls are available
|
||||||
loadSettings();
|
loadSettings();
|
||||||
});
|
});
|
||||||
@@ -28,6 +36,8 @@ function addSpot() {
|
|||||||
var dx = $("#dx-call").val().toUpperCase();
|
var dx = $("#dx-call").val().toUpperCase();
|
||||||
var freqStr = $("#freq").val();
|
var freqStr = $("#freq").val();
|
||||||
var mode = $("#mode")[0].value;
|
var mode = $("#mode")[0].value;
|
||||||
|
var sig = $("#sig")[0].value;
|
||||||
|
var sigRef = $("#sig-ref").val();
|
||||||
var dxGrid = $("#dx-grid").val();
|
var dxGrid = $("#dx-grid").val();
|
||||||
var comment = $("#comment").val();
|
var comment = $("#comment").val();
|
||||||
var de = $("#de-call").val().toUpperCase();
|
var de = $("#de-call").val().toUpperCase();
|
||||||
@@ -48,6 +58,12 @@ function addSpot() {
|
|||||||
if (mode != "") {
|
if (mode != "") {
|
||||||
spot["mode"] = mode;
|
spot["mode"] = mode;
|
||||||
}
|
}
|
||||||
|
if (sig != "") {
|
||||||
|
spot["sig"] = sig;
|
||||||
|
}
|
||||||
|
if (sigRef != "") {
|
||||||
|
spot["sig_refs"] = [{id: sigRef}];
|
||||||
|
}
|
||||||
if (dxGrid != "") {
|
if (dxGrid != "") {
|
||||||
spot["dx_grid"] = dxGrid;
|
spot["dx_grid"] = dxGrid;
|
||||||
}
|
}
|
||||||
@@ -68,7 +84,7 @@ function addSpot() {
|
|||||||
type : 'POST',
|
type : 'POST',
|
||||||
timeout: 10000,
|
timeout: 10000,
|
||||||
success: async function (result) {
|
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("");
|
$("#result-bad").html("");
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
$("#result-good").hide();
|
$("#result-good").hide();
|
||||||
|
|||||||
Reference in New Issue
Block a user