add a wfm tau dropdown to the web settings
This commit is contained in:
parent
689cd49694
commit
47ecc26f28
@ -12,7 +12,9 @@ from owrx.form import (
|
|||||||
Option,
|
Option,
|
||||||
ServicesCheckboxInput,
|
ServicesCheckboxInput,
|
||||||
Js8ProfileCheckboxInput,
|
Js8ProfileCheckboxInput,
|
||||||
ReceiverKeysInput,
|
ReceiverKeysConverter,
|
||||||
|
WfmTauValues,
|
||||||
|
WfmTauConverter
|
||||||
)
|
)
|
||||||
from urllib.parse import quote
|
from urllib.parse import quote
|
||||||
import json
|
import json
|
||||||
@ -104,9 +106,10 @@ class GeneralSettingsController(AdminController):
|
|||||||
),
|
),
|
||||||
Section(
|
Section(
|
||||||
"Receiver listings",
|
"Receiver listings",
|
||||||
ReceiverKeysInput(
|
TextInput(
|
||||||
"receiver_keys",
|
"receiver_keys",
|
||||||
"Receiver keys",
|
"Receiver keys",
|
||||||
|
converter=ReceiverKeysConverter(),
|
||||||
infotext="Put the keys you receive on listing sites (e.g. "
|
infotext="Put the keys you receive on listing sites (e.g. "
|
||||||
+ '<a href="https://www.receiverbook.de">Receiverbook</a>) here, one per line',
|
+ '<a href="https://www.receiverbook.de">Receiverbook</a>) here, one per line',
|
||||||
),
|
),
|
||||||
@ -154,6 +157,17 @@ class GeneralSettingsController(AdminController):
|
|||||||
CheckboxInput("digimodes_enable", "", checkboxText="Enable Digimodes"),
|
CheckboxInput("digimodes_enable", "", checkboxText="Enable Digimodes"),
|
||||||
NumberInput("digimodes_fft_size", "Digimodes FFT size", append="bins"),
|
NumberInput("digimodes_fft_size", "Digimodes FFT size", append="bins"),
|
||||||
),
|
),
|
||||||
|
Section(
|
||||||
|
"Wideband FM settings",
|
||||||
|
DropdownInput(
|
||||||
|
"wfm_deemphasis_tau",
|
||||||
|
"Tau setting for WFM (broadcast FM) deemphasis",
|
||||||
|
options=[o.toOption() for o in WfmTauValues],
|
||||||
|
converter=WfmTauConverter(),
|
||||||
|
infotext='See <a href="https://en.wikipedia.org/wiki/FM_broadcasting#Pre-emphasis_and_de-emphasis">'
|
||||||
|
+ "this Wikipedia article for more information</a>",
|
||||||
|
),
|
||||||
|
),
|
||||||
Section(
|
Section(
|
||||||
"Digital voice",
|
"Digital voice",
|
||||||
NumberInput(
|
NumberInput(
|
||||||
|
@ -1,13 +1,36 @@
|
|||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from owrx.modes import Modes
|
from owrx.modes import Modes
|
||||||
from owrx.config import Config
|
from owrx.config import Config
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class Converter(ABC):
|
||||||
|
@abstractmethod
|
||||||
|
def convert_to_form(self, value):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@abstractmethod
|
||||||
|
def convert_from_form(self, value):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
class NullConverter(Converter):
|
||||||
|
def convert_to_form(self, value):
|
||||||
|
return value
|
||||||
|
|
||||||
|
def convert_from_form(self, value):
|
||||||
|
return value
|
||||||
|
|
||||||
|
|
||||||
class Input(ABC):
|
class Input(ABC):
|
||||||
def __init__(self, id, label, infotext=None):
|
def __init__(self, id, label, infotext=None, converter: Converter = None):
|
||||||
self.id = id
|
self.id = id
|
||||||
self.label = label
|
self.label = label
|
||||||
self.infotext = infotext
|
self.infotext = infotext
|
||||||
|
self.converter = self.defaultConverter() if converter is None else converter
|
||||||
|
|
||||||
|
def defaultConverter(self):
|
||||||
|
return NullConverter()
|
||||||
|
|
||||||
def bootstrap_decorate(self, input):
|
def bootstrap_decorate(self, input):
|
||||||
infotext = "<small>{text}</small>".format(text=self.infotext) if self.infotext else ""
|
infotext = "<small>{text}</small>".format(text=self.infotext) if self.infotext else ""
|
||||||
@ -30,17 +53,11 @@ class Input(ABC):
|
|||||||
def render_input(self, value):
|
def render_input(self, value):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def convert_to_form(self, value):
|
|
||||||
return value
|
|
||||||
|
|
||||||
def convert_from_form(self, value):
|
|
||||||
return value
|
|
||||||
|
|
||||||
def render(self, config):
|
def render(self, config):
|
||||||
return self.bootstrap_decorate(self.render_input(self.convert_to_form(config[self.id])))
|
return self.bootstrap_decorate(self.render_input(self.converter.convert_to_form(config[self.id])))
|
||||||
|
|
||||||
def parse(self, data):
|
def parse(self, data):
|
||||||
return {self.id: self.convert_from_form(data[self.id][0])} if self.id in data else {}
|
return {self.id: self.converter.convert_from_form(data[self.id][0])} if self.id in data else {}
|
||||||
|
|
||||||
|
|
||||||
class TextInput(Input):
|
class TextInput(Input):
|
||||||
@ -52,12 +69,23 @@ class TextInput(Input):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class IntConverter(Converter):
|
||||||
|
def convert_to_form(self, value):
|
||||||
|
return str(value)
|
||||||
|
|
||||||
|
def convert_from_form(self, value):
|
||||||
|
return int(value)
|
||||||
|
|
||||||
|
|
||||||
class NumberInput(Input):
|
class NumberInput(Input):
|
||||||
def __init__(self, id, label, infotext=None, append=""):
|
def __init__(self, id, label, infotext=None, append="", converter: Converter = None):
|
||||||
super().__init__(id, label, infotext)
|
super().__init__(id, label, infotext, converter=converter)
|
||||||
self.step = None
|
self.step = None
|
||||||
self.append = append
|
self.append = append
|
||||||
|
|
||||||
|
def defaultConverter(self):
|
||||||
|
return IntConverter()
|
||||||
|
|
||||||
def render_input(self, value):
|
def render_input(self, value):
|
||||||
if self.append:
|
if self.append:
|
||||||
append = """
|
append = """
|
||||||
@ -84,17 +112,22 @@ class NumberInput(Input):
|
|||||||
append=append,
|
append=append,
|
||||||
)
|
)
|
||||||
|
|
||||||
def convert_from_form(self, v):
|
|
||||||
return int(v)
|
class FloatConverter(Converter):
|
||||||
|
def convert_to_form(self, value):
|
||||||
|
return str(value)
|
||||||
|
|
||||||
|
def convert_from_form(self, value):
|
||||||
|
return float(value)
|
||||||
|
|
||||||
|
|
||||||
class FloatInput(NumberInput):
|
class FloatInput(NumberInput):
|
||||||
def __init__(self, id, label, infotext=None):
|
def __init__(self, id, label, infotext=None, converter: Converter = None):
|
||||||
super().__init__(id, label, infotext)
|
super().__init__(id, label, infotext, converter=converter)
|
||||||
self.step = "any"
|
self.step = "any"
|
||||||
|
|
||||||
def convert_from_form(self, v):
|
def defaultConverter(self):
|
||||||
return float(v)
|
return FloatConverter()
|
||||||
|
|
||||||
|
|
||||||
class LocationInput(Input):
|
class LocationInput(Input):
|
||||||
@ -137,7 +170,7 @@ class TextAreaInput(Input):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class ReceiverKeysInput(TextAreaInput):
|
class ReceiverKeysConverter(Converter):
|
||||||
def convert_to_form(self, value):
|
def convert_to_form(self, value):
|
||||||
return "\n".join(value)
|
return "\n".join(value)
|
||||||
|
|
||||||
@ -235,8 +268,8 @@ class Js8ProfileCheckboxInput(MultiCheckboxInput):
|
|||||||
|
|
||||||
|
|
||||||
class DropdownInput(Input):
|
class DropdownInput(Input):
|
||||||
def __init__(self, id, label, options, infotext=None):
|
def __init__(self, id, label, options, infotext=None, converter: Converter = None):
|
||||||
super().__init__(id, label, infotext=infotext)
|
super().__init__(id, label, infotext=infotext, converter=converter)
|
||||||
self.options = options
|
self.options = options
|
||||||
|
|
||||||
def render_input(self, value):
|
def render_input(self, value):
|
||||||
@ -258,3 +291,29 @@ class DropdownInput(Input):
|
|||||||
for o in self.options
|
for o in self.options
|
||||||
]
|
]
|
||||||
return "".join(options)
|
return "".join(options)
|
||||||
|
|
||||||
|
|
||||||
|
class WfmTauValues(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):
|
||||||
|
return Option(self.name, str(self))
|
||||||
|
|
||||||
|
|
||||||
|
class WfmTauConverter(Converter):
|
||||||
|
def convert_to_form(self, value):
|
||||||
|
return WfmTauValues(value * 1e6).name
|
||||||
|
|
||||||
|
def convert_from_form(self, value):
|
||||||
|
return WfmTauValues[value].value / 1e6
|
||||||
|
Loading…
Reference in New Issue
Block a user