from core.config import SERVER_OWNER_CALLSIGN from data.band import Band from data.sig import SIG # General software SOFTWARE_VERSION = "2.1-pre" # HTTP headers used for spot providers that use HTTP HTTP_HEADERS = {"User-Agent": f"Spothole v{SOFTWARE_VERSION} (operated by {SERVER_OWNER_CALLSIGN})"} HAMQTH_PRG = f"Spothole v{SOFTWARE_VERSION} operated by {SERVER_OWNER_CALLSIGN}".replace(" ", "_") # Special Interest Groups SIGS = [ SIG( name="POTA", comment_names=["POTA"], description="Parks on the Air", ref_regex=r"[A-Z]{2}\-\d{4,5}|K\-TEST", icon="fa-tree" ), SIG( name="SOTA", comment_names=["SOTA"], description="Summits on the Air", ref_regex=r"[A-Z0-9]{1,3}\/[A-Z]{2}\-\d{3}", icon="fa-mountain-sun" ), SIG( name="WWFF", comment_names=["WWFF"], description="World Wide Flora & Fauna", ref_regex=r"[A-Z0-9]{1,3}FF\-\d{4}", icon="fa-seedling" ), SIG( name="GMA", comment_names=["GMA"], description="Global Mountain Activity", ref_regex=r"[A-Z0-9]{1,3}\/[A-Z]{2}\-\d{3}", icon="fa-person-hiking" ), SIG( name="WWBOTA", comment_names=["WWBOTA", "BOTA"], description="Worldwide Bunkers on the Air", ref_regex=r"B\/[A-Z0-9]{1,3}\-\d{3,4}", icon="fa-radiation" ), SIG( name="HEMA", comment_names=["HEMA"], description="HuMPs Excluding Marilyns Award", ref_regex=r"[A-Z0-9]{1,3}\/[A-Z]{3}\-\d{3}", icon="fa-mound" ), SIG( name="IOTA", comment_names=["IOTA"], description="Islands on the Air", ref_regex=r"[A-Z]{2}\-\d{3}", icon="fa-book-atlas" ), SIG( name="GMA Islands", comment_names=[], description="Global Mountain Activity - Islands", ref_regex=r"(([A-Z]{2}\-\d{3})|([A-Z0-9]{1,3}\/[A-Z]{2}\-\d{3}))", icon="fa-person-hiking" ), SIG( name="ARLHS", comment_names=["ARLHS"], description="Amateur Radio Lighthouse Society", ref_regex=r"[A-Z]{3}[\- ]\d{3,4}", icon="fa-house-flood-water" ), SIG( name="ILLW", comment_names=["ILLW"], description="International Lighthouse & Lightship Weekend", ref_regex=r"[A-Z]{2}\d{4}", icon="fa-house-flood-water" ), SIG( name="MOTA", comment_names=["MOTA"], description="Mills on the Air", ref_regex=r"X\d{4,6}", icon="fa-fan" ), SIG( name="SIOTA", comment_names=["SIOTA"], description="Silos on the Air", ref_regex=r"[A-Z]{2}\-[A-Z]{3}\d", icon="fa-wheat-awn" ), SIG( name="WCA", comment_names=["WCA"], description="World Castles Award", ref_regex=r"[A-Z0-9]{1,3}\-\d{5}", icon="fa-chess-rook" ), SIG( name="ZLOTA", comment_names=["ZLOTA"], description="New Zealand on the Air", ref_regex=r"ZL[A-Z]/[A-Z]{2}\-\d{3,4}", icon="fa-kiwi-bird", region_flag="🇳🇿" ), SIG( name="WOTA", comment_names=["WOTA"], description="Wainwrights on the Air", ref_regex=r"[A-Z]{3}-[0-9]{2}", icon="fa-w", region_flag="🇬🇧" ), SIG(name="BOTA", comment_names=[], description="Beaches on the Air", icon="fa-umbrella-beach" ), SIG( name="KRMNPA", comment_names=["KRMNPA"], description="Keith Roget Memorial National Parks Award", ref_regex=r"VKFF\-\d{4}", icon="fa-earth-oceania", region_flag="🇦🇺" ), SIG( name="SANPCPA", comment_names=["SANPCPA"], description="South Australian National Parks and Conservation Parks Award", ref_regex=r"VKFF\-\d{4}", icon="fa-earth-oceania", region_flag="🇦🇺" ), SIG( name="LLOTA", comment_names=["LLOTA"], description="Lagos y Lagunas on the Air", ref_regex=r"LL[A-Z]{2}\-\d{4}", icon="fa-water" ), SIG( name="Towers", comment_names=["TOTA"], description="Towers on the Air", ref_regex=r"[A-Z]{2,3}R\-\d{4}", icon="fa-tower-observation" ), SIG( name="Tiles", comment_names=[], description="Tiles on the Air", ref_regex=r"[A-Za-z]{2}[0-9]{2}[A-Za-z]{2}", icon="fa-square" ), SIG( name="WAB", comment_names=["WAB"], description="Worked All Britain", ref_regex=r"[A-Z]{1,2}[0-9]{2}", icon="fa-table-cells-large", region_flag="🇬🇧" ), SIG( name="WAI", comment_names=["WAI"], description="Worked All Ireland", ref_regex=r"[A-Z][0-9]{2}", icon="fa-table-cells-large", region_flag="🇮🇪" ), SIG( name="DME", comment_names=["DME"], description="Diploma Municipios de España", ref_regex=r"\d{4,5}", icon="fa-building", region_flag="🇪🇸" ), SIG( name="FEA", comment_names=["FEA"], description="Diploma Faros de España", # 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, so we treat FEA reference IDs as if they were just the number. ref_regex=r"\d{4}(\.\d)?", icon="fa-house-flood-water", region_flag="🇪🇸" ), SIG( name="DTMBA", comment_names=["DTMBA"], description="Diploma Teatri Musei e Belle Arti", ref_regex=r"I-?[0-9]{3,4}\s?[A-Z]{2}", icon="fa-masks-theater", region_flag="🇮🇹" ), SIG( name="BIWOTA", comment_names=["BIWOTA"], description="British Inland Waterways on the Air", icon="fa-ship", region_flag="🇬🇧" ), SIG( name="Toilets", comment_names=[], description="Toilets on the Air", ref_regex=r"T\-[0-9]{2}", icon="fa-toilet", region_flag="🏴‍☠️" ), ] # Modes. Note "DIGI" and "DIGITAL" are also supported but are normalised into "DATA". CW_MODES = ["CW"] PHONE_MODES = [ "PHONE", "SSB", "AM", "FM", "DV" ] DATA_MODES = [ "DATA", "FT8", "FT4", "RTTY", "SSTV", "JS8", "HELL", "PSK", "FSK", "OLIVIA", "PKT", "MSK144", ] ALL_MODES = CW_MODES + PHONE_MODES + DATA_MODES MODE_TYPES = ["CW", "PHONE", "DATA"] # Mode aliases. Sometimes we get spots with a mode described in a different way that is effectively the same as a mode # we already know, or we want to normalise things for consistency. The lookup table for this is here. Incoming spots # that match a key in this table will be converted to the corresponding value, so only the modes above will actually be # present in the spots. MODE_ALIASES = { "USB": "SSB", "LSB": "SSB", "DMR": "DV", "DSTAR": "DV", "C4FM": "DV", "FUSION": "DV", "M17": "DV", "RTT": "RTTY", "BPSK": "PSK", "PSK31": "PSK", "BPSK31": "PSK", "MFSK": "FSK", "MFSK32": "FSK", "DIGI": "DATA", "DIGITAL": "DATA", } # Band definitions BANDS = [ Band(name="2200m", start_freq=135700, end_freq=137800), Band(name="600m", start_freq=472000, end_freq=479000), Band(name="160m", start_freq=1800000, end_freq=2000000, is_ham_hf=True), Band(name="80m", start_freq=3500000, end_freq=4000000, is_ham_hf=True), Band(name="60m", start_freq=5250000, end_freq=5410000, is_ham_hf=True), Band(name="40m", start_freq=7000000, end_freq=7300000, is_ham_hf=True), Band(name="30m", start_freq=10100000, end_freq=10150000, is_ham_hf=True), Band(name="20m", start_freq=14000000, end_freq=14350000, is_ham_hf=True), Band(name="17m", start_freq=18068000, end_freq=18168000, is_ham_hf=True), Band(name="15m", start_freq=21000000, end_freq=21450000, is_ham_hf=True), Band(name="12m", start_freq=24890000, end_freq=24990000, is_ham_hf=True), Band(name="11m", start_freq=26965000, end_freq=27405000), Band(name="10m", start_freq=28000000, end_freq=29700000, is_ham_hf=True), Band(name="6m", start_freq=50000000, end_freq=54000000), Band(name="5m", start_freq=56000000, end_freq=60500000), Band(name="4m", start_freq=70000000, end_freq=70500000), Band(name="2m", start_freq=144000000, end_freq=148000000), Band(name="1.25m", start_freq=219000000, end_freq=225000000), Band(name="70cm", start_freq=420000000, end_freq=450000000), Band(name="23cm", start_freq=1240000000, end_freq=1325000000), Band(name="13cm", start_freq=2300000000, end_freq=2450000000), Band(name="5.8GHz", start_freq=5725000000, end_freq=5850000000), Band(name="10GHz", start_freq=10000000000, end_freq=10500000000), Band(name="24GHz", start_freq=24000000000, end_freq=24050000000), Band(name="47GHz", start_freq=47000000000, end_freq=47200000000), Band(name="76GHz", start_freq=75500000000, end_freq=81500000000), ] UNKNOWN_BAND = Band(name="Unknown", start_freq=0, end_freq=0) # Continents CONTINENTS = ["EU", "NA", "SA", "AS", "AF", "OC", "AN"] # Propagation modes used in VHF/UHF DX cluster comments, e.g. "JN61ESJM56XT". I don't think there's an official list # of these anywhere, but here are some I've seen or seen reference to PROPAGATION_MODES = { "F2": "F2 layer ionospheric", "ES": "Sporadic-E", "TR": "Tropospheric ducting", "TEP": "Trans-Equatorial Propagation", "EME": "Earth-Moon-Earth", "AU": "Aurora", "MS": "Meteor scatter", "RS": "Rain scatter", "AS": "Aircraft scatter", "SAT": "Satellite", }