mirror of
https://git.ianrenton.com/ian/spothole.git
synced 2026-06-24 05:35:10 +00:00
Merge branch 'main' into 95-send-spots-to-xota
# Conflicts: # README.md # server/handlers/api/addspot.py # server/handlers/api/options.py # spotproviders/tiles.py # templates/about.html # templates/add_spot.html # templates/alerts.html # templates/api_only_home.html # templates/bands.html # templates/base.html # templates/conditions.html # templates/map.html # templates/spots.html # templates/status.html # webassets/css/style.css # webassets/js/add-spot.js # webassets/js/geo.js # webassets/js/ui-ham.js # webassets/js/utils.js
This commit is contained in:
@@ -3,10 +3,13 @@ import logging
|
||||
import re
|
||||
import threading
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
import pytz
|
||||
import requests
|
||||
import tornado
|
||||
from tornado import httputil
|
||||
from tornado.web import Application
|
||||
|
||||
from core.config import ALLOW_SPOTTING, ALLOW_UPSTREAM_SPOTTING, MAX_SPOT_AGE, RECAPTCHA_SECRET_KEY
|
||||
from core.constants import UNKNOWN_BAND
|
||||
@@ -23,6 +26,11 @@ RECAPTCHA_VERIFY_URL = "https://www.google.com/recaptcha/api/siteverify"
|
||||
class APISpotHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/spot (POST)"""
|
||||
|
||||
def __init__(self, application: "Application", request: httputil.HTTPServerRequest, **kwargs: Any):
|
||||
self._spots = None
|
||||
self._web_server_metrics = None
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def initialize(self, spots, web_server_metrics, spot_providers=None):
|
||||
self._spots = spots
|
||||
self._web_server_metrics = web_server_metrics
|
||||
|
||||
@@ -3,16 +3,18 @@ import json
|
||||
import logging
|
||||
from datetime import datetime
|
||||
from queue import Queue
|
||||
from typing import Any
|
||||
|
||||
import pytz
|
||||
import tornado
|
||||
import tornado_eventsource.handler
|
||||
from tornado import httputil
|
||||
from tornado.web import Application
|
||||
|
||||
from core.prometheus_metrics_handler import api_requests_counter
|
||||
from core.utils import serialize_everything, empty_queue
|
||||
from data.lookup_credentials import extract_credentials
|
||||
|
||||
|
||||
SSE_HANDLER_MAX_QUEUE_SIZE = 100
|
||||
SSE_HANDLER_QUEUE_CHECK_INTERVAL = 5000
|
||||
|
||||
@@ -20,6 +22,11 @@ SSE_HANDLER_QUEUE_CHECK_INTERVAL = 5000
|
||||
class APIAlertsHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/alerts"""
|
||||
|
||||
def __init__(self, application: "Application", request: httputil.HTTPServerRequest, **kwargs: Any):
|
||||
self._alerts = None
|
||||
self._web_server_metrics = None
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def initialize(self, alerts, web_server_metrics):
|
||||
self._alerts = alerts
|
||||
self._web_server_metrics = web_server_metrics
|
||||
@@ -67,6 +74,15 @@ class APIAlertsHandler(tornado.web.RequestHandler):
|
||||
class APIAlertsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
||||
"""API request handler for /api/v1/alerts/stream"""
|
||||
|
||||
def __init__(self, application, request, **kwargs: Any):
|
||||
self._sse_alert_queues = None
|
||||
self._web_server_metrics = None
|
||||
self._query_params = None
|
||||
self._credentials = None
|
||||
self._alert_queue = None
|
||||
self._heartbeat = None
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def initialize(self, sse_alert_queues, web_server_metrics):
|
||||
self._sse_alert_queues = sse_alert_queues
|
||||
self._web_server_metrics = web_server_metrics
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
import json
|
||||
from collections import Counter
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Any
|
||||
|
||||
import pytz
|
||||
import tornado
|
||||
from tornado import httputil
|
||||
from tornado.web import Application
|
||||
|
||||
from core.prometheus_metrics_handler import api_requests_counter
|
||||
|
||||
@@ -16,6 +19,11 @@ BANDS_SET = frozenset(BANDS)
|
||||
class APIDxStatsHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/dxstats"""
|
||||
|
||||
def __init__(self, application: "Application", request: httputil.HTTPServerRequest, **kwargs: Any):
|
||||
self._spots = None
|
||||
self._web_server_metrics = None
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def initialize(self, spots, web_server_metrics):
|
||||
self._spots = spots
|
||||
self._web_server_metrics = web_server_metrics
|
||||
|
||||
@@ -2,9 +2,12 @@ import json
|
||||
import logging
|
||||
import re
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
import pytz
|
||||
import tornado
|
||||
from tornado import httputil
|
||||
from tornado.web import Application
|
||||
|
||||
from core.constants import SIGS
|
||||
from core.geo_utils import lat_lon_for_grid_sw_corner_plus_size, lat_lon_to_cq_zone, lat_lon_to_itu_zone
|
||||
@@ -19,6 +22,10 @@ from data.spot import Spot
|
||||
class APILookupCallHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/lookup/call"""
|
||||
|
||||
def __init__(self, application: "Application", request: httputil.HTTPServerRequest, **kwargs: Any):
|
||||
self._web_server_metrics = None
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def initialize(self, web_server_metrics):
|
||||
self._web_server_metrics = web_server_metrics
|
||||
|
||||
@@ -36,7 +43,7 @@ class APILookupCallHandler(tornado.web.RequestHandler):
|
||||
|
||||
# The "call" query param must exist and look like a callsign
|
||||
if "call" in query_params.keys():
|
||||
call = query_params.get("call").upper()
|
||||
call = str(query_params.get("call")).upper()
|
||||
if re.match(r"^[A-Z0-9/\-]*$", call):
|
||||
# Take the callsign, make a "fake spot" so we can run infer_missing() on it, then repack the
|
||||
# resulting data in the correct way for the API response.
|
||||
@@ -80,6 +87,10 @@ class APILookupCallHandler(tornado.web.RequestHandler):
|
||||
class APILookupSIGRefHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/lookup/sigref"""
|
||||
|
||||
def __init__(self, application: "Application", request: httputil.HTTPServerRequest, **kwargs: Any):
|
||||
self._web_server_metrics = None
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def initialize(self, web_server_metrics):
|
||||
self._web_server_metrics = web_server_metrics
|
||||
|
||||
@@ -98,8 +109,8 @@ class APILookupSIGRefHandler(tornado.web.RequestHandler):
|
||||
# "sig" and "id" query params must exist, SIG must be known, and if we have a reference regex for that SIG,
|
||||
# the provided id must match it.
|
||||
if "sig" in query_params.keys() and "id" in query_params.keys():
|
||||
sig = query_params.get("sig").upper()
|
||||
ref_id = query_params.get("id").upper()
|
||||
sig = str(query_params.get("sig")).upper()
|
||||
ref_id = str(query_params.get("id")).upper()
|
||||
if sig in list(map(lambda p: p.name, SIGS)):
|
||||
if not get_ref_regex_for_sig(sig) or re.match(get_ref_regex_for_sig(sig), ref_id):
|
||||
data = populate_sig_ref_info(SIGRef(id=ref_id, sig=sig))
|
||||
@@ -107,8 +118,9 @@ class APILookupSIGRefHandler(tornado.web.RequestHandler):
|
||||
|
||||
else:
|
||||
self.write(
|
||||
json.dumps("Error - '" + ref_id + "' does not look like a valid reference ID for " + sig + ".",
|
||||
default=serialize_everything))
|
||||
json.dumps(
|
||||
"Error - '" + ref_id + "' does not look like a valid reference ID for " + sig + ".",
|
||||
default=serialize_everything))
|
||||
self.set_status(422)
|
||||
else:
|
||||
self.write(json.dumps("Error - sig '" + sig + "' is not known.", default=serialize_everything))
|
||||
@@ -129,6 +141,10 @@ class APILookupSIGRefHandler(tornado.web.RequestHandler):
|
||||
class APILookupGridHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/lookup/grid"""
|
||||
|
||||
def __init__(self, application: "Application", request: httputil.HTTPServerRequest, **kwargs: Any):
|
||||
self._web_server_metrics = None
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def initialize(self, web_server_metrics):
|
||||
self._web_server_metrics = web_server_metrics
|
||||
|
||||
@@ -146,7 +162,7 @@ class APILookupGridHandler(tornado.web.RequestHandler):
|
||||
|
||||
# "grid" query param must exist.
|
||||
if "grid" in query_params.keys():
|
||||
grid = query_params.get("grid").upper()
|
||||
grid = str(query_params.get("grid")).upper()
|
||||
lat, lon, lat_cell_size, lon_cell_size = lat_lon_for_grid_sw_corner_plus_size(grid)
|
||||
if lat is not None and lon is not None and lat_cell_size is not None and lon_cell_size is not None:
|
||||
center_lat = lat + lat_cell_size / 2.0
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
import pytz
|
||||
import tornado
|
||||
from tornado import httputil
|
||||
from tornado.web import Application
|
||||
|
||||
from core.config import MAX_SPOT_AGE, ALLOW_SPOTTING
|
||||
from core.constants import BANDS, ALL_MODES, MODE_TYPES, SIGS, CONTINENTS
|
||||
@@ -13,6 +16,11 @@ from core.utils import serialize_everything
|
||||
class APIOptionsHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/options"""
|
||||
|
||||
def __init__(self, application: "Application", request: httputil.HTTPServerRequest, **kwargs: Any):
|
||||
self._status_data = None
|
||||
self._web_server_metrics = None
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def initialize(self, status_data, web_server_metrics, spot_providers=None):
|
||||
self._status_data = status_data
|
||||
self._web_server_metrics = web_server_metrics
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
import pytz
|
||||
import tornado
|
||||
from tornado import httputil
|
||||
from tornado.web import Application
|
||||
|
||||
from core.prometheus_metrics_handler import api_requests_counter
|
||||
|
||||
@@ -9,6 +12,11 @@ from core.prometheus_metrics_handler import api_requests_counter
|
||||
class APISolarConditionsHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/solar"""
|
||||
|
||||
def __init__(self, application: "Application", request: httputil.HTTPServerRequest, **kwargs: Any):
|
||||
self._solar_conditions = None
|
||||
self._web_server_metrics = None
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def initialize(self, solar_conditions, web_server_metrics):
|
||||
self._solar_conditions = solar_conditions
|
||||
self._web_server_metrics = web_server_metrics
|
||||
|
||||
@@ -3,16 +3,18 @@ import json
|
||||
import logging
|
||||
from datetime import datetime, timedelta
|
||||
from queue import Queue
|
||||
from typing import Any
|
||||
|
||||
import pytz
|
||||
import tornado
|
||||
import tornado_eventsource.handler
|
||||
from tornado import httputil
|
||||
from tornado.web import Application
|
||||
|
||||
from core.prometheus_metrics_handler import api_requests_counter
|
||||
from core.utils import serialize_everything, empty_queue
|
||||
from data.lookup_credentials import extract_credentials
|
||||
|
||||
|
||||
SSE_HANDLER_MAX_QUEUE_SIZE = 1000
|
||||
SSE_HANDLER_QUEUE_CHECK_INTERVAL = 5000
|
||||
|
||||
@@ -20,6 +22,11 @@ SSE_HANDLER_QUEUE_CHECK_INTERVAL = 5000
|
||||
class APISpotsHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/spots"""
|
||||
|
||||
def __init__(self, application: "Application", request: httputil.HTTPServerRequest, **kwargs: Any):
|
||||
self._spots = None
|
||||
self._web_server_metrics = None
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def initialize(self, spots, web_server_metrics):
|
||||
self._spots = spots
|
||||
self._web_server_metrics = web_server_metrics
|
||||
@@ -67,6 +74,15 @@ class APISpotsHandler(tornado.web.RequestHandler):
|
||||
class APISpotsStreamHandler(tornado_eventsource.handler.EventSourceHandler):
|
||||
"""API request handler for /api/v1/spots/stream"""
|
||||
|
||||
def __init__(self, application, request, **kwargs: Any):
|
||||
self._sse_spot_queues = None
|
||||
self._web_server_metrics = None
|
||||
self._query_params = None
|
||||
self._credentials = None
|
||||
self._spot_queue = None
|
||||
self._heartbeat = None
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def initialize(self, sse_spot_queues, web_server_metrics):
|
||||
self._sse_spot_queues = sse_spot_queues
|
||||
self._web_server_metrics = web_server_metrics
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import json
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
import pytz
|
||||
import tornado
|
||||
from tornado import httputil
|
||||
from tornado.web import Application
|
||||
|
||||
from core.prometheus_metrics_handler import api_requests_counter
|
||||
from core.utils import serialize_everything
|
||||
@@ -11,6 +14,11 @@ from core.utils import serialize_everything
|
||||
class APIStatusHandler(tornado.web.RequestHandler):
|
||||
"""API request handler for /api/v1/status"""
|
||||
|
||||
def __init__(self, application: "Application", request: httputil.HTTPServerRequest, **kwargs: Any):
|
||||
self._status_data = None
|
||||
self._web_server_metrics = None
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def initialize(self, status_data, web_server_metrics):
|
||||
self._status_data = status_data
|
||||
self._web_server_metrics = web_server_metrics
|
||||
|
||||
@@ -1,7 +1,10 @@
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
import pytz
|
||||
import tornado
|
||||
from tornado import httputil
|
||||
from tornado.web import Application
|
||||
|
||||
from core.config import ALLOW_SPOTTING, WEB_UI_OPTIONS, BASE_URL, SERVER_OWNER_CALLSIGN
|
||||
from core.constants import SOFTWARE_VERSION
|
||||
@@ -11,6 +14,11 @@ from core.prometheus_metrics_handler import page_requests_counter
|
||||
class PageTemplateHandler(tornado.web.RequestHandler):
|
||||
"""Handler for all HTML pages generated from templates"""
|
||||
|
||||
def __init__(self, application: "Application", request: httputil.HTTPServerRequest, **kwargs: Any):
|
||||
self._template_name = None
|
||||
self._web_server_metrics = None
|
||||
super().__init__(application, request, **kwargs)
|
||||
|
||||
def initialize(self, template_name, web_server_metrics):
|
||||
self._template_name = template_name
|
||||
self._web_server_metrics = web_server_metrics
|
||||
@@ -25,4 +33,4 @@ class PageTemplateHandler(tornado.web.RequestHandler):
|
||||
# Load named template, and provide variables used in templates
|
||||
self.render(self._template_name + ".html", software_version=SOFTWARE_VERSION,
|
||||
server_owner_callsign=SERVER_OWNER_CALLSIGN, allow_spotting=ALLOW_SPOTTING,
|
||||
web_ui_options=WEB_UI_OPTIONS, baseurl=BASE_URL, current_path=self.request.path)
|
||||
web_ui_options=WEB_UI_OPTIONS, baseurl=BASE_URL, current_path=self.request.path)
|
||||
|
||||
Reference in New Issue
Block a user