diff --git a/htdocs/clients.html b/htdocs/clients.html
new file mode 100644
index 00000000..37ba9dfd
--- /dev/null
+++ b/htdocs/clients.html
@@ -0,0 +1,21 @@
+
+
+
+ OpenWebRX+ Clients
+
+
+
+
+
+
+
+${header}
+
+
+
Clients
+
+
+ ${clients}
+
+
+
diff --git a/owrx/controllers/clients.py b/owrx/controllers/clients.py
new file mode 100644
index 00000000..c11d2a83
--- /dev/null
+++ b/owrx/controllers/clients.py
@@ -0,0 +1,71 @@
+from owrx.controllers.admin import AuthorizationMixin
+from owrx.controllers.template import WebpageController
+from owrx.breadcrumb import Breadcrumb, BreadcrumbItem, BreadcrumbMixin
+from owrx.websocket import WebSocketConnection
+import re
+
+import logging
+
+logger = logging.getLogger(__name__)
+
+
+class ClientController(AuthorizationMixin, WebpageController):
+ def indexAction(self):
+ self.serve_template("clients.html", **self.template_variables())
+
+ def template_variables(self):
+ variables = super().template_variables()
+ variables["clients"] = self.renderClients()
+ return variables
+
+ @staticmethod
+ def renderClients():
+ return """
+
+
+ | IP Address |
+ SDR Profile |
+ Local Time |
+ Actions |
+
+ {clients}
+
+ """.format(
+ clients="".join(ClientController.renderClient(c) for c in WebSocketConnection.listAll())
+ )
+
+ @staticmethod
+ def renderClient(c):
+ return "| {0} | {1} | {2} {3} | {4} |
".format(
+ ClientController.renderIp(c["ip"]),
+ "banned" if c["ban"] else c["sdr"] + " " + c["band"] if "sdr" in c else "n/a",
+ "until" if c["ban"] else "since",
+ c["ts"].strftime('%H:%M:%S'),
+ ClientController.renderButtons(c)
+ )
+
+ @staticmethod
+ def renderIp(ip):
+ ip = re.sub("^::ffff:", "", ip)
+ return """
+ {1}
+ """.format(ip, ip)
+
+ @staticmethod
+ def renderButtons(c):
+ action = "unban" if c["ban"] else "ban"
+ return """
+
+ """.format(action, c["ip"], action)
+
+ def ban(self):
+ ip = self.request.matches.group(1)
+ logger.info("Banning {0} for {1} minutes".format(ip, 15))
+ WebSocketConnection.banIp(ip, 15)
+ self.send_response("{}", content_type="application/json", code=200)
+
+ def unban(self):
+ ip = self.request.matches.group(1)
+ logger.info("Unbanning {0}".format(ip))
+ WebSocketConnection.unbanIp(ip)
+ self.send_response("{}", content_type="application/json", code=200)
diff --git a/owrx/controllers/settings/__init__.py b/owrx/controllers/settings/__init__.py
index baa97776..e02404cc 100644
--- a/owrx/controllers/settings/__init__.py
+++ b/owrx/controllers/settings/__init__.py
@@ -1,11 +1,11 @@
from owrx.config import Config
from owrx.controllers.admin import AuthorizationMixin
from owrx.controllers.template import WebpageController
+from owrx.controllers.clients import ClientController
from owrx.breadcrumb import Breadcrumb, BreadcrumbItem, BreadcrumbMixin
from owrx.websocket import WebSocketConnection
from abc import ABCMeta, abstractmethod
from urllib.parse import parse_qs
-import re
import logging
@@ -18,57 +18,9 @@ class SettingsController(AuthorizationMixin, WebpageController):
def template_variables(self):
variables = super().template_variables()
- variables["clients"] = self.renderClients()
+ variables["clients"] = ClientController.renderClients()
return variables
- def renderClients(self):
- return """
-
-
- | IP Address |
- SDR Profile |
- Local Time |
- Actions |
-
- {clients}
-
- """.format(
- clients="".join(self.renderClient(c) for c in WebSocketConnection.listAll())
- )
-
- def renderClient(self, c):
- return "| {0} | {1} | {2} {3} | {4} |
".format(
- self.renderIp(c["ip"]),
- "banned" if c["ban"] else c["sdr"] + " " + c["band"] if "sdr" in c else "n/a",
- "until" if c["ban"] else "since",
- c["ts"].strftime('%H:%M:%S'),
- self.renderButtons(c)
- )
-
- def renderIp(self, ip):
- ip = re.sub("^::ffff:", "", ip)
- return """
- {1}
- """.format(ip, ip)
-
- def renderButtons(self, c):
- action = "unban" if c["ban"] else "ban"
- return """
-
- """.format(action, c["ip"], action)
-
- def ban(self):
- ip = self.request.matches.group(1)
- logger.info("Banning {0} for {1} minutes".format(ip, 15))
- WebSocketConnection.banIp(ip, 15)
- self.send_response("{}", content_type="application/json", code=200)
-
- def unban(self):
- ip = self.request.matches.group(1)
- logger.info("Unbanning {0}".format(ip))
- WebSocketConnection.unbanIp(ip)
- self.send_response("{}", content_type="application/json", code=200)
-
class SettingsFormController(AuthorizationMixin, BreadcrumbMixin, WebpageController, metaclass=ABCMeta):
def __init__(self, handler, request, options):
diff --git a/owrx/http.py b/owrx/http.py
index c2ab9ce7..6245f8ee 100644
--- a/owrx/http.py
+++ b/owrx/http.py
@@ -6,6 +6,7 @@ from owrx.controllers.assets import OwrxAssetsController, AprsSymbolsController,
from owrx.controllers.websocket import WebSocketController
from owrx.controllers.api import ApiController
from owrx.controllers.metrics import MetricsController
+from owrx.controllers.clients import ClientController
from owrx.controllers.settings import SettingsController
from owrx.controllers.settings.general import GeneralSettingsController
from owrx.controllers.settings.sdr import (
@@ -106,8 +107,11 @@ class Router(object):
StaticRoute("/metrics", MetricsController, options={"action": "prometheusAction"}),
StaticRoute("/metrics.json", MetricsController),
StaticRoute("/settings", SettingsController),
- RegexRoute("^/settings/ban/(.+)$", SettingsController, options={"action": "ban"}),
- RegexRoute("^/settings/unban/(.+)$", SettingsController, options={"action": "unban"}),
+ StaticRoute("/clients", ClientController),
+ RegexRoute("^/clients/ban/(.+)$", ClientController, options={"action": "ban"}),
+ RegexRoute("^/clients/unban/(.+)$", ClientController, options={"action": "unban"}),
+ RegexRoute("^/settings/ban/(.+)$", ClientController, options={"action": "ban"}),
+ RegexRoute("^/settings/unban/(.+)$", ClientController, options={"action": "unban"}),
StaticRoute("/settings/general", GeneralSettingsController),
StaticRoute(
"/settings/general", GeneralSettingsController, method="POST", options={"action": "processFormData"}