mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2025-10-27 16:59:25 +00:00
Various UI things #7
This commit is contained in:
24
.idea/runConfigurations/Run.xml
generated
Normal file
24
.idea/runConfigurations/Run.xml
generated
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Run" type="PythonConfigurationType" factoryName="Python">
|
||||||
|
<module name="metaspot" />
|
||||||
|
<option name="ENV_FILES" value="" />
|
||||||
|
<option name="INTERPRETER_OPTIONS" value="" />
|
||||||
|
<option name="PARENT_ENVS" value="true" />
|
||||||
|
<envs>
|
||||||
|
<env name="PYTHONUNBUFFERED" value="1" />
|
||||||
|
</envs>
|
||||||
|
<option name="SDK_HOME" value="" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="" />
|
||||||
|
<option name="IS_MODULE_SDK" value="true" />
|
||||||
|
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||||
|
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||||
|
<option name="SCRIPT_NAME" value="$PROJECT_DIR$/main.py" />
|
||||||
|
<option name="PARAMETERS" value="" />
|
||||||
|
<option name="SHOW_COMMAND_LINE" value="false" />
|
||||||
|
<option name="EMULATE_TERMINAL" value="false" />
|
||||||
|
<option name="MODULE_MODE" value="false" />
|
||||||
|
<option name="REDIRECT_INPUT" value="false" />
|
||||||
|
<option name="INPUT_FILE" value="" />
|
||||||
|
<method v="2" />
|
||||||
|
</configuration>
|
||||||
|
</component>
|
||||||
@@ -16,10 +16,12 @@ Supported data sources include DX Clusters, the Reverse Beacon Network (RBN), th
|
|||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
### Installing your own copy
|
### Running your own copy
|
||||||
|
|
||||||
TODO
|
TODO
|
||||||
|
|
||||||
|
The software can take a few seconds to start up, mostly because it is downloading an updated file to match callsigns to countries. This is normal, don't panic!
|
||||||
|
|
||||||
### Writing your own Providers
|
### Writing your own Providers
|
||||||
|
|
||||||
(S)pothole is designed to be easily extensible. If you want to write your own provider, simply add a module to the `providers` package containing your class. (Currently, in order to be loaded correctly, the module (file) name should be the same as the class name, but lower case.)
|
(S)pothole is designed to be easily extensible. If you want to write your own provider, simply add a module to the `providers` package containing your class. (Currently, in order to be loaded correctly, the module (file) name should be the same as the class name, but lower case.)
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ DXCC_FLAGS = {
|
|||||||
3: "\U0001F1E6\U0001F1EB", # AFGHANISTAN
|
3: "\U0001F1E6\U0001F1EB", # AFGHANISTAN
|
||||||
4: "", # AGALEGA & ST BRANDON ISLANDS
|
4: "", # AGALEGA & ST BRANDON ISLANDS
|
||||||
5: "\U0001F1E6\U0001F1FD", # ALAND ISLANDS
|
5: "\U0001F1E6\U0001F1FD", # ALAND ISLANDS
|
||||||
6: "", # ALASKA
|
6: "\U0001F1FA\U0001F1F8", # ALASKA
|
||||||
7: "\U0001F1E6\U0001F1F1", # ALBANIA
|
7: "\U0001F1E6\U0001F1F1", # ALBANIA
|
||||||
8: "", # ALDABRA
|
8: "", # ALDABRA
|
||||||
9: "\U0001F1E6\U0001F1F8", # AMERICAN SAMOA
|
9: "\U0001F1E6\U0001F1F8", # AMERICAN SAMOA
|
||||||
@@ -63,7 +63,7 @@ DXCC_FLAGS = {
|
|||||||
18: "\U0001F1E6\U0001F1FF", # AZERBAIJAN
|
18: "\U0001F1E6\U0001F1FF", # AZERBAIJAN
|
||||||
19: "", # BAJO NUEVO
|
19: "", # BAJO NUEVO
|
||||||
20: "", # BAKER HOWLAND ISLANDS
|
20: "", # BAKER HOWLAND ISLANDS
|
||||||
21: "", # BALEARIC ISLANDS
|
21: "\U0001F1EA\U0001F1F8", # BALEARIC ISLANDS
|
||||||
22: "\U0001F1F5\U0001F1FC", # PALAU
|
22: "\U0001F1F5\U0001F1FC", # PALAU
|
||||||
23: "", # BLENHEIM REEF
|
23: "", # BLENHEIM REEF
|
||||||
24: "\U0001F1E7\U0001F1FB", # BOUVET ISLAND
|
24: "\U0001F1E7\U0001F1FB", # BOUVET ISLAND
|
||||||
@@ -71,10 +71,10 @@ DXCC_FLAGS = {
|
|||||||
26: "", # BRITISH SOMALILAND
|
26: "", # BRITISH SOMALILAND
|
||||||
27: "\U0001F1E7\U0001F1FE", # BELARUS
|
27: "\U0001F1E7\U0001F1FE", # BELARUS
|
||||||
28: "\U0001F1E8\U0001F1FB", # CANAL ZONE
|
28: "\U0001F1E8\U0001F1FB", # CANAL ZONE
|
||||||
29: "", # CANARY ISLANDS
|
29: "\U0001F1EA\U0001F1F8", # CANARY ISLANDS
|
||||||
30: "", # CELEBE & MOLUCCA ISLANDS
|
30: "", # CELEBE & MOLUCCA ISLANDS
|
||||||
31: "\U0001F1F0\U0001F1EE", # CENTRAL KIRIBATI
|
31: "\U0001F1F0\U0001F1EE", # CENTRAL KIRIBATI
|
||||||
32: "", # CEUTA & MELILLA
|
32: "\U0001F1EA\U0001F1F8", # CEUTA & MELILLA
|
||||||
33: "", # CHAGOS ISLANDS
|
33: "", # CHAGOS ISLANDS
|
||||||
34: "", # CHATHAM ISLAND
|
34: "", # CHATHAM ISLAND
|
||||||
35: "\U0001F1E8\U0001F1FD", # CHRISTMAS ISLAND
|
35: "\U0001F1E8\U0001F1FD", # CHRISTMAS ISLAND
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ from core.config import config
|
|||||||
from core.constants import BANDS, UNKNOWN_BAND, CW_MODES, PHONE_MODES, DATA_MODES, ALL_MODES
|
from core.constants import BANDS, UNKNOWN_BAND, CW_MODES, PHONE_MODES, DATA_MODES, ALL_MODES
|
||||||
|
|
||||||
# Lookup helpers from pyhamtools
|
# Lookup helpers from pyhamtools
|
||||||
LOOKUP_LIB_BASIC = LookupLib(lookuptype="countryfile", filename="cty.plist")
|
LOOKUP_LIB_BASIC = LookupLib(lookuptype="countryfile")
|
||||||
CALL_INFO_BASIC = Callinfo(LOOKUP_LIB_BASIC)
|
CALL_INFO_BASIC = Callinfo(LOOKUP_LIB_BASIC)
|
||||||
QRZ_AVAILABLE = config["qrz-password"] != ""
|
QRZ_AVAILABLE = config["qrz-password"] != ""
|
||||||
if QRZ_AVAILABLE:
|
if QRZ_AVAILABLE:
|
||||||
|
|||||||
@@ -12,17 +12,20 @@
|
|||||||
span.flag-wrapper {
|
span.flag-wrapper {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 1.7em;
|
width: 1.7em;
|
||||||
|
text-align: center;
|
||||||
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.icon-wrapper {
|
span.icon-wrapper {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 1.5em;
|
width: 1.5em;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
cursor: default;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.freq-mhz {
|
span.freq-mhz {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
width: 2em;
|
min-width: 1.5em;
|
||||||
text-align: right;
|
text-align: right;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
}
|
}
|
||||||
@@ -35,7 +38,13 @@ span.freq-hz {
|
|||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
span.mode-q {
|
||||||
|
padding-left: 0.5em;
|
||||||
|
font-size: 0.7em;
|
||||||
|
color: lightgray;
|
||||||
|
}
|
||||||
|
|
||||||
tr.table-faded td {
|
tr.table-faded td {
|
||||||
color: gray;
|
color: lightgray;
|
||||||
text-decoration: line-through !important;
|
text-decoration: line-through !important;
|
||||||
}
|
}
|
||||||
@@ -7,6 +7,8 @@ var spots = []
|
|||||||
var options = {};
|
var options = {};
|
||||||
// Last time we updated the spots list on display.
|
// Last time we updated the spots list on display.
|
||||||
var lastUpdateTime;
|
var lastUpdateTime;
|
||||||
|
// Options-based lookups for band colours
|
||||||
|
band_colors = {}
|
||||||
|
|
||||||
// Load spots and populate the table.
|
// Load spots and populate the table.
|
||||||
function loadSpots() {
|
function loadSpots() {
|
||||||
@@ -41,6 +43,12 @@ function updateTable() {
|
|||||||
var time = moment.utc(s["time"], moment.ISO_8601);
|
var time = moment.utc(s["time"], moment.ISO_8601);
|
||||||
var time_formatted = time.format("HH:mm")
|
var time_formatted = time.format("HH:mm")
|
||||||
|
|
||||||
|
// Format dx country
|
||||||
|
var dx_country = s["dx_country"]
|
||||||
|
if (dx_country == null) {
|
||||||
|
dx_country = "Unknown or not a country"
|
||||||
|
}
|
||||||
|
|
||||||
// Format the frequency
|
// Format the frequency
|
||||||
var mhz = Math.floor(s["freq"] / 1000.0);
|
var mhz = Math.floor(s["freq"] / 1000.0);
|
||||||
var khz = Math.floor(s["freq"] - (mhz * 1000.0));
|
var khz = Math.floor(s["freq"] - (mhz * 1000.0));
|
||||||
@@ -48,6 +56,18 @@ function updateTable() {
|
|||||||
var hz_string = (hz > 0) ? hz.toFixed(0) : "";
|
var hz_string = (hz > 0) ? hz.toFixed(0) : "";
|
||||||
var freq_string = `<span class='freq-mhz'>${mhz.toFixed(0)}</span><span class='freq-khz'>${khz.toFixed(0).padStart(3, '0')}</span><span class='freq-hz'>${hz_string}</span>`
|
var freq_string = `<span class='freq-mhz'>${mhz.toFixed(0)}</span><span class='freq-khz'>${khz.toFixed(0).padStart(3, '0')}</span><span class='freq-hz'>${hz_string}</span>`
|
||||||
|
|
||||||
|
// Format the mode
|
||||||
|
mode_string = s["mode"];
|
||||||
|
if (s["mode_source"] == "BANDPLAN") {
|
||||||
|
mode_string = mode_string + "<span class='mode-q'><i class='fa-solid fa-circle-question' title='The mode was not reported via the spotting service. This is a guess based on the frequency.'></i></span>"
|
||||||
|
}
|
||||||
|
|
||||||
|
// Band-based colour
|
||||||
|
var band_dot_style = ""
|
||||||
|
if (band_colors[s["band"]]) {
|
||||||
|
band_dot_style = `color: ${band_colors[s["band"]]}; `
|
||||||
|
}
|
||||||
|
|
||||||
// Format sig_refs
|
// Format sig_refs
|
||||||
var sig_refs = ""
|
var sig_refs = ""
|
||||||
if (s["sig_refs"]) {
|
if (s["sig_refs"]) {
|
||||||
@@ -55,20 +75,26 @@ function updateTable() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Format DE flag
|
// Format DE flag
|
||||||
var de_flag = "<i class='fa-solid fa-question'></i>";
|
var de_flag = "<i class='fa-solid fa-circle-question'></i>";
|
||||||
if (s["de_flag"] && s["de_flag"] != "") {
|
if (s["de_flag"] && s["de_flag"] != "") {
|
||||||
de_flag = s["de_flag"];
|
de_flag = s["de_flag"];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Format de country
|
||||||
|
var de_country = s["de_country"]
|
||||||
|
if (de_country == null) {
|
||||||
|
de_country = "Unknown or not a country"
|
||||||
|
}
|
||||||
|
|
||||||
// Populate the row
|
// Populate the row
|
||||||
$tr.append(`<td>${time_formatted}</td>`);
|
$tr.append(`<td>${time_formatted}</td>`);
|
||||||
$tr.append(`<td><span class='flag-wrapper'>${s["dx_flag"]}</span>${s["dx_call"]}</td>`);
|
$tr.append(`<td><span class='flag-wrapper' title='${dx_country}'>${s["dx_flag"]}</span>${s["dx_call"]}</td>`);
|
||||||
$tr.append(`<td>${freq_string}</td>`);
|
$tr.append(`<td><span class='band-dot' style='${band_dot_style}'>■</span>${freq_string}</td>`);
|
||||||
$tr.append(`<td>${s["mode"]}</td>`);
|
$tr.append(`<td>${mode_string}</td>`);
|
||||||
$tr.append('<td>' + escapeHtml(`${s["comment"]}`) + '</td>');
|
$tr.append('<td>' + escapeHtml(`${s["comment"]}`) + '</td>');
|
||||||
$tr.append(`<td><span class='icon-wrapper'><i class='fa-solid fa-${s["icon"]}'></i></span> ${s["source"]}</td>`);
|
$tr.append(`<td><span class='icon-wrapper'><i class='fa-solid fa-${s["icon"]}'></i></span> ${s["source"]}</td>`);
|
||||||
$tr.append(`<td>${sig_refs}</td>`);
|
$tr.append(`<td>${sig_refs}</td>`);
|
||||||
$tr.append(`<td><span class='flag-wrapper'>${s["de_flag"]}</span>${s["de_call"]}</td>`);
|
$tr.append(`<td><span class='flag-wrapper' title='${de_country}'>${de_flag}</span>${s["de_call"]}</td>`);
|
||||||
table.find('tbody').append($tr);
|
table.find('tbody').append($tr);
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -87,8 +113,15 @@ function loadStatus() {
|
|||||||
// spots repeatedly.
|
// spots repeatedly.
|
||||||
function loadOptions() {
|
function loadOptions() {
|
||||||
$.getJSON('/api/options', function(jsonData) {
|
$.getJSON('/api/options', function(jsonData) {
|
||||||
|
// Store options
|
||||||
options = jsonData;
|
options = jsonData;
|
||||||
console.log(options); //todo remove
|
|
||||||
|
// Separately store colour lookups for bands
|
||||||
|
options["bands"].forEach(m => {
|
||||||
|
band_colors[m["name"]] = m["color"]
|
||||||
|
});
|
||||||
|
|
||||||
|
// Load spots and set up the timer
|
||||||
loadSpots();
|
loadSpots();
|
||||||
setInterval(loadSpots, REFRESH_INTERVAL_SEC * 1000)
|
setInterval(loadSpots, REFRESH_INTERVAL_SEC * 1000)
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user