diff --git a/core/constants.py b/core/constants.py index 31cabe7..6c57950 100644 --- a/core/constants.py +++ b/core/constants.py @@ -1,5 +1,5 @@ from core.config import SERVER_OWNER_CALLSIGN -from core.enums import SIGType +from core.enums import SIGRefType, SIGType from data.band import Band from data.sig import SIG @@ -17,6 +17,7 @@ SIGS = [ comment_names=["POTA"], description="Parks on the Air", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.PARK, ref_regex=r"[A-Z]{2}\-\d{4,5}|K\-TEST", icon="fa-tree", refs_globally_unique=False, @@ -26,6 +27,7 @@ SIGS = [ comment_names=["SOTA"], description="Summits on the Air", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.SUMMIT, ref_regex=r"[A-Z0-9]{1,3}\/[A-Z]{2}\-\d{3}", icon="fa-mountain-sun", refs_globally_unique=False, @@ -35,6 +37,7 @@ SIGS = [ comment_names=["WWFF"], description="World Wide Flora & Fauna", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.PARK, ref_regex=r"[A-Z0-9]{1,3}FF\-\d{4}", icon="fa-seedling", refs_globally_unique=True, @@ -44,6 +47,7 @@ SIGS = [ comment_names=["GMA"], description="Global Mountain Activity", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.SUMMIT, ref_regex=r"[A-Z0-9]{1,3}\/[A-Z]{2}\-\d{3}", icon="fa-person-hiking", refs_globally_unique=False, @@ -53,6 +57,7 @@ SIGS = [ comment_names=["WWBOTA", "BOTA"], description="Worldwide Bunkers on the Air", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.BUNKER, ref_regex=r"B\/[A-Z0-9]{1,3}\-\d{3,4}", icon="fa-radiation", refs_globally_unique=True, @@ -62,6 +67,7 @@ SIGS = [ comment_names=["HEMA"], description="HuMPs Excluding Marilyns Award", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.SUMMIT, ref_regex=r"[A-Z0-9]{1,3}\/[A-Z]{3}\-\d{3}", icon="fa-mound", refs_globally_unique=False, @@ -71,6 +77,7 @@ SIGS = [ comment_names=["IOTA"], description="Islands on the Air", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.ISLAND, ref_regex=r"[A-Z]{2}\-\d{3}", icon="fa-book-atlas", refs_globally_unique=False, @@ -80,6 +87,7 @@ SIGS = [ comment_names=[], description="Global Mountain Activity - Islands", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.ISLAND, ref_regex=r"(([A-Z]{2}\-\d{3})|([A-Z0-9]{1,3}\/[A-Z]{2}\-\d{3}))", icon="fa-person-hiking", refs_globally_unique=False, @@ -89,6 +97,7 @@ SIGS = [ comment_names=["ARLHS"], description="Amateur Radio Lighthouse Society", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.LIGHTHOUSE, ref_regex=r"[A-Z]{3}[\- ]\d{3,4}", icon="fa-house-flood-water", refs_globally_unique=False, @@ -98,6 +107,7 @@ SIGS = [ comment_names=["ILLW"], description="International Lighthouse & Lightship Weekend", sig_type=SIGType.EVENT, + ref_type=SIGRefType.LIGHTHOUSE, ref_regex=r"[A-Z]{2}\d{4}", icon="fa-house-flood-water", refs_globally_unique=False, @@ -107,6 +117,7 @@ SIGS = [ comment_names=["MOTA"], description="Mills on the Air", sig_type=SIGType.EVENT, + ref_type=SIGRefType.MILL, ref_regex=r"X\d{4,6}", icon="fa-fan", refs_globally_unique=True, @@ -116,6 +127,7 @@ SIGS = [ comment_names=["SIOTA"], description="Silos on the Air", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.SILO, ref_regex=r"[A-Z]{2}\-[A-Z]{3}\d", icon="fa-wheat-awn", refs_globally_unique=False, @@ -125,6 +137,7 @@ SIGS = [ comment_names=["WCA"], description="World Castles Award", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.CASTLE, ref_regex=r"[A-Z0-9]{1,3}\-\d{5}", icon="fa-chess-rook", refs_globally_unique=False, @@ -134,6 +147,7 @@ SIGS = [ comment_names=["ZLOTA"], description="New Zealand on the Air", sig_type=SIGType.REGIONAL, + ref_type=None, ref_regex=r"ZL[A-Z]/[A-Z]{2}\-\d{3,4}", icon="fa-kiwi-bird", region_flag="🇳🇿", @@ -144,6 +158,7 @@ SIGS = [ comment_names=["WOTA"], description="Wainwrights on the Air", sig_type=SIGType.REGIONAL, + ref_type=SIGRefType.SUMMIT, ref_regex=r"[A-Z]{3}-[0-9]{2}", icon="fa-w", region_flag="🇬🇧", @@ -154,6 +169,7 @@ SIGS = [ comment_names=[], description="Beaches on the Air", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.BEACH, icon="fa-umbrella-beach", refs_globally_unique=False, ), @@ -162,6 +178,7 @@ SIGS = [ comment_names=["KRMNPA"], description="Keith Roget Memorial National Parks Award", sig_type=SIGType.REGIONAL, + ref_type=SIGRefType.PARK, ref_regex=r"VKFF\-\d{4}", icon="fa-earth-oceania", region_flag="🇦🇺", @@ -172,6 +189,7 @@ SIGS = [ comment_names=["SANPCPA"], description="South Australian National Parks and Conservation Parks Award", sig_type=SIGType.REGIONAL, + ref_type=SIGRefType.PARK, ref_regex=r"VKFF\-\d{4}", icon="fa-earth-oceania", region_flag="🇦🇺", @@ -182,6 +200,7 @@ SIGS = [ comment_names=["LLOTA"], description="Lagos y Lagunas on the Air", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.LAKE, ref_regex=r"LL[A-Z]{2}\-\d{4}", icon="fa-water", refs_globally_unique=True, @@ -191,6 +210,7 @@ SIGS = [ comment_names=["TOTA"], description="Towers on the Air", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.TOWER, ref_regex=r"[A-Z]{2,3}R\-\d{4}", icon="fa-tower-observation", refs_globally_unique=False, @@ -200,6 +220,7 @@ SIGS = [ comment_names=[], description="Tiles on the Air", sig_type=SIGType.WORLDWIDE, + ref_type=SIGRefType.GRID, ref_regex=r"[A-Za-z]{2}[0-9]{2}[A-Za-z]{2}", icon="fa-square", refs_globally_unique=False, @@ -209,6 +230,7 @@ SIGS = [ comment_names=["WAB"], description="Worked All Britain", sig_type=SIGType.REGIONAL, + ref_type=SIGRefType.GRID, ref_regex=r"[A-Z]{1,2}[0-9]{2}", icon="fa-table-cells-large", region_flag="🇬🇧", @@ -219,6 +241,7 @@ SIGS = [ comment_names=["WAI"], description="Worked All Ireland", sig_type=SIGType.REGIONAL, + ref_type=SIGRefType.GRID, ref_regex=r"[A-Z][0-9]{2}", icon="fa-table-cells-large", region_flag="🇮🇪", @@ -229,6 +252,7 @@ SIGS = [ comment_names=["DME"], description="Diploma Municipios de España", sig_type=SIGType.REGIONAL, + ref_type=SIGRefType.TOWN, ref_regex=r"\d{4,5}", icon="fa-building", region_flag="🇪🇸", @@ -239,6 +263,7 @@ SIGS = [ comment_names=["FEA"], description="Diploma Faros de España", sig_type=SIGType.REGIONAL, + ref_type=SIGRefType.LIGHTHOUSE, # FEA references are technically [DE]\-\d{4}(\.\d)? but spotters always seem to miss out the D- or E- # prefix and just use FEA-1234 or FEA 1234, so allow for that. The FEA sigref data provider adds both # forms to the database. @@ -252,6 +277,7 @@ SIGS = [ comment_names=["DMUE"], description="Diploma Museos de España", sig_type=SIGType.REGIONAL, + ref_type=SIGRefType.BUILDING, ref_regex=r"MUE[A-Z]{2}-\d{3}", icon="fa-landmark", region_flag="🇪🇸", @@ -262,6 +288,7 @@ SIGS = [ comment_names=["DMVE"], description="Diploma Monumentos y Vestigios de España", sig_type=SIGType.REGIONAL, + ref_type=SIGRefType.BUILDING, ref_regex=r"MV[A-Z]{1,2}-\d{4}", icon="fa-monument", region_flag="🇪🇸", @@ -272,6 +299,7 @@ SIGS = [ comment_names=["DCE"], description="Diploma Castillos de España", sig_type=SIGType.REGIONAL, + ref_type=SIGRefType.CASTLE, ref_regex=r"C[A-Z]{1,2}-\d{3}", icon="fa-chess-rook", region_flag="🇪🇸", @@ -282,6 +310,7 @@ SIGS = [ comment_names=["DEFE"], description="Diploma Estaciones de Ferrocarril de España", sig_type=SIGType.REGIONAL, + ref_type=SIGRefType.BUILDING, ref_regex=r"EF[A-Z]{1,2}-\d{3}", icon="fa-train", region_flag="🇪🇸", @@ -292,6 +321,7 @@ SIGS = [ comment_names=["DTMBA"], description="Diploma Teatri Musei e Belle Arti", sig_type=SIGType.REGIONAL, + ref_type=SIGRefType.BUILDING, ref_regex=r"I-?[0-9]{3,4}\s?[A-Z]{2}", icon="fa-landmark", region_flag="🇮🇹", @@ -302,6 +332,7 @@ SIGS = [ comment_names=["BIWOTA"], description="British Inland Waterways on the Air", sig_type=SIGType.EVENT, + ref_type=SIGRefType.WATERWAY, icon="fa-ship", region_flag="🇬🇧", refs_globally_unique=False, @@ -311,6 +342,7 @@ SIGS = [ comment_names=["COTA"], description="Castles on the Air", sig_type=SIGType.REGIONAL, + ref_type=SIGRefType.CASTLE, ref_regex=r"[A-Z]{3}\-[0-9]{3,5}", icon="fa-chess-rook", region_flag="🇩🇪", @@ -321,6 +353,7 @@ SIGS = [ comment_names=["PGA"], description="Polish Gmina Award", sig_type=SIGType.REGIONAL, + ref_type=SIGRefType.REGION, ref_regex=r"[A-Z]{2}[0-9]{2}", icon="fa-g", region_flag="🇵🇱", @@ -331,6 +364,7 @@ SIGS = [ comment_names=[], description="Toilets on the Air", sig_type=SIGType.EVENT, + ref_type=SIGRefType.TOILET, ref_regex=r"T\-[0-9]{2}", icon="fa-toilet", region_flag="🏴‍☠️", diff --git a/core/sig_lookup_helper.py b/core/sig_lookup_helper.py index 313e95c..e5fc5be 100644 --- a/core/sig_lookup_helper.py +++ b/core/sig_lookup_helper.py @@ -2,20 +2,22 @@ import logging from pyhamtools.locator import latlong_to_locator, locator_to_latlong +from core.constants import SIGS from core.data_store import DATA_STORE +from core.enums import SIGRefType from core.geo_utils import wab_wai_square_to_lat_lon from data.sig_ref import SIGRef logger = logging.getLogger(__name__) -def get_sig_ref_info(sig, ref_id): +def get_sig_ref_info(sig_name, ref_id): """Look up details of a SIG reference (e.g. POTA park) such as name, lat/lon, and grid. Takes in a sig name and a reference ID (both strings) and returns a SigRef object populated with as much data as we can find. This makes use of SIG ref data in the data store, live lookups from the web, or just automatic calculation depending on which SIG we are getting data for.""" - if sig is None or sig == "" or ref_id is None or ref_id == "": + if sig_name is None or sig_name == "" or ref_id is None or ref_id == "": logger.debug("Failed to look up sig_ref info, sig or ref were not set.") return None @@ -24,33 +26,43 @@ def get_sig_ref_info(sig, ref_id): ref_id.replace(" ", "-") # Prepare the object to be returned - sig_ref = SIGRef(sig=sig, id=ref_id) + sig_ref = SIGRef(sig=sig_name, id=ref_id) + + # We can always get the reference type and the icon from the SIG itself, if the reference data doesn't already + # contain it. If the sig ref already has this data, it should be used for preference. + for sig in SIGS: + if sig.name.upper() == sig_name.upper(): + if not sig_ref.ref_type: + sig_ref.ref_type = sig.ref_type + if not sig_ref.icon: + sig_ref.icon = sig.icon try: ### FUDGES ### # # DME fudge. Our database has leading zeros padding to 5 digits which is the expected format, but not all # activators add leading zeros. - if sig.upper() == "DME": + if sig_name.upper() == "DME": ref_id = ref_id.zfill(5) # DTMBA spotters sometimes include spaces and dashes, our regex allows them but they must be removed here so we # can look up against the official list which doesn't have them - if sig.upper() == "DTMBA": + if sig_name.upper() == "DTMBA": ref_id = ref_id.replace("-", "").replace(" ", "") - # If the SIG is HEMA, we have no current lookup for this so just skip the lookup here. - if sig.upper() == "HEMA": - sig_ref.ref_type = "Summit" + ### NO DATA SIGS ### + # + # If the SIG is HEMA or BIWOTA, we have no way to either generate useful data or look it up on a reference list, + # so just skip the lookup here. + if sig_name.upper() == "HEMA" or sig_name.upper() == "BIWOTA": return sig_ref ### PROGRAMMATIC DATA GENERATION INSTEAD OF LOOKUPS ### # # If the SIG is Tiles, WAB, WAI or BOTA (Beaches), we don't have anything to look up from the data store, we can # calculate all the information we are going to get directly. - if sig.upper() == "TILES": + if sig_name.upper() == "TILES": # Tiles on the Air just uses Maidenhead 6-digit squares, so ID, Name and Grid are all the same - sig_ref.ref_type = "Grid" if not sig_ref.name: sig_ref.name = sig_ref.id if not sig_ref.grid: @@ -61,8 +73,7 @@ def get_sig_ref_info(sig, ref_id): sig_ref.longitude = ll[1] return sig_ref - elif sig.upper() == "WAB" or sig.upper() == "WAI": - sig_ref.ref_type = "Grid" + elif sig_name.upper() == "WAB" or sig_name.upper() == "WAI": ll = wab_wai_square_to_lat_lon(ref_id) if ll: sig_ref.name = ref_id @@ -74,20 +85,15 @@ def get_sig_ref_info(sig, ref_id): logger.warning("Invalid lat/lon received for WAB/WAI reference") return sig_ref - elif sig.upper() == "BOTA": + elif sig_name.upper() == "BOTA": # For BOTA all we can ever generate is the URL, there is no data file or lookup for lat/longs - sig_ref.ref_type = "Beach" if not sig_ref.name: sig_ref.name = sig_ref.id if sig_ref.name: sig_ref.url = f"https://www.beachesontheair.com/beaches/{sig_ref.name.lower().replace(' ', '-')}" return sig_ref - elif sig.upper() == "BIWOTA": - # For BIWOTA there are no references, all we can set is a type - sig_ref.ref_type = "Waterway" - - elif sig.upper() == "GMA Islands": + elif sig_name.upper() == "GMA Islands": # GMA Islands is a bit of a mess of GMA and IOTA references. Try looking them both up and see what returns # the best result. iota_lookup = get_sig_ref_info("IOTA", ref_id) @@ -98,14 +104,14 @@ def get_sig_ref_info(sig, ref_id): for key, value in gma_lookup.__dict__.items(): if value is not None and sig_ref.__dict__.get(key) is None: sig_ref.__dict__[key] = value - sig_ref.ref_type = "Island" + sig_ref.ref_type = SIGRefType.ISLAND return sig_ref ### ACTUAL LOOKUP ### # # OK, this is something we have to look up. Now check to see if our data store contains reference data and use # that. - key = f"{sig}:{ref_id}" + key = f"{sig_name}:{ref_id}" lookup_data = DATA_STORE.sigrefs.get(key) if key in DATA_STORE.sigrefs else None if lookup_data: return lookup_data @@ -113,10 +119,10 @@ def get_sig_ref_info(sig, ref_id): else: # Maybe a super new reference we don't know about yet, but more likely a typo or a test reference, # just silently ignore it. - logger.debug(f"{sig} database did not contain data for ref {ref_id}") + logger.debug(f"{sig_name} database did not contain data for ref {ref_id}") except Exception: - logger.exception(f"Exception when looking up sig_ref info for {sig} ref {ref_id}") + logger.exception(f"Exception when looking up sig_ref info for {sig_name} ref {ref_id}") return sig_ref diff --git a/core/utils.py b/core/utils.py index 73037e3..0c232ed 100644 --- a/core/utils.py +++ b/core/utils.py @@ -99,7 +99,16 @@ def infer_mode_from_frequency(freq): or (28180 <= khz < 28183) ): mode = "FT4" - return mode + + if not mode: + return None + + mode = mode.upper() + if mode in MODE_ALIASES: + mode = MODE_ALIASES[mode] + + return Mode(mode) + except KeyError: return None diff --git a/data/alert.py b/data/alert.py index d2bbaea..584f771 100644 --- a/data/alert.py +++ b/data/alert.py @@ -20,6 +20,9 @@ class Alert: # Unique identifier for the alert id: str | None = None + + # DX (alerting) operator info + # Callsigns of the operators that has been alerted dx_calls: list | None = None # Names of the operators that has been alerted @@ -36,6 +39,9 @@ class Alert: dx_cq_zone: int | None = None # ITU zone of the DX operator dx_itu_zone: int | None = None + + # General alert info + # Intended frequencies & modes of operation. Essentially just a different kind of comment field. freqs_modes: str | None = None # Start time of the activation, UTC seconds since UNIX epoch @@ -46,27 +52,41 @@ class Alert: end_time: float | None = None # End time of the activation of the alert, ISO 8601 end_time_iso: str | None = None + # Comment made by the alerter, if any + comment: str | None = None + # The type of alert this is: xOTA, DXpedition, or Contest. + alert_type: AlertType | None = None + # A URL link to more information, if any + url: str | None = None + + # Special Interest Group info + + # Special Interest Group (SIG), e.g. outdoor activity programme such as POTA + sig: str | None = None + # SIG references. We allow multiple here for e.g. n-fer activations, unlike ADIF SIG_INFO + sig_refs: list | None = None + + # Timing info + # Time that this software received the alert, UTC seconds since UNIX epoch. This is used with the "since_received" # call to our API to receive all data that is new to us, even if by a quirk of the API it might be older than the # list time the client polled the API. received_time: float | None = None # Time that this software received the alert, ISO 8601 received_time_iso: str | None = None - # Comment made by the alerter, if any - comment: str | None = None - # Special Interest Group (SIG), e.g. outdoor activity programme such as POTA - sig: str | None = None - # SIG references. We allow multiple here for e.g. n-fer activations, unlike ADIF SIG_INFO - sig_refs: list | None = None - # The type of alert this is: xOTA, DXpedition, or Contest. - alert_type: AlertType | None = None - # A URL link to more information, if any - url: str | None = None + + # Source info + # Where we got the alert from, e.g. "POTA", "SOTA"... source: str | None = None # The ID the source gave it, if any. source_id: str | None = None + # Display info + + # Icon to use when displaying this alert in the web UI. Chosen from the Font Awesome set. + icon: str | None = None + def infer_missing(self, credentials=None): """Infer missing parameters where possible""" @@ -132,6 +152,15 @@ class Alert: if self.dx_calls and not self.dx_names: self.dx_names = [get_call_info(c, credentials).name for c in self.dx_calls] + # Icon for the spot should be the icon of the first SIG ref if present, otherwise a radio tower + self.icon = "fa-tower-cell" + if self.alert_type == AlertType.DXPEDITION: + self.icon = "fa-globe-africa" + elif self.alert_type == AlertType.CONTEST: + self.icon = "fa-trophy" + elif self.sig_refs and len(self.sig_refs) > 0 and self.sig_refs[0].icon: + self.icon = self.sig_refs[0].icon + except Exception: logger.exception("Exception while inferring missing data from spot") diff --git a/data/sig.py b/data/sig.py index a69603a..743578f 100644 --- a/data/sig.py +++ b/data/sig.py @@ -1,6 +1,6 @@ from dataclasses import dataclass, field -from core.enums import SIGType +from core.enums import SIGRefType, SIGType @dataclass @@ -27,6 +27,9 @@ class SIG: refs_globally_unique: bool # SIG names as they might appear in cluster spot comments, e.g. ["TOTA"] comment_names: list[str] = field(default_factory=list) + # Reference type, what gets activated e.g. Park, Summit. May be None if the SIG is for multiple types of things, in + # which case the spot data will have to provide this instead. + ref_type: SIGRefType | None = None # Regex matcher for references, e.g. for POTA r"[A-Z]{2}\-\d+". ref_regex: str | None = None # Icon to use in the UI when referencing this SIG. Chosen from the Font Awesome set. diff --git a/data/sig_ref.py b/data/sig_ref.py index f14e65d..1ab29df 100644 --- a/data/sig_ref.py +++ b/data/sig_ref.py @@ -18,6 +18,8 @@ class SIGRef: ref_type: SIGRefType | None = None # URL to look up more information about the reference, if known. url: str | None = None + # Icon to use for the reference, derived from the SIG. Chosen from the Font Awesome set. + icon: str | None = None # Latitude of the reference, in degrees, if known. latitude: float | None = None # Longitude of the reference, in degrees, if known. diff --git a/data/spot.py b/data/spot.py index acc3d53..8fd869d 100644 --- a/data/spot.py +++ b/data/spot.py @@ -146,6 +146,11 @@ class Spot: # The ID the source gave it, if any. source_id: str | None = None + # Display info + + # Icon to use when displaying this spot in the web UI. Chosen from the Font Awesome set. + icon: str | None = None + def __post_init__(self): """Normalise fields that don't survive a plain dict to Spot conversion. This is used in the "add spot" API endpoint where the client is submitting JSON, and we want to recreate a full Spot object, including nested @@ -455,6 +460,11 @@ class Spot: self.de_longitude = de_call_info.longitude self.de_grid = de_call_info.grid + # Icon for the spot should be the icon of the first SIG ref if present, otherwise a radio tower + self.icon = "fa-tower-cell" + if self.sig_refs and len(self.sig_refs) > 0 and self.sig_refs[0].icon: + self.icon = self.sig_refs[0].icon + except Exception: logger.exception("Exception while inferring missing data from spot") diff --git a/static/apidocs/openapi.yml b/static/apidocs/openapi.yml index e4040dd..0c834b1 100644 --- a/static/apidocs/openapi.yml +++ b/static/apidocs/openapi.yml @@ -20,6 +20,7 @@ info: * Added DTMBA, FEA, BIWOTA, COTA & PGA SIGs * Removed the distinction between LSB & USB (both will now show as SSB) and between the various digital voice modes, which will now show as DV. * Added `sig_type`, `icon`, `region_flag` and `refs_globally_unique` to SIG data + * Added `icon` to spot and alert data * Added `alert_type` and `url` to alert data * Added `contests_skip_max_duration_check` to alert query parameters * SIG reference types (e.g. "Park") are now capitalised to match other enums @@ -1298,6 +1299,10 @@ components: Propagation mode, if known. This is only populated when the upstream spot specifically states it; Spothole does not try to determine it using its own algorithm. $ref: "#/components/schemas/PropagationMode" + icon: + type: string + description: Icon to use when displaying this spot in the web UI. Chosen from the Font Awesome set. + example: "fa-tower-cell" SpotSubmission: @@ -1466,6 +1471,10 @@ components: type: string description: The ID the source gave it, if any. example: "GUID-123456" + icon: + type: string + description: Icon to use when displaying this spot in the web UI. Chosen from the Font Awesome set. + example: "fa-tower-cell" AlertStream: diff --git a/static/js/alerts.js b/static/js/alerts.js index 07ff9dd..2fbfef2 100644 --- a/static/js/alerts.js +++ b/static/js/alerts.js @@ -273,7 +273,7 @@ function addAlertRowsToTable(tbody, alerts) { $tr.append(`${commentText}`); } if (showSource) { - $tr.append(` ${sigSourceText}`); + $tr.append(` ${sigSourceText}`); } if (showRef) { $tr.append(`${sig_refs}`); @@ -291,7 +291,7 @@ function addAlertRowsToTable(tbody, alerts) { const $td2 = $(""); if (showSource) { - $td2.append(` `); + $td2.append(` `); } if (showRef) { $td2.append(`${sig_refs} `); diff --git a/static/js/common.js b/static/js/common.js index e7ffaf5..d68c0b8 100644 --- a/static/js/common.js +++ b/static/js/common.js @@ -285,20 +285,6 @@ function callWanted(call) { } } -// Get the Font Awesome icon for a given SIG. If the SIG is unknown, the provided default symbol will be returned -// The sig is provided by name as a string, while all_sigs contains all the SIG info from the options call. This -// is because sometimes the sig name arrives via a spot and therefore we need to look up the rest of the SIG data -// separately. -function sigToIcon(sig, all_sigs, defaultIcon) { - if (sig) { - const match = all_sigs.find((check_sig) => check_sig["name"].toUpperCase() === sig.toUpperCase()); - if (match) { - return match["icon"]; - } - } - return defaultIcon; -} - // Startup $(document).ready(function () { usePreferredTheme(); diff --git a/static/js/map.js b/static/js/map.js index 68cbf20..ed63e93 100644 --- a/static/js/map.js +++ b/static/js/map.js @@ -223,7 +223,7 @@ function updateMap() { // Get an icon for a spot, based on its band, using PSK Reporter colours, its program etc. function getIcon(s) { return L.ExtraMarkers.icon({ - icon: sigToIcon(s["sig"], options["sigs"], "fa-tower-cell"), + icon: s["icon"], iconColor: bandToContrastColor(s["band"]), markerColor: bandToColor(s["band"]), shape: 'circle', @@ -243,13 +243,19 @@ function getTooltipText(s) { dx_call = dx_call + "-" + s["dx_ssid"]; } + // Format dx country + let dx_country = s["dx_country"]; + if (dx_country == null) { + dx_country = "Unknown or not a country"; + } + // Format DX flag let dx_flag = ""; if (dx_call == null) { dx_flag = ""; } - if (s["dx_flag"] && s["dx_flag"] != null && s["dx_flag"] !== "") { - dx_flag = s["dx_flag"]; + if (s["dx_dxcc_id"] && s["dx_dxcc_id"] != null && s["dx_dxcc_id"] !== 0) { + dx_flag = `${dx_country}`; } // Format the frequency @@ -303,7 +309,7 @@ function getTooltipText(s) { ttt += "
"; // Source / SIG / Ref - ttt += ` ${sigSourceText} ${sig_refs}
`; + ttt += ` ${sigSourceText} ${sig_refs}
`; // Time ttt += ` ${moment.unix(s["time"]).fromNow()}`; diff --git a/static/js/spots.js b/static/js/spots.js index 372dfe0..56d7de5 100644 --- a/static/js/spots.js +++ b/static/js/spots.js @@ -398,7 +398,7 @@ function createNewTableRowsForSpot(s, highlightNew) { $tr.append(`${distanceText}`); } if (showType) { - $tr.append(` ${typeText}`); + $tr.append(` ${typeText}`); } if (showRef) { $tr.append(`${sig_refs}`); @@ -430,7 +430,7 @@ function createNewTableRowsForSpot(s, highlightNew) { const $td2 = $(""); const $td2floatleft = $(`
`); if (showType) { - $td2floatleft.append(` ${typeText} `); + $td2floatleft.append(` ${typeText} `); } if (showRef) { $td2floatleft.append(`${sig_refs} `); diff --git a/templates/add_spot.html b/templates/add_spot.html index 8ce828d..d3ca997 100644 --- a/templates/add_spot.html +++ b/templates/add_spot.html @@ -77,7 +77,7 @@
- + diff --git a/templates/alerts.html b/templates/alerts.html index 521f0e7..704537b 100644 --- a/templates/alerts.html +++ b/templates/alerts.html @@ -81,7 +81,7 @@ - + diff --git a/templates/bands.html b/templates/bands.html index 851a27a..6610b7b 100644 --- a/templates/bands.html +++ b/templates/bands.html @@ -76,8 +76,8 @@ - - + + diff --git a/templates/base.html b/templates/base.html index 92ffbbf..c60fa1c 100644 --- a/templates/base.html +++ b/templates/base.html @@ -1,6 +1,6 @@ {% extends "skeleton.html" %} {% block head_extra %} - + @@ -16,10 +16,10 @@ window.fetchEventSource = fetchEventSource; - - - - + + + + {% end %} {% block body %}
diff --git a/templates/conditions.html b/templates/conditions.html index 6cedb3b..9b8e6e5 100644 --- a/templates/conditions.html +++ b/templates/conditions.html @@ -284,7 +284,7 @@
- + diff --git a/templates/map.html b/templates/map.html index 16bf7ca..359b0a5 100644 --- a/templates/map.html +++ b/templates/map.html @@ -113,8 +113,8 @@ const CARTODB_API_KEY = "{{ web_ui_options.get('cartodb_api_key', '') }}"; - - + + diff --git a/templates/spots.html b/templates/spots.html index 9b9088c..306cf69 100644 --- a/templates/spots.html +++ b/templates/spots.html @@ -113,8 +113,8 @@ - - + + diff --git a/templates/status.html b/templates/status.html index 726edb1..f595bd4 100644 --- a/templates/status.html +++ b/templates/status.html @@ -86,7 +86,7 @@ - +