Files
spothole/providers/spot/pota.py
T

82 lines
3.2 KiB
Python

from datetime import datetime
import pytz
import requests
from core.constants import HTTP_HEADERS
from core.enums import Mode
from core.enums import ActivityName, ActivityRefType
from data.activity_ref import ActivityRef
from data.spot import Spot
from providers.spot.http_spot_provider import HTTPSpotProvider
class POTA(HTTPSpotProvider):
"""Spot provider for Parks on the Air"""
POLL_INTERVAL_SEC = 120
SPOTS_URL = "https://api.pota.app/spot/activator"
SUBMIT_URL = "https://api.pota.app/spot"
def __init__(self, provider_config):
super().__init__("POTA", provider_config, self.SPOTS_URL, self.POLL_INTERVAL_SEC)
def _http_response_to_spots(self, http_response):
new_spots = []
# Iterate through source data
for source_spot in http_response.json():
# Convert to our spot format
spot = Spot(
source=self.name,
source_id=source_spot["spotId"],
dx_call=source_spot["activator"].upper(),
de_call=source_spot["spotter"].upper(),
freq=float(source_spot["frequency"]) * 1000 if source_spot["frequency"] != "INVALID" else None,
mode=Mode.from_name(source_spot["mode"].upper()),
comment=source_spot["comments"],
sig=ActivityName.POTA,
sig_refs=[
ActivityRef(
id=source_spot["reference"],
sig=ActivityName.POTA,
name=source_spot["name"],
latitude=source_spot["latitude"],
longitude=source_spot["longitude"],
ref_type=ActivityRefType.PARK
)
],
time=datetime.strptime(source_spot["spotTime"], "%Y-%m-%dT%H:%M:%S")
.replace(tzinfo=pytz.UTC)
.timestamp(),
dx_grid=source_spot["grid6"],
dx_latitude=source_spot["latitude"],
dx_longitude=source_spot["longitude"],
)
# Add to our list. Don't worry about de-duping, removing old spots etc. at this point; other code will do
# that for us.
new_spots.append(spot)
return new_spots
def can_submit_spot(self, activity):
return activity == ActivityName.POTA
def submit_spot(self, spot, credentials):
sig_ref = spot.sig_refs[0].id if spot.sig_refs else None
if sig_ref:
body = {
"activator": spot.dx_call,
"spotter": spot.de_call,
"frequency": str(spot.freq / 1000.0),
"mode": spot.mode or "",
"reference": sig_ref,
"comments": spot.comment or "",
"source": "Spothole",
}
headers = {**HTTP_HEADERS, "Content-Type": "application/json"}
response = requests.post(self.SUBMIT_URL, json=body, headers=headers, timeout=(5, 30))
if not response.ok:
raise RuntimeError(f"POTA API returned {response.status_code!s}: {response.text}")
else:
raise RuntimeError("Park reference is required for submitting POTA spots.")