add more inputs, bind to actual data
This commit is contained in:
parent
27c16c3720
commit
039b57d28b
@ -10,11 +10,10 @@ class Section(object):
|
|||||||
self.title = title
|
self.title = title
|
||||||
self.inputs = inputs
|
self.inputs = inputs
|
||||||
|
|
||||||
def render_inputs(self):
|
def render_inputs(self, data):
|
||||||
config = Config.get()
|
return "".join([i.render(data) for i in self.inputs])
|
||||||
return "".join([i.render(config) for i in self.inputs])
|
|
||||||
|
|
||||||
def render(self):
|
def render(self, data):
|
||||||
return """
|
return """
|
||||||
<div class="col-12 settings-section">
|
<div class="col-12 settings-section">
|
||||||
<h3 class="settings-header">
|
<h3 class="settings-header">
|
||||||
@ -23,7 +22,7 @@ class Section(object):
|
|||||||
{inputs}
|
{inputs}
|
||||||
</div>
|
</div>
|
||||||
""".format(
|
""".format(
|
||||||
title=self.title, inputs=self.render_inputs()
|
title=self.title, inputs=self.render_inputs(data)
|
||||||
)
|
)
|
||||||
|
|
||||||
def parse(self, data):
|
def parse(self, data):
|
||||||
@ -44,8 +43,11 @@ class SettingsFormController(AuthorizationMixin, WebpageController, metaclass=AB
|
|||||||
def getTitle(self):
|
def getTitle(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def getData(self):
|
||||||
|
return Config.get()
|
||||||
|
|
||||||
def render_sections(self):
|
def render_sections(self):
|
||||||
sections = "".join(section.render() for section in self.getSections())
|
sections = "".join(section.render(self.getData()) for section in self.getSections())
|
||||||
return """
|
return """
|
||||||
<form class="settings-body" method="POST">
|
<form class="settings-body" method="POST">
|
||||||
{sections}
|
{sections}
|
||||||
@ -78,6 +80,7 @@ class SettingsFormController(AuthorizationMixin, WebpageController, metaclass=AB
|
|||||||
|
|
||||||
def processFormData(self):
|
def processFormData(self):
|
||||||
self.processData(self.parseFormData())
|
self.processData(self.parseFormData())
|
||||||
|
self.send_redirect(self.request.path)
|
||||||
|
|
||||||
def processData(self, data):
|
def processData(self, data):
|
||||||
config = Config.get()
|
config = Config.get()
|
||||||
@ -88,4 +91,3 @@ class SettingsFormController(AuthorizationMixin, WebpageController, metaclass=AB
|
|||||||
else:
|
else:
|
||||||
config[k] = v
|
config[k] = v
|
||||||
config.store()
|
config.store()
|
||||||
self.send_redirect(self.request.path)
|
|
||||||
|
@ -5,6 +5,10 @@ from owrx.source import SdrDeviceDescription, SdrDeviceDescriptionMissing
|
|||||||
from owrx.config import Config
|
from owrx.config import Config
|
||||||
from urllib.parse import quote, unquote
|
from urllib.parse import quote, unquote
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class SdrDeviceListController(AuthorizationMixin, WebpageController):
|
class SdrDeviceListController(AuthorizationMixin, WebpageController):
|
||||||
def header_variables(self):
|
def header_variables(self):
|
||||||
@ -52,6 +56,13 @@ class SdrDeviceController(SettingsFormController):
|
|||||||
super().__init__(handler, request, options)
|
super().__init__(handler, request, options)
|
||||||
self.device = self._get_device()
|
self.device = self._get_device()
|
||||||
|
|
||||||
|
def getData(self):
|
||||||
|
return self.device
|
||||||
|
|
||||||
|
def processData(self, data):
|
||||||
|
# TODO implement storing of data here
|
||||||
|
logger.debug(data)
|
||||||
|
|
||||||
def getSections(self):
|
def getSections(self):
|
||||||
try:
|
try:
|
||||||
description = SdrDeviceDescription.getByType(self.device["type"])
|
description = SdrDeviceDescription.getByType(self.device["type"])
|
||||||
|
@ -139,8 +139,8 @@ class TextAreaInput(Input):
|
|||||||
|
|
||||||
|
|
||||||
class CheckboxInput(Input):
|
class CheckboxInput(Input):
|
||||||
def __init__(self, id, label, checkboxText, infotext=None):
|
def __init__(self, id, label, checkboxText, infotext=None, converter: Converter = None):
|
||||||
super().__init__(id, label, infotext=infotext)
|
super().__init__(id, label, infotext=infotext, converter=converter)
|
||||||
self.checkboxText = checkboxText
|
self.checkboxText = checkboxText
|
||||||
|
|
||||||
def render_input(self, value):
|
def render_input(self, value):
|
||||||
@ -162,7 +162,7 @@ class CheckboxInput(Input):
|
|||||||
return " ".join(["form-check", "form-control-sm"])
|
return " ".join(["form-check", "form-control-sm"])
|
||||||
|
|
||||||
def parse(self, data):
|
def parse(self, data):
|
||||||
return {self.id: self.id in data and data[self.id][0] == "on"}
|
return {self.id: self.converter.convert_from_form(self.id in data and data[self.id][0] == "on")}
|
||||||
|
|
||||||
|
|
||||||
class Option(object):
|
class Option(object):
|
||||||
|
@ -22,15 +22,21 @@ class NullConverter(Converter):
|
|||||||
|
|
||||||
class OptionalConverter(Converter):
|
class OptionalConverter(Converter):
|
||||||
"""
|
"""
|
||||||
Maps None to an empty string, and reverse
|
Transforms a special form value to None
|
||||||
useful for optional fields
|
The default is look for an empty string, but this can be used to adopt to other types.
|
||||||
|
If the default is not found, the actual value is passed to the sub_converter for further transformation.
|
||||||
|
useful for optional fields since None is not stored in the configuration
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(self, sub_converter: Converter = None, defaultFormValue=""):
|
||||||
|
self.sub_converter = NullConverter() if sub_converter is None else sub_converter
|
||||||
|
self.defaultFormValue = defaultFormValue
|
||||||
|
|
||||||
def convert_to_form(self, value):
|
def convert_to_form(self, value):
|
||||||
return "" if value is None else value
|
return self.defaultFormValue if value is None else self.sub_converter.convert_to_form(value)
|
||||||
|
|
||||||
def convert_from_form(self, value):
|
def convert_from_form(self, value):
|
||||||
return value if value else None
|
return None if value == self.defaultFormValue else self.sub_converter.convert_to_form(value)
|
||||||
|
|
||||||
|
|
||||||
class IntConverter(Converter):
|
class IntConverter(Converter):
|
||||||
|
13
owrx/form/soapy.py
Normal file
13
owrx/form/soapy.py
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
from owrx.form import FloatInput
|
||||||
|
|
||||||
|
|
||||||
|
class SoapyGainInput(FloatInput):
|
||||||
|
def __init__(self, id, label, gain_stages):
|
||||||
|
super().__init__(id, label)
|
||||||
|
self.gain_stages = gain_stages
|
||||||
|
|
||||||
|
def render_input(self, value):
|
||||||
|
if not self.gain_stages:
|
||||||
|
return super().render_input(value)
|
||||||
|
# TODO implement input for multiple gain stages here
|
||||||
|
return "soapy gain stages here..."
|
@ -117,6 +117,7 @@ class Router(object):
|
|||||||
),
|
),
|
||||||
StaticRoute("/settings/sdr", SdrDeviceListController),
|
StaticRoute("/settings/sdr", SdrDeviceListController),
|
||||||
RegexRoute("/settings/sdr/(.+)", SdrDeviceController),
|
RegexRoute("/settings/sdr/(.+)", SdrDeviceController),
|
||||||
|
RegexRoute("/settings/sdr/(.+)", SdrDeviceController, method="POST", options={"action": "processFormData"}),
|
||||||
StaticRoute("/settings/bookmarks", BookmarksController),
|
StaticRoute("/settings/bookmarks", BookmarksController),
|
||||||
StaticRoute("/settings/bookmarks", BookmarksController, method="POST", options={"action": "new"}),
|
StaticRoute("/settings/bookmarks", BookmarksController, method="POST", options={"action": "new"}),
|
||||||
RegexRoute("/settings/bookmarks/(.+)", BookmarksController, method="POST", options={"action": "update"}),
|
RegexRoute("/settings/bookmarks/(.+)", BookmarksController, method="POST", options={"action": "update"}),
|
||||||
|
@ -10,7 +10,8 @@ from abc import ABC, abstractmethod
|
|||||||
from owrx.command import CommandMapper
|
from owrx.command import CommandMapper
|
||||||
from owrx.socket import getAvailablePort
|
from owrx.socket import getAvailablePort
|
||||||
from owrx.property import PropertyStack, PropertyLayer
|
from owrx.property import PropertyStack, PropertyLayer
|
||||||
from owrx.form import Input, TextInput, NumberInput, CheckboxInput
|
from owrx.form import Input, TextInput, NumberInput, CheckboxInput, FloatInput
|
||||||
|
from owrx.form.converter import IntConverter, OptionalConverter
|
||||||
from owrx.controllers.settings import Section
|
from owrx.controllers.settings import Section
|
||||||
from typing import List
|
from typing import List
|
||||||
|
|
||||||
@ -375,14 +376,25 @@ class SdrDeviceDescription(object):
|
|||||||
def getInputs(self) -> List[Input]:
|
def getInputs(self) -> List[Input]:
|
||||||
return [
|
return [
|
||||||
TextInput("name", "Device name"),
|
TextInput("name", "Device name"),
|
||||||
NumberInput("ppm", "Frequency correction", append="ppm"),
|
NumberInput(
|
||||||
|
"ppm",
|
||||||
|
"Frequency correction",
|
||||||
|
append="ppm",
|
||||||
|
converter=OptionalConverter(IntConverter(), defaultFormValue="0"),
|
||||||
|
),
|
||||||
CheckboxInput(
|
CheckboxInput(
|
||||||
"always-on",
|
"always-on",
|
||||||
"",
|
"",
|
||||||
checkboxText="Keep device running at all times",
|
checkboxText="Keep device running at all times",
|
||||||
infotext="Prevents shutdown of the device when idle. Useful for devices with unreliable startup."
|
infotext="Prevents shutdown of the device when idle. Useful for devices with unreliable startup.",
|
||||||
),
|
),
|
||||||
CheckboxInput("services", "", "Run services on this device"),
|
CheckboxInput(
|
||||||
|
"services",
|
||||||
|
"",
|
||||||
|
"Run background services on this device",
|
||||||
|
converter=OptionalConverter(defaultFormValue=True),
|
||||||
|
),
|
||||||
|
FloatInput("rf_gain", "Device gain"),
|
||||||
]
|
]
|
||||||
|
|
||||||
def mergeInputs(self, *args):
|
def mergeInputs(self, *args):
|
||||||
|
@ -4,6 +4,7 @@ import socket
|
|||||||
from owrx.command import Flag, Option
|
from owrx.command import Flag, Option
|
||||||
from typing import List
|
from typing import List
|
||||||
from owrx.form import Input, NumberInput
|
from owrx.form import Input, NumberInput
|
||||||
|
from owrx.form.converter import OptionalConverter, IntConverter
|
||||||
|
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
@ -84,6 +85,7 @@ class ConnectorDeviceDescription(SdrDeviceDescription):
|
|||||||
infotext="Activate an rtl_tcp compatible interface on the port number specified.<br />"
|
infotext="Activate an rtl_tcp compatible interface on the port number specified.<br />"
|
||||||
+ "Note: Port is only available on the local machine, not on the network.<br />"
|
+ "Note: Port is only available on the local machine, not on the network.<br />"
|
||||||
+ "Note: IQ data may be degraded by the downsampling process to 8 bits.",
|
+ "Note: IQ data may be degraded by the downsampling process to 8 bits.",
|
||||||
|
converter=OptionalConverter(IntConverter()),
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
@ -20,4 +20,5 @@ class SdrplaySource(SoapyConnectorSource):
|
|||||||
|
|
||||||
|
|
||||||
class SdrplayDeviceDescription(SoapyConnectorDeviceDescription):
|
class SdrplayDeviceDescription(SoapyConnectorDeviceDescription):
|
||||||
pass
|
def getGainStages(self):
|
||||||
|
return ["RFGR", "IFGR"]
|
||||||
|
@ -3,6 +3,7 @@ from owrx.command import Option
|
|||||||
from owrx.source.connector import ConnectorSource, ConnectorDeviceDescription
|
from owrx.source.connector import ConnectorSource, ConnectorDeviceDescription
|
||||||
from typing import List
|
from typing import List
|
||||||
from owrx.form import Input, TextInput
|
from owrx.form import Input, TextInput
|
||||||
|
from owrx.form.soapy import SoapyGainInput
|
||||||
|
|
||||||
|
|
||||||
class SoapyConnectorSource(ConnectorSource, metaclass=ABCMeta):
|
class SoapyConnectorSource(ConnectorSource, metaclass=ABCMeta):
|
||||||
@ -108,5 +109,13 @@ class SoapyConnectorDeviceDescription(ConnectorDeviceDescription):
|
|||||||
"Device Identifier",
|
"Device Identifier",
|
||||||
infotext='SoapySDR device identifier string (example: "serial=123456789")',
|
infotext='SoapySDR device identifier string (example: "serial=123456789")',
|
||||||
),
|
),
|
||||||
|
SoapyGainInput(
|
||||||
|
"rf_gain",
|
||||||
|
"Device Gain",
|
||||||
|
gain_stages=self.getGainStages(),
|
||||||
|
),
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def getGainStages(self):
|
||||||
|
return []
|
||||||
|
Loading…
Reference in New Issue
Block a user