Added frequency to SSTV filenames, refactored storage code, etc.

This commit is contained in:
Marat Fayzullin 2023-02-28 14:38:24 -05:00
parent 5d97d68f60
commit e1300f76d8
6 changed files with 40 additions and 20 deletions

View File

@ -31,3 +31,9 @@ td {
img {
width: 100%;
}
.file-title {
text-align: center;
font-size: 80%;
}

View File

@ -301,8 +301,9 @@ SstvMessagePanel.prototype.pushMessage = function(msg) {
// $b.scrollTop($b[0].scrollHeight);
}
else if(msg.width>0 && msg.height>0 && !msg.hasOwnProperty('line')) {
var f = msg.frequency>0? ' at ' + Math.floor(msg.frequency/1000) + 'kHz' : '';
var h = '<div>' + msg.timestamp + ' ' + msg.width + 'x' + msg.height +
' ' + msg.sstvMode + '</div>';
' ' + msg.sstvMode + f + '</div>';
var c = '<div onclick="saveCanvas(\'' + msg.filename + '\');">' +
'<canvas class="frame" id="' + msg.filename +
'" width="' + msg.width + '" height="' + msg.height +

View File

@ -4,7 +4,7 @@ from owrx.storage import Storage
class FileController(AssetsController):
def getFilePath(self, file):
return Storage().getStoredFilePath(file)
return Storage().getFilePath(file)
class FilesController(WebpageController):
@ -20,7 +20,7 @@ class FilesController(WebpageController):
rows += ('<td class="file-tile">' +
('<a href="/files/%s" download="%s">' % (files[i], files[i])) +
('<img src="/files/%s" download="%s">' % (files[i], files[i])) +
('<p align="center">%s</p>' % files[i]) +
('<p class="file-title">%s</p>' % files[i]) +
'</a></td>\n')
# Finish a row
if i % 3 == 2:

View File

@ -23,6 +23,7 @@ from owrx.controllers.session import SessionController
from owrx.controllers.profile import ProfileController
from owrx.controllers.imageupload import ImageUploadController
from owrx.controllers.robots import RobotsController
from owrx.storage import Storage
from http.server import BaseHTTPRequestHandler
from urllib.parse import urlparse, parse_qs
import re
@ -98,7 +99,7 @@ class Router(object):
StaticRoute("/policy", PolicyController),
StaticRoute("/features", FeatureController),
StaticRoute("/files", FilesController),
RegexRoute("^/files/(SSTV-[0-9]+-[0-9]+\.bmp)$", FileController),
RegexRoute("^/files/(%s)$" % Storage().getNamePattern(), FileController),
StaticRoute("/api/features", ApiController),
StaticRoute("/metrics", MetricsController, options={"action": "prometheusAction"}),
StaticRoute("/metrics.json", MetricsController),

View File

@ -17,7 +17,7 @@ modeNames = {
44: "Martin 1",
56: "Scottie 2",
60: "Scottie 1",
76: "Scottie DX",
75: "Scottie DX",
# Unsupported modes
0: "Robot 12",
@ -58,13 +58,14 @@ modeNames = {
class SstvParser(ThreadModule):
def __init__(self, service: bool = False):
self.service = service
self.file = None
self.data = bytearray(b'')
self.width = 0
self.height = 0
self.line = 0
self.mode = 0
self.service = service
self.frequency = 0
self.file = None
self.data = bytearray(b'')
self.width = 0
self.height = 0
self.line = 0
self.mode = 0
super().__init__()
def __del__(self):
@ -92,7 +93,7 @@ class SstvParser(ThreadModule):
def newFile(self, fileName):
self.closeFile()
try:
self.fileName = Storage().getStoredFilePath(fileName + ".bmp")
self.fileName = Storage().getFilePath(fileName + ".bmp")
logger.debug("Opening bitmap file '%s'..." % self.fileName)
self.file = open(self.fileName, "wb")
except Exception:
@ -111,6 +112,9 @@ class SstvParser(ThreadModule):
def getOutputFormat(self) -> Format:
return Format.CHAR
def setDialFrequency(self, frequency: int) -> None:
self.frequency = frequency
def run(self):
# Run while there is input data
while self.doRun:
@ -141,9 +145,10 @@ class SstvParser(ThreadModule):
self.mode = self.data[6]
self.line = 0
# Find mode name and time
modeName = modeNames.get(self.mode) if self.mode in modeNames else "Unknown Mode"
modeName = modeNames.get(self.mode) if self.mode in modeNames else "Unknown Mode %d" % self.mode
timeStamp = datetime.utcnow().strftime("%H:%M:%S")
fileName = Storage().makeStoredFileName("SSTV-{0}")
fileName = Storage().makeFileName("SSTV-{0}", self.frequency)
logger.debug("Receiving %dx%d %s frame as '%s'." % (self.width, self.height, modeName, fileName))
# If running as a service...
if self.service:
# Create a new image file and write BMP header
@ -158,7 +163,8 @@ class SstvParser(ThreadModule):
"height": self.height,
"sstvMode": modeName,
"timestamp": timeStamp,
"filename": fileName
"filename": fileName,
"frequency": self.frequency
}
# Parse debug messages enclosed in ' [...]'

View File

@ -11,16 +11,22 @@ logger = logging.getLogger(__name__)
class Storage(object):
def __init__(self):
self.filePattern = r'[A-Z]+-[0-9]+-[0-9]+\.bmp'
self.filePattern = r'[A-Z]+-[0-9]+-[0-9]+(-[0-9]+)?\.bmp'
# Get file name pattern
def getNamePattern(self):
return self.filePattern
# Create stored file name by inserting current UTC date
# and time into the pattern spot designated with "{0}"
def makeStoredFileName(self, pattern):
return pattern.format(datetime.utcnow().strftime('%y%m%d-%H%M%S'))
def makeFileName(self, pattern: str = '{0}', frequency: int = 0):
d = datetime.utcnow().strftime('%y%m%d-%H%M%S')
f = ('-%d' % (frequency // 1000)) if frequency>0 else ''
return pattern.format(d + f)
# Get complete path to a stored file from its filename by
# adding folder name
def getStoredFilePath(self, filename):
def getFilePath(self, filename: str):
return os.path.join(CoreConfig().get_temporary_directory(), filename)
# Get list of stored files, sorted in reverse alphabetic order