mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2025-10-27 08:49:27 +00:00
Add NG3K DXpedition calendar #17
This commit is contained in:
73
alertproviders/ng3k.py
Normal file
73
alertproviders/ng3k.py
Normal file
@@ -0,0 +1,73 @@
|
||||
from datetime import datetime
|
||||
|
||||
import pytz
|
||||
from rss_parser import RSSParser
|
||||
|
||||
from alertproviders.http_alert_provider import HTTPAlertProvider
|
||||
from data.alert import Alert
|
||||
|
||||
|
||||
# Alert provider NG3K DXpedition list
|
||||
class NG3K(HTTPAlertProvider):
|
||||
POLL_INTERVAL_SEC = 3600
|
||||
ALERTS_URL = "https://www.ng3k.com/adxo.xml"
|
||||
|
||||
def __init__(self, provider_config):
|
||||
super().__init__(provider_config, self.ALERTS_URL, self.POLL_INTERVAL_SEC)
|
||||
|
||||
def http_response_to_alerts(self, http_response):
|
||||
new_alerts = []
|
||||
rss = RSSParser.parse(http_response.content.decode())
|
||||
# Iterate through source data
|
||||
for source_alert in rss.channel.items:
|
||||
# Deal with "the format"...
|
||||
parts = source_alert.description.split(" --\n")
|
||||
|
||||
start_string = parts[0].split("-")[0]
|
||||
end_string = parts[0].split("-")[1]
|
||||
|
||||
end_year = end_string.split(", ")[1].strip()
|
||||
|
||||
if ", " in start_string:
|
||||
start_year = start_string.split(", ")[1].strip()
|
||||
start_mon = start_string.split(", ")[0][0:3].strip()
|
||||
start_day = start_string.split(", ")[0][4:].strip()
|
||||
else:
|
||||
start_year = end_year
|
||||
start_mon = start_string[0:3].strip()
|
||||
start_day = start_string[4:].strip()
|
||||
|
||||
if " " in end_string.split(", ")[0]:
|
||||
end_mon = end_string.split(", ")[0].split(" ")[0].strip()
|
||||
end_day = end_string.split(", ")[0].split(" ")[1].strip()
|
||||
else:
|
||||
end_day = end_string.split(", ")[0].strip()
|
||||
end_mon = start_mon
|
||||
|
||||
start_timestamp = datetime.strptime(start_year + " " + start_mon + " " + start_day, "%Y %b %d").replace(
|
||||
tzinfo=pytz.UTC).timestamp()
|
||||
end_timestamp = datetime.strptime(end_year + " " + end_mon + " " + end_day + " 23:59", "%Y %b %d %H:%M").replace(
|
||||
tzinfo=pytz.UTC).timestamp()
|
||||
|
||||
dx_country = parts[1]
|
||||
dx_call = parts[2]
|
||||
qsl_info = parts[3]
|
||||
extra_parts = parts[5].split("; ")
|
||||
by = extra_parts[0]
|
||||
bands = extra_parts[1]
|
||||
modes = extra_parts[2] if len(extra_parts) > 3 else ""
|
||||
comment = extra_parts[-1]
|
||||
|
||||
# Convert to our alert format
|
||||
alert = Alert(source=self.name,
|
||||
dx_call=dx_call.upper(),
|
||||
dx_country=dx_country,
|
||||
freqs_modes=bands + (("; " + modes) if modes != "" else ""),
|
||||
comment=by + "; " + comment + "; " + qsl_info,
|
||||
icon="globe-africa",
|
||||
start_time=start_timestamp,
|
||||
end_time=end_timestamp)
|
||||
|
||||
# Add to our list.
|
||||
new_alerts.append(alert)
|
||||
return new_alerts
|
||||
@@ -84,6 +84,10 @@ alert-providers:
|
||||
class: "WWFF"
|
||||
name: "WWFF"
|
||||
enabled: true
|
||||
-
|
||||
class: "NG3K"
|
||||
name: "NG3K"
|
||||
enabled: true
|
||||
|
||||
# Port to open the local web server on
|
||||
web-server-port: 8080
|
||||
|
||||
@@ -9,3 +9,4 @@ aprslib~=0.7.2
|
||||
diskcache~=5.6.3
|
||||
psutil~=7.1.0
|
||||
requests-sse~=0.5.2
|
||||
rss-parser~=2.1.1
|
||||
|
||||
@@ -10,7 +10,7 @@ info:
|
||||
license:
|
||||
name: The Unlicense
|
||||
url: https://unlicense.org/#the-unlicense
|
||||
version: 1
|
||||
version: v1
|
||||
servers:
|
||||
- url: https://spothole.app/api/v1
|
||||
paths:
|
||||
|
||||
@@ -27,7 +27,7 @@ function buildQueryString() {
|
||||
});
|
||||
str = str + "limit=" + $("#alerts-to-fetch option:selected").val();
|
||||
var maxDur = $("#max-duration option:selected").val();
|
||||
if (maxDur != "") {
|
||||
if (maxDur != "9999999999") {
|
||||
str = str + "&max_duration=" + maxDur;
|
||||
}
|
||||
return str;
|
||||
@@ -89,7 +89,8 @@ function addAlertRowsToTable(tbody, alerts) {
|
||||
var useLocalTime = $("#useLocalTime")[0].checked;
|
||||
|
||||
// Get times for the alert, and convert to local time if necessary.
|
||||
var start_time = moment.unix(a["start_time"]).utc();
|
||||
var start_time_unix = moment.unix(a["start_time"]);
|
||||
var start_time = start_time_unix.utc();
|
||||
if (useLocalTime) {
|
||||
start_time = start_time.local();
|
||||
}
|
||||
@@ -103,21 +104,27 @@ function addAlertRowsToTable(tbody, alerts) {
|
||||
// different year to the current year, in which case the year is inserted between month and hour.
|
||||
// If the time is set to local not UTC, and the date in local time is "today", we display that instead.
|
||||
// End time is displayed the same as above, except if the end date is the same as the start date, in which case
|
||||
// just e.g. 23:45 is used. Finally, if there is no end date set, "---" is displayed.
|
||||
var start_time_formatted = start_time.format("D MMM HH:mm");
|
||||
// just e.g. 23:45 is used.
|
||||
// Overriding all of that, if the start time is 00:00 and the end time is 23:59 when considered in UTC, the
|
||||
// hours and minutes are stripped out from the display, as we assume the server is just giving us full days.
|
||||
// Finally, if there is no end date set, "---" is displayed.
|
||||
var whole_days = start_time_unix.utc().format("HH:mm") == "00:00" &&
|
||||
(end_time_unix != null || end_time_unix > 0 || end_time_unix.utc().format("HH:mm") == "23:59");
|
||||
var hours_minutes_format = whole_days ? "" : " HH:mm";
|
||||
var start_time_formatted = start_time.format("D MMM" + hours_minutes_format);
|
||||
if (start_time.format("YYYY") != moment().format("YYYY")) {
|
||||
start_time_formatted = start_time.format("D MMM YYYY HH:mm");
|
||||
start_time_formatted = start_time.format("D MMM YYYY" + hours_minutes_format);
|
||||
} else if (useLocalTime && start_time.format("D MMM YYYY") == moment().format("D MMM YYYY")) {
|
||||
start_time_formatted = start_time.format("[Today] HH:mm");
|
||||
start_time_formatted = start_time.format("[Today]" + hours_minutes_format);
|
||||
}
|
||||
var end_time_formatted = "---";
|
||||
if (end_time_unix != null && end_time_unix > 0 && end_time != null) {
|
||||
var end_time_formatted = end_time.format("HH:mm");
|
||||
var end_time_formatted = whole_days ? start_time_formatted : end_time.format("HH:mm");
|
||||
if (end_time.format("D MMM") != start_time.format("D MMM")) {
|
||||
if (end_time.format("YYYY") != moment().format("YYYY")) {
|
||||
end_time_formatted = end_time.format("D MMM YYYY HH:mm");
|
||||
end_time_formatted = end_time.format("D MMM YYYY" + hours_minutes_format);
|
||||
} else {
|
||||
end_time_formatted = end_time.format("D MMM HH:mm");
|
||||
end_time_formatted = end_time.format("D MMM" + hours_minutes_format);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -212,7 +219,7 @@ function generateMaxDurationDropdownFilterCard(band_options) {
|
||||
<option value="86400" selected>24 hours</option>
|
||||
<option value="604800">1 week</option>
|
||||
<option value="2419200">4 weeks</option>
|
||||
<option value="">No limit</option>
|
||||
<option value="9999999999">No limit</option>
|
||||
</select>`);
|
||||
$p.append(" <i class='fa-solid fa-circle-question' title='Some users create long-duration alerts for the period they will be generally in and around xOTA references, not just the times they are specifically on the air. Use this control to restrict the maximum duration of spots that the software will display, and exclude any with a long duration.'></i>");
|
||||
// Compile HTML elements to return
|
||||
|
||||
@@ -108,10 +108,10 @@ function saveSettings() {
|
||||
// Find all storeable UI elements, store a key of "element id:property name" mapped to the value of that
|
||||
// property. For a checkbox, that's the "checked" property.
|
||||
$(".storeable-checkbox").each(function() {
|
||||
localStorage.setItem($(this)[0].id + ":checked", $(this)[0].checked);
|
||||
localStorage.setItem("#" + $(this)[0].id + ":checked", $(this)[0].checked);
|
||||
});
|
||||
$(".storeable-select").each(function() {
|
||||
localStorage.setItem($(this)[0].id + ":value", $(this)[0].value);
|
||||
localStorage.setItem("#" + $(this)[0].id + ":value", $(this)[0].value);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -119,8 +119,10 @@ function saveSettings() {
|
||||
function loadSettings() {
|
||||
// Find all local storage entries and push their data to the corresponding UI element
|
||||
Object.keys(localStorage).forEach(function(key) {
|
||||
if (key.startsWith("#") && key.includes(":")) {
|
||||
// Split the key back into an element ID and a property
|
||||
var split = key.split(":");
|
||||
$("#" + split[0]).prop(split[1], JSON.parse(localStorage.getItem(key)));
|
||||
$(split[0]).prop(split[1], JSON.parse(localStorage.getItem(key)));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user