make dropdowns work with enums directly

This commit is contained in:
Jakob Ketterl 2021-02-08 01:16:02 +01:00
parent 5cfacac6c0
commit ce48892173
2 changed files with 31 additions and 36 deletions

View File

@ -14,11 +14,9 @@ from owrx.form import (
Js8ProfileCheckboxInput, Js8ProfileCheckboxInput,
ReceiverKeysConverter, ReceiverKeysConverter,
WfmTauValues, WfmTauValues,
WfmTauConverter,
MultiCheckboxInput, MultiCheckboxInput,
OptionalConverter, OptionalConverter,
AprsBeaconSymbols, AprsBeaconSymbols,
EnumConverter,
AprsAntennaDirections, AprsAntennaDirections,
) )
from urllib.parse import quote from urllib.parse import quote
@ -173,8 +171,7 @@ class GeneralSettingsController(AdminController):
DropdownInput( DropdownInput(
"wfm_deemphasis_tau", "wfm_deemphasis_tau",
"Tau setting for WFM (broadcast FM) deemphasis", "Tau setting for WFM (broadcast FM) deemphasis",
options=[o.toOption() for o in WfmTauValues], WfmTauValues,
converter=WfmTauConverter(),
infotext='See <a href="https://en.wikipedia.org/wiki/FM_broadcasting#Pre-emphasis_and_de-emphasis">' infotext='See <a href="https://en.wikipedia.org/wiki/FM_broadcasting#Pre-emphasis_and_de-emphasis">'
+ "this Wikipedia article</a> for more information", + "this Wikipedia article</a> for more information",
), ),
@ -276,8 +273,7 @@ class GeneralSettingsController(AdminController):
DropdownInput( DropdownInput(
"aprs_igate_symbol", "aprs_igate_symbol",
"APRS beacon symbol", "APRS beacon symbol",
[o.toOption() for o in AprsBeaconSymbols], AprsBeaconSymbols,
converter=EnumConverter(AprsBeaconSymbols),
), ),
TextInput( TextInput(
"aprs_igate_comment", "aprs_igate_comment",
@ -301,8 +297,7 @@ class GeneralSettingsController(AdminController):
DropdownInput( DropdownInput(
"aprs_igate_dir", "aprs_igate_dir",
"Antenna direction", "Antenna direction",
[o.toOption() for o in AprsAntennaDirections], AprsAntennaDirections
converter=EnumConverter(AprsAntennaDirections),
), ),
), ),
Section( Section(

View File

@ -283,8 +283,17 @@ class Js8ProfileCheckboxInput(MultiCheckboxInput):
class DropdownInput(Input): class DropdownInput(Input):
def __init__(self, id, label, options, infotext=None, converter: Converter = None): def __init__(self, id, label, options, infotext=None, converter: Converter = None):
try:
isEnum = issubclass(options, DropdownEnum)
except TypeError:
isEnum = False
if isEnum:
self.options = [o.toOption() for o in options]
if converter is None:
converter = EnumConverter(options)
else:
self.options = options
super().__init__(id, label, infotext=infotext, converter=converter) super().__init__(id, label, infotext=infotext, converter=converter)
self.options = options
def render_input(self, value): def render_input(self, value):
return """ return """
@ -307,20 +316,7 @@ class DropdownInput(Input):
return "".join(options) return "".join(options)
class WfmTauValues(Enum): class DropdownEnum(Enum):
TAU_50_MICRO = (50, "most regions")
TAU_75_MICRO = (75, "Americas and South Korea")
def __new__(cls, *args, **kwargs):
value, description = args
obj = object.__new__(cls)
obj._value_ = value
obj.description = description
return obj
def __str__(self):
return "{}µs ({})".format(self.value, self.description)
def toOption(self): def toOption(self):
return Option(self.name, str(self)) return Option(self.name, str(self))
@ -336,15 +332,22 @@ class EnumConverter(Converter):
return self.enumCls[value].value return self.enumCls[value].value
class WfmTauConverter(Converter): class WfmTauValues(DropdownEnum):
def convert_to_form(self, value): TAU_50_MICRO = (50e-6, "most regions")
return WfmTauValues(value * 1e6).name TAU_75_MICRO = (75e-6, "Americas and South Korea")
def convert_from_form(self, value): def __new__(cls, *args, **kwargs):
return WfmTauValues[value].value / 1e6 value, description = args
obj = object.__new__(cls)
obj._value_ = value
obj.description = description
return obj
def __str__(self):
return "{}µs ({})".format(int(self.value * 1E6), self.description)
class AprsBeaconSymbols(Enum): class AprsBeaconSymbols(DropdownEnum):
BEACON_RECEIVE_ONLY = ("R&", "Receive only IGate") BEACON_RECEIVE_ONLY = ("R&", "Receive only IGate")
BEACON_HF_GATEWAY = ("/&", "HF Gateway") BEACON_HF_GATEWAY = ("/&", "HF Gateway")
BEACON_IGATE_GENERIC = ("I&", "Igate Generic (please use more specific overlay)") BEACON_IGATE_GENERIC = ("I&", "Igate Generic (please use more specific overlay)")
@ -361,13 +364,10 @@ class AprsBeaconSymbols(Enum):
return obj return obj
def __str__(self): def __str__(self):
return self.description return "{description} ({symbol})".format(description=self.description, symbol=self.value)
def toOption(self):
return Option(self.name, "{description} ({symbol})".format(description=str(self), symbol=self.value))
class AprsAntennaDirections(Enum): class AprsAntennaDirections(DropdownEnum):
DIRECTION_OMNI = None DIRECTION_OMNI = None
DIRECTION_N = "N" DIRECTION_N = "N"
DIRECTION_NE = "NE" DIRECTION_NE = "NE"
@ -378,5 +378,5 @@ class AprsAntennaDirections(Enum):
DIRECTION_W = "W" DIRECTION_W = "W"
DIRECTION_NW = "NW" DIRECTION_NW = "NW"
def toOption(self): def __str__(self):
return Option(self.name, "omnidirectional" if self.value is None else self.value) return "omnidirectional" if self.value is None else self.value