send updated bookmarks to clients on the fly

This commit is contained in:
Jakob Ketterl 2021-03-25 15:25:15 +01:00
parent 20cd3f6efe
commit 287a04be94
3 changed files with 57 additions and 3 deletions

View File

@ -31,6 +31,23 @@ class Bookmark(object):
} }
class BookmakrSubscription(object):
def __init__(self, subscriptee, range, subscriber: callable):
self.subscriptee = subscriptee
self.range = range
self.subscriber = subscriber
def inRange(self, bookmark: Bookmark):
low, high = self.range
return low <= bookmark.getFrequency() <= high
def call(self, *args, **kwargs):
self.subscriber(*args, **kwargs)
def cancel(self):
self.subscriptee.unsubscribe(self)
class Bookmarks(object): class Bookmarks(object):
sharedInstance = None sharedInstance = None
@ -43,6 +60,7 @@ class Bookmarks(object):
def __init__(self): def __init__(self):
self.file_modified = None self.file_modified = None
self.bookmarks = [] self.bookmarks = []
self.subscriptions = []
self.fileList = [Bookmarks._getBookmarksFile(), "/etc/openwebrx/bookmarks.json", "bookmarks.json"] self.fileList = [Bookmarks._getBookmarksFile(), "/etc/openwebrx/bookmarks.json", "bookmarks.json"]
def _refresh(self): def _refresh(self):
@ -101,8 +119,26 @@ class Bookmarks(object):
def addBookmark(self, bookmark: Bookmark): def addBookmark(self, bookmark: Bookmark):
self.bookmarks.append(bookmark) self.bookmarks.append(bookmark)
self.notifySubscriptions(bookmark)
def removeBookmark(self, bookmark: Bookmark): def removeBookmark(self, bookmark: Bookmark):
if bookmark not in self.bookmarks: if bookmark not in self.bookmarks:
return return
self.bookmarks.remove(bookmark) self.bookmarks.remove(bookmark)
self.notifySubscriptions(bookmark)
def notifySubscriptions(self, bookmark: Bookmark):
for sub in self.subscriptions:
if sub.inRange(bookmark):
try:
sub.call()
except Exception:
logger.exception("Error while calling bookmark subscriptions")
def subscribe(self, range, callback):
self.subscriptions.append(BookmakrSubscription(self, range, callback))
def unsubscribe(self, subscriptions: BookmakrSubscription):
if subscriptions not in self.subscriptions:
return
self.subscriptions.remove(subscriptions)

View File

@ -141,6 +141,7 @@ class OpenWebRxReceiverClient(OpenWebRxClient, SdrSourceEventClient):
self.dsp = None self.dsp = None
self.sdr = None self.sdr = None
self.configSubs = [] self.configSubs = []
self.bookmarkSub = None
self.connectionProperties = {} self.connectionProperties = {}
try: try:
@ -190,7 +191,7 @@ class OpenWebRxReceiverClient(OpenWebRxClient, SdrSourceEventClient):
config["sdr_id"] = self.sdr.getId() config["sdr_id"] = self.sdr.getId()
self.write_config(config) self.write_config(config)
def sendBookmarks(changes=None): def sendBookmarks(*args):
cf = configProps["center_freq"] cf = configProps["center_freq"]
srh = configProps["samp_rate"] / 2 srh = configProps["samp_rate"] / 2
frequencyRange = (cf - srh, cf + srh) frequencyRange = (cf - srh, cf + srh)
@ -198,8 +199,17 @@ class OpenWebRxReceiverClient(OpenWebRxClient, SdrSourceEventClient):
bookmarks = [b.__dict__() for b in Bookmarks.getSharedInstance().getBookmarks(frequencyRange)] bookmarks = [b.__dict__() for b in Bookmarks.getSharedInstance().getBookmarks(frequencyRange)]
self.write_bookmarks(bookmarks) self.write_bookmarks(bookmarks)
def updateBookmarkSubscription(*args):
if self.bookmarkSub is not None:
self.bookmarkSub.cancel()
cf = configProps["center_freq"]
srh = configProps["samp_rate"] / 2
frequencyRange = (cf - srh, cf + srh)
self.bookmarkSub = Bookmarks.getSharedInstance().subscribe(frequencyRange, sendBookmarks)
sendBookmarks()
self.configSubs.append(configProps.wire(sendConfig)) self.configSubs.append(configProps.wire(sendConfig))
self.configSubs.append(stack.filter("center_freq", "samp_rate").wire(sendBookmarks)) self.configSubs.append(stack.filter("center_freq", "samp_rate").wire(updateBookmarkSubscription))
# send initial config # send initial config
sendConfig() sendConfig()
@ -332,6 +342,8 @@ class OpenWebRxReceiverClient(OpenWebRxClient, SdrSourceEventClient):
ClientRegistry.getSharedInstance().removeClient(self) ClientRegistry.getSharedInstance().removeClient(self)
while self.configSubs: while self.configSubs:
self.configSubs.pop().cancel() self.configSubs.pop().cancel()
if self.bookmarkSub is not None:
self.bookmarkSub.cancel()
super().close() super().close()
def stopDsp(self): def stopDsp(self):

View File

@ -88,6 +88,8 @@ class BookmarksController(AuthorizationMixin, WebpageController):
value = int(value) value = int(value)
setattr(bookmark, key, value) setattr(bookmark, key, value)
Bookmarks.getSharedInstance().store() Bookmarks.getSharedInstance().store()
# TODO this should not be called explicitly... bookmarks don't have any event capability right now, though
Bookmarks.getSharedInstance().notifySubscriptions(bookmark)
self.send_response("{}", content_type="application/json", code=200) self.send_response("{}", content_type="application/json", code=200)
except json.JSONDecodeError: except json.JSONDecodeError:
self.send_response("{}", content_type="application/json", code=400) self.send_response("{}", content_type="application/json", code=400)
@ -97,7 +99,11 @@ class BookmarksController(AuthorizationMixin, WebpageController):
try: try:
data = json.loads(self.get_body()) data = json.loads(self.get_body())
# sanitize # sanitize
data = {k: data[k] for k in ["name", "frequency", "modulation"]} data = {
"name": data["name"],
"frequency": int(data["frequency"]),
"modulation": data["modulation"],
}
bookmark = Bookmark(data) bookmark = Bookmark(data)
bookmarks.addBookmark(bookmark) bookmarks.addBookmark(bookmark)