From 37d89c074b6b0c287ce684ea16f069bf248a9aba Mon Sep 17 00:00:00 2001 From: Jakob Ketterl Date: Wed, 3 Mar 2021 00:16:28 +0100 Subject: [PATCH] implement "new device" page (redirects not working yet) --- owrx/controllers/settings/sdr.py | 66 +++++++++++++++++++++++++++++++- owrx/http.py | 11 +++++- owrx/source/__init__.py | 11 ++++++ 3 files changed, 85 insertions(+), 3 deletions(-) diff --git a/owrx/controllers/settings/sdr.py b/owrx/controllers/settings/sdr.py index 88e1d31..4b28c68 100644 --- a/owrx/controllers/settings/sdr.py +++ b/owrx/controllers/settings/sdr.py @@ -4,8 +4,11 @@ from owrx.controllers.settings import SettingsFormController from owrx.source import SdrDeviceDescription, SdrDeviceDescriptionMissing, SdrClientClass from owrx.config import Config from owrx.connection import OpenWebRxReceiverClient +from owrx.controllers.settings import Section from urllib.parse import quote, unquote from owrx.sdr import SdrService +from owrx.form import TextInput, DropdownInput, Option +from owrx.property import PropertyLayer, PropertyStack from abc import ABCMeta @@ -77,13 +80,16 @@ class SdrDeviceListController(AuthorizationMixin, WebpageController): state="Unknown" if source is None else source.getState(), num_profiles=len(config["profiles"]), additional_info=additional_info, - profiles="".join(render_profile(p_id, p) for p_id, p in config["profiles"].items()) + profiles="".join(render_profile(p_id, p) for p_id, p in config["profiles"].items()), ) return """ +
+ Add new device... +
""".format( devices="".join(render_device(key, value) for key, value in Config.get()["sdrs"].items()) ) @@ -109,7 +115,7 @@ class SdrFormController(SettingsFormController, metaclass=ABCMeta): config = Config.get() device_id = unquote(self.request.matches.group(1)) if device_id not in config["sdrs"]: - return None + return None, None return device_id, config["sdrs"][device_id] @@ -167,6 +173,56 @@ class SdrDeviceController(SdrFormController): return self.serve_template("settings/general.html", **self.template_variables()) + def processFormData(self): + if self.device is None: + self.send_response("device not found", code=404) + return + return super().processFormData() + + +class NewSdrDeviceController(SettingsFormController): + def __init__(self, handler, request, options): + super().__init__(handler, request, options) + id_layer = PropertyLayer(id="") + self.data_layer = PropertyLayer(name="", type="", profiles={}) + self.stack = PropertyStack() + self.stack.addLayer(0, id_layer) + self.stack.addLayer(1, self.data_layer) + + def header_variables(self): + variables = super().header_variables() + variables["assets_prefix"] = "../../" + return variables + + def template_variables(self): + variables = super().template_variables() + variables["assets_prefix"] = "../../" + return variables + + def getSections(self): + return [ + Section( + "New device settings", + TextInput("name", "Device name"), + DropdownInput("type", "Device type", [Option(name, name) for name in SdrDeviceDescription.getTypes()]), + TextInput("id", "Device ID"), + ) + ] + + def getTitle(self): + return "New device" + + def getData(self): + return self.stack + + def store(self): + # need to overwrite the existing key in the config since the layering won't capture the changes otherwise + config = Config.get() + sdrs = config["sdrs"] + sdrs[self.stack["id"]] = self.data_layer + config["sdrs"] = sdrs + super().store() + class SdrProfileController(SdrFormController): def __init__(self, handler, request, options): @@ -210,3 +266,9 @@ class SdrProfileController(SdrFormController): self.send_response("profile not found", code=404) return self.serve_template("settings/general.html", **self.template_variables()) + + def processFormData(self): + if self.profile is None: + self.send_response("profile not found", code=404) + return + return super().processFormData() diff --git a/owrx/http.py b/owrx/http.py index 381e070..4c16938 100644 --- a/owrx/http.py +++ b/owrx/http.py @@ -6,7 +6,12 @@ from owrx.controllers.api import ApiController from owrx.controllers.metrics import MetricsController from owrx.controllers.settings import SettingsController from owrx.controllers.settings.general import GeneralSettingsController -from owrx.controllers.settings.sdr import SdrDeviceListController, SdrDeviceController, SdrProfileController +from owrx.controllers.settings.sdr import ( + SdrDeviceListController, + SdrDeviceController, + SdrProfileController, + NewSdrDeviceController, +) from owrx.controllers.settings.reporting import ReportingController from owrx.controllers.settings.backgrounddecoding import BackgroundDecodingController from owrx.controllers.settings.decoding import DecodingSettingsController @@ -116,6 +121,10 @@ class Router(object): "/settings/general", GeneralSettingsController, method="POST", options={"action": "processFormData"} ), StaticRoute("/settings/sdr", SdrDeviceListController), + StaticRoute("/settings/sdr/new", NewSdrDeviceController), + StaticRoute( + "/settings/sdr/new", NewSdrDeviceController, method="POST", options={"action": "processFormData"} + ), RegexRoute("^/settings/sdr/([^/]+)$", SdrDeviceController), RegexRoute( "^/settings/sdr/([^/]+)$", SdrDeviceController, method="POST", options={"action": "processFormData"} diff --git a/owrx/source/__init__.py b/owrx/source/__init__.py index 3992e1b..ca052e0 100644 --- a/owrx/source/__init__.py +++ b/owrx/source/__init__.py @@ -6,6 +6,7 @@ import socket import shlex import time import signal +import pkgutil from abc import ABC, abstractmethod from owrx.command import CommandMapper from owrx.socket import getAvailablePort @@ -476,6 +477,16 @@ class SdrDeviceDescription(object): except (ModuleNotFoundError, AttributeError): raise SdrDeviceDescriptionMissing("Device description for type {} not available".format(sdr_type)) + @staticmethod + def getTypes(): + def has_description(module_name): + try: + SdrDeviceDescription.getByType(module_name) + return True + except SdrDeviceDescriptionMissing: + return False + return [module_name for _, module_name, _ in pkgutil.walk_packages(__path__) if has_description(module_name)] + def getDeviceInputs(self) -> List[Input]: return [TextInput("name", "Device name")] + self.getInputs()