Files
spothole/core/utils.py
T

79 lines
2.9 KiB
Python

import logging
import simplejson
from pyhamtools.frequency import freq_to_band
from core.constants import UNKNOWN_BAND, BANDS, CW_MODES, PHONE_MODES, DATA_MODES, MODE_ALIASES, ALL_MODES
from core.data_store import DATA_STORE
def safe_json_dumps(obj):
"""Safe version of json.dumps that also converts objects to dicts so they can be output, and ignores NaN floats
which are invalid in JSON."""
return simplejson.dumps(obj, ensure_ascii=False, ignore_nan=True, default=lambda o: o.__dict__)
def infer_mode_from_comment(comment):
"""Infer a mode from the comment"""
for mode in ALL_MODES:
if mode in comment.upper():
return mode
for mode in MODE_ALIASES.keys():
if mode in comment.upper():
return MODE_ALIASES[mode]
return None
def infer_mode_type_from_mode(mode):
"""Infer a "mode family" from a mode."""
if mode.upper() in CW_MODES:
return "CW"
elif mode.upper() in PHONE_MODES:
return "PHONE"
elif mode.upper() in DATA_MODES:
return "DATA"
else:
if mode.upper() != "OTHER":
logging.warning("Found an unrecognised mode: " + mode + ". Developer should categorise this.")
return None
def infer_band_from_freq(freq):
"""Infer a band from a frequency in Hz"""
for b in BANDS:
if b.start_freq <= freq <= b.end_freq:
return b
return UNKNOWN_BAND
def infer_mode_from_frequency(freq):
"""Infer a mode from the frequency (in Hz) according to the band plan. Just a guess really."""
try:
khz = freq / 1000.0
mode = freq_to_band(khz)["mode"]
# Some additional common digimode ranges in addition to what the 3rd-party freq_to_band function returns.
# This is mostly here just because freq_to_band is very specific about things like FT8 frequencies, and e.g.
# a spot at 7074.5 kHz will be indicated as LSB, even though it's clearly in the FT8 range. Future updates
# might include other common digimode centres of activity here, but this achieves the main goal of keeping
# large numbers of clearly-FT* spots off the list of people filtering out digimodes.
if (7074 <= khz < 7077) or (10136 <= khz < 10139) or (14074 <= khz < 14077) or (18100 <= khz < 18103) or (
21074 <= khz < 21077) or (24915 <= khz < 24918) or (28074 <= khz < 28077):
mode = "FT8"
if (7047.5 <= khz < 7050.5) or (10140 <= khz < 10143) or (14080 <= khz < 14083) or (
18104 <= khz < 18107) or (21140 <= khz < 21143) or (24919 <= khz < 24922) or (28180 <= khz < 28183):
mode = "FT4"
return mode
except KeyError:
return None
def get_flag_for_dxcc(dxcc):
"""Get an emoji flag for a given DXCC entity ID"""
dxcc_data = DATA_STORE.dxcc_data[dxcc] if dxcc in DATA_STORE.dxcc_data else None
return dxcc_data["flag"] if dxcc_data else None