Added frequency to SSTV filenames, refactored storage code, etc.
This commit is contained in:
parent
5d97d68f60
commit
e1300f76d8
|
|
@ -31,3 +31,9 @@ td {
|
|||
img {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.file-title {
|
||||
text-align: center;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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 +
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
30
owrx/sstv.py
30
owrx/sstv.py
|
|
@ -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 ' [...]'
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue