diff --git a/htdocs/css/files.css b/htdocs/css/files.css new file mode 100644 index 00000000..b9b77d78 --- /dev/null +++ b/htdocs/css/files.css @@ -0,0 +1,29 @@ +@import url("openwebrx-header.css"); +@import url("openwebrx-globals.css"); + +html, body { + height: unset; +} + +body { + margin-bottom: 5rem; +} + +hr { + background: #444; +} + +h1 { + margin: 1em 0; + text-align: center; +} + +table { + border-collapse: separate; + border-spacing: 15px; +} + +td { + text-align: center; + border: 3px dotted; +} diff --git a/htdocs/css/openwebrx.css b/htdocs/css/openwebrx.css index 6fb6e2ed..a55a109d 100644 --- a/htdocs/css/openwebrx.css +++ b/htdocs/css/openwebrx.css @@ -158,8 +158,8 @@ input[type=range]:disabled { { height: 100%; position: relative; - display: flex; - flex-direction: column; + display: flex; + flex-direction: column; } #openwebrx-scale-container diff --git a/htdocs/files.html b/htdocs/files.html new file mode 100644 index 00000000..0125d0f4 --- /dev/null +++ b/htdocs/files.html @@ -0,0 +1,18 @@ + + OpenWebRX+ Received Files + + + + + + + + + ${header} +
+

OpenWebRX+ Received Files

+ + ${rows} +
+
+ diff --git a/htdocs/files.js b/htdocs/files.js new file mode 100644 index 00000000..a663729f --- /dev/null +++ b/htdocs/files.js @@ -0,0 +1,17 @@ +function saveCanvas(canvas, name) { + var a = document.createElement('a'); + + canvas.toBlob(function(blob) { + a.href = window.URL.createObjectURL(blob); + }, 'image/png'); + + a.style = 'display: none'; + a.download = name; + document.body.appendChild(a); + a.click(); + + setTimeout(function() { + document.body.removeChild(a); + window.URL.revokeObjectURL(a.href); + }, 0); +} diff --git a/htdocs/openwebrx.js b/htdocs/openwebrx.js index 825a2a85..aa23ffce 100644 --- a/htdocs/openwebrx.js +++ b/htdocs/openwebrx.js @@ -93,6 +93,24 @@ function toggleRecording() { } +function saveCanvas(canvas, name) { + var a = document.createElement('a'); + + canvas.toBlob(function(blob) { + a.href = window.URL.createObjectURL(blob); + }, 'image/png'); + + a.style = 'display: none'; + a.download = name; + document.body.appendChild(a); + a.click(); + + setTimeout(function() { + document.body.removeChild(a); + window.URL.revokeObjectURL(a.href); + }, 0); +} + function zoomInOneStep() { zoom_set(zoom_level + 1); } diff --git a/owrx/controllers/file.py b/owrx/controllers/file.py new file mode 100644 index 00000000..0589693d --- /dev/null +++ b/owrx/controllers/file.py @@ -0,0 +1,62 @@ +from owrx.controllers.template import WebpageController +from owrx.controllers.assets import ModificationAwareController +from owrx.breadcrumb import Breadcrumb, BreadcrumbItem, BreadcrumbMixin +from owrx.controllers.settings import SettingsBreadcrumb +from owrx.config.core import CoreConfig + +from datetime import datetime, timezone +import mimetypes +import os +import re + +class FileController(ModificationAwareController): + def getModified(self, file): + return datetime.fromtimestamp(os.path.getmtime(file), timezone.utc) + + def openFile(self, file): + return open(file, "rb") + + def serve_file(self, file, content_type=None): + try: + modified = self.getModified(file) + + if not self.wasModified(file): + self.send_response("", code=304) + return + + f = self.openFile(file) + data = f.read() + f.close() + + if content_type is None: + (content_type, encoding) = mimetypes.guess_type(file) + self.send_response(data, content_type=content_type, last_modified=modified, max_age=3600) + except FileNotFoundError: + self.send_response("file '%s' not found" % file, code=404) + + def indexAction(self): + filename = self.request.matches.group(1) + self.serve_file("/tmp/" + filename) + + +class FilesController(WebpageController): + def template_variables(self): + files = [f for f in os.listdir('/tmp') if re.match(r'SSTV-[0-9]+-[0-9]+\.bmp', f)] + rows = "" + + for i in range(len(files)): + # Start a row + if i % 3 == 0: + rows += '\n' + # Print out individual tiles + rows += ('' % (files[i], files[i])) + ('

%s

\n' % files[i]) + # Finish a row + if i % 3 == 2: + rows += '\n' + + variables = super().template_variables() + variables["rows"] = rows + return variables + + def indexAction(self): + self.serve_template("files.html", **self.template_variables()) diff --git a/owrx/http.py b/owrx/http.py index 347bacff..ebb35b70 100644 --- a/owrx/http.py +++ b/owrx/http.py @@ -1,6 +1,7 @@ from owrx.controllers.status import StatusController from owrx.controllers.template import IndexController, MapController, PolicyController from owrx.controllers.feature import FeatureController +from owrx.controllers.file import FilesController, FileController from owrx.controllers.assets import OwrxAssetsController, AprsSymbolsController, CompiledAssetsController from owrx.controllers.websocket import WebSocketController from owrx.controllers.api import ApiController @@ -96,6 +97,8 @@ class Router(object): StaticRoute("/map", MapController), StaticRoute("/policy", PolicyController), StaticRoute("/features", FeatureController), + StaticRoute("/files", FilesController), + RegexRoute("^/files/(SSTV-[0-9]+-[0-9]+\.bmp)$", FileController), StaticRoute("/api/features", ApiController), StaticRoute("/metrics", MetricsController, options={"action": "prometheusAction"}), StaticRoute("/metrics.json", MetricsController),