from datetime import timedelta, datetime import pytz from requests_cache import CachedSession from rss_parser import RSSParser from core.constants import HTTP_HEADERS from core.sig_utils import get_icon_for_sig from data.spot import Spot from spotproviders.http_spot_provider import HTTPSpotProvider # Spot provider for Wainwrights on the Air class WOTA(HTTPSpotProvider): POLL_INTERVAL_SEC = 120 SPOTS_URL = "https://www.wota.org.uk/spots_rss.php" LIST_URL = "https://www.wota.org.uk/mapping/data/summits.json" LIST_CACHE_TIME_DAYS = 30 LIST_CACHE = CachedSession("cache/wota_data_cache", expire_after=timedelta(days=LIST_CACHE_TIME_DAYS)) RSS_DATE_TIME_FORMAT = "%a, %d %b %Y %H:%M:%S %z" def __init__(self, provider_config): super().__init__(provider_config, self.SPOTS_URL, self.POLL_INTERVAL_SEC) def http_response_to_spots(self, http_response): new_spots = [] rss = RSSParser.parse(http_response.content.decode()) # Iterate through source data for source_spot in rss.channel.items: # Reject GUID missing or zero if not source_spot.guid or not source_spot.guid.content or source_spot.guid.content == "http://www.wota.org.uk/alerts/0": continue # Pick apart the title title_split = source_spot.title.split(" on ") dx_call = title_split[0] ref = None ref_name = None if len(title_split) > 1: ref_split = title_split[1].split(" - ") ref = ref_split[0] if len(ref_split) > 1: ref_name = ref_split[1] # Pick apart the description desc_split = source_spot.description.split(". ") freq_mode = desc_split[0].replace("Frequencies/modes:", "").strip() freq_mode_split = freq_mode.split("-") freq_hz = float(freq_mode_split[0]) * 1000000 mode = freq_mode_split[1] comment = None if len(desc_split) > 1: comment = desc_split[1].strip() spotter = None if len(desc_split) > 2: spotter = desc_split[2].replace("Spotted by ", "").replace(".", "").strip() time = datetime.strptime(source_spot.pub_date.content, self.RSS_DATE_TIME_FORMAT).astimezone(pytz.UTC) # Convert to our spot format spot = Spot(source=self.name, source_id=source_spot.guid.content, dx_call=dx_call, de_call=spotter, freq=freq_hz, mode=mode, comment=comment, sig="WOTA", sig_refs=[ref] if ref else [], sig_refs_names=[ref_name] if ref_name else [], sig_refs_urls="https://www.wota.org.uk/MM_" + ref if ref else [], icon=get_icon_for_sig("WOTA"), time=time.timestamp()) # WOTA name/lat/lon lookup wota_data = self.LIST_CACHE.get(self.LIST_URL, headers=HTTP_HEADERS).json() for feature in wota_data["features"]: if feature["properties"]["wotaId"] == spot.sig_refs[0]: spot.sig_refs_names = [feature["properties"]["title"]] spot.dx_latitude = feature["geometry"]["coordinates"][1] spot.dx_longitude = feature["geometry"]["coordinates"][0] spot.dx_grid = feature["properties"]["qthLocator"] break new_spots.append(spot) return new_spots