add controller options to allow multiple routes per controller

This commit is contained in:
Jakob Ketterl 2020-02-23 18:32:37 +01:00
parent 42191f4e77
commit aa9737498a
8 changed files with 24 additions and 25 deletions

View File

@ -3,9 +3,10 @@ from datetime import datetime
class Controller(ABC): class Controller(ABC):
def __init__(self, handler, request): def __init__(self, handler, request, options):
self.handler = handler self.handler = handler
self.request = request self.request = request
self.options = options
def send_response(self, content, code=200, content_type="text/html", last_modified: datetime = None, max_age=None): def send_response(self, content, code=200, content_type="text/html", last_modified: datetime = None, max_age=None):
self.handler.send_response(code) self.handler.send_response(code)
@ -20,6 +21,8 @@ class Controller(ABC):
content = content.encode() content = content.encode()
self.handler.wfile.write(content) self.handler.wfile.write(content)
@abstractmethod
def handle_request(self): def handle_request(self):
pass action = "indexAction"
if "action" in self.options:
action = self.options["action"]
getattr(self, action)()

View File

@ -4,6 +4,6 @@ import json
class ApiController(Controller): class ApiController(Controller):
def handle_request(self): def indexAction(self):
data = json.dumps(FeatureDetector().feature_report()) data = json.dumps(FeatureDetector().feature_report())
self.send_response(data, content_type="application/json") self.send_response(data, content_type="application/json")

View File

@ -35,7 +35,7 @@ class AssetsController(Controller):
except FileNotFoundError: except FileNotFoundError:
self.send_response("file not found", code=404) self.send_response("file not found", code=404)
def handle_request(self): def indexAction(self):
filename = self.request.matches.group(1) filename = self.request.matches.group(1)
self.serve_file(filename) self.serve_file(filename)

View File

@ -4,6 +4,6 @@ import json
class MetricsController(Controller): class MetricsController(Controller):
def handle_request(self): def indexAction(self):
data = json.dumps(Metrics.getSharedInstance().getMetrics()) data = json.dumps(Metrics.getSharedInstance().getMetrics())
self.send_response(data, content_type="application/json") self.send_response(data, content_type="application/json")

View File

@ -8,7 +8,7 @@ import json
class StatusController(Controller): class StatusController(Controller):
def handle_request(self): def indexAction(self):
pm = PropertyManager.getSharedInstance() pm = PropertyManager.getSharedInstance()
# TODO keys that have been left out since they are no longer simple strings: sdr_hw, bands, antenna # TODO keys that have been left out since they are no longer simple strings: sdr_hw, bands, antenna
vars = { vars = {
@ -25,8 +25,6 @@ class StatusController(Controller):
} }
self.send_response("\n".join(["{key}={value}".format(key=key, value=value) for key, value in vars.items()])) self.send_response("\n".join(["{key}={value}".format(key=key, value=value) for key, value in vars.items()]))
class StatusJsonController(Controller):
def getProfileStats(self, profile): def getProfileStats(self, profile):
return { return {
"name": profile["name"], "name": profile["name"],
@ -43,7 +41,7 @@ class StatusJsonController(Controller):
} }
return stats return stats
def handle_request(self): def jsonAction(self):
pm = PropertyManager.getSharedInstance() pm = PropertyManager.getSharedInstance()
gps = pm["receiver_gps"] gps = pm["receiver_gps"]

View File

@ -25,16 +25,16 @@ class WebpageController(TemplateController, metaclass=ABCMeta):
class IndexController(WebpageController): class IndexController(WebpageController):
def handle_request(self): def indexAction(self):
self.serve_template("index.html", **self.template_variables()) self.serve_template("index.html", **self.template_variables())
class MapController(WebpageController): class MapController(WebpageController):
def handle_request(self): def indexAction(self):
# TODO check if we have a google maps api key first? # TODO check if we have a google maps api key first?
self.serve_template("map.html", **self.template_variables()) self.serve_template("map.html", **self.template_variables())
class FeatureController(WebpageController): class FeatureController(WebpageController):
def handle_request(self): def indexAction(self):
self.serve_template("features.html", **self.template_variables()) self.serve_template("features.html", **self.template_variables())

View File

@ -4,7 +4,7 @@ from owrx.connection import WebSocketMessageHandler
class WebSocketController(Controller): class WebSocketController(Controller):
def handle_request(self): def indexAction(self):
conn = WebSocketConnection(self.handler, WebSocketMessageHandler()) conn = WebSocketConnection(self.handler, WebSocketMessageHandler())
# enter read loop # enter read loop
conn.handle() conn.handle()

View File

@ -1,7 +1,4 @@
from owrx.controllers.status import ( from owrx.controllers.status import StatusController
StatusJsonController,
StatusController
)
from owrx.controllers.template import ( from owrx.controllers.template import (
IndexController, IndexController,
MapController, MapController,
@ -48,8 +45,9 @@ class Request(object):
class Route(ABC): class Route(ABC):
def __init__(self, controller): def __init__(self, controller, controllerOptions = None):
self.controller = controller self.controller = controller
self.controllerOptions = controllerOptions if controllerOptions is not None else {}
@abstractmethod @abstractmethod
def matches(self, request): def matches(self, request):
@ -57,18 +55,18 @@ class Route(ABC):
class StaticRoute(Route): class StaticRoute(Route):
def __init__(self, route, controller): def __init__(self, route, controller, controllerOptions = None):
self.route = route self.route = route
super().__init__(controller) super().__init__(controller, controllerOptions)
def matches(self, request): def matches(self, request):
return request.path == self.route return request.path == self.route
class RegexRoute(Route): class RegexRoute(Route):
def __init__(self, regex, controller): def __init__(self, regex, controller, controllerOptions = None):
self.regex = re.compile(regex) self.regex = re.compile(regex)
super().__init__(controller) super().__init__(controller, controllerOptions)
def matches(self, request): def matches(self, request):
matches = self.regex.match(request.path) matches = self.regex.match(request.path)
@ -82,7 +80,7 @@ class Router(object):
self.routes = [ self.routes = [
StaticRoute("/", IndexController), StaticRoute("/", IndexController),
StaticRoute("/status", StatusController), StaticRoute("/status", StatusController),
StaticRoute("/status.json", StatusJsonController), StaticRoute("/status.json", StatusController, {"action": "jsonAction"}),
RegexRoute("/static/(.+)", OwrxAssetsController), RegexRoute("/static/(.+)", OwrxAssetsController),
RegexRoute("/aprs-symbols/(.+)", AprsSymbolsController), RegexRoute("/aprs-symbols/(.+)", AprsSymbolsController),
StaticRoute("/ws/", WebSocketController), StaticRoute("/ws/", WebSocketController),
@ -106,6 +104,6 @@ class Router(object):
route = self.find_route(request) route = self.find_route(request)
if route is not None: if route is not None:
controller = route.controller controller = route.controller
controller(handler, request).handle_request() controller(handler, request, route.controllerOptions).handle_request()
else: else:
handler.send_error(404, "Not Found", "The page you requested could not be found.") handler.send_error(404, "Not Found", "The page you requested could not be found.")