openwebrx-clone/owrx/controllers/settings/bookmarks.py

149 lines
5.7 KiB
Python
Raw Permalink Normal View History

from owrx.controllers.template import WebpageController
from owrx.controllers.admin import AuthorizationMixin
from owrx.controllers.settings import SettingsBreadcrumb
2021-02-13 17:35:15 +00:00
from owrx.bookmarks import Bookmark, Bookmarks
2021-02-13 22:53:16 +00:00
from owrx.modes import Modes
from owrx.breadcrumb import Breadcrumb, BreadcrumbItem, BreadcrumbMixin
2021-02-13 23:41:03 +00:00
import json
import math
2021-02-13 23:41:03 +00:00
import logging
logger = logging.getLogger(__name__)
class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController):
def get_breadcrumb(self) -> Breadcrumb:
return SettingsBreadcrumb().append(BreadcrumbItem("Bookmark editor", "settings/bookmarks"))
2021-02-13 17:35:15 +00:00
def template_variables(self):
variables = super().template_variables()
variables["bookmarks"] = self.render_table()
return variables
def render_table(self):
bookmarks = Bookmarks.getSharedInstance().getBookmarks()
emptyText = """
<tr class="emptytext"><td colspan="4">
No bookmarks in storage. You can add new bookmarks using the buttons below.
</td></tr>
"""
2021-02-13 22:53:16 +00:00
2021-02-13 17:35:15 +00:00
return """
<table class="table" data-modes='{modes}'>
2021-02-13 17:35:15 +00:00
<tr>
<th>Name</th>
<th class="frequency">Frequency</th>
<th>Modulation</th>
2021-02-13 17:41:42 +00:00
<th>Actions</th>
2021-02-13 17:35:15 +00:00
</tr>
{bookmarks}
</table>
""".format(
bookmarks="".join(self.render_bookmark(b) for b in bookmarks) if bookmarks else emptyText,
modes=json.dumps({m.modulation: m.name for m in Modes.getAvailableModes()}),
2021-02-13 17:35:15 +00:00
)
2021-02-14 13:48:32 +00:00
def render_bookmark(self, bookmark: Bookmark):
def render_frequency(freq):
suffixes = {
0: "",
3: "k",
6: "M",
9: "G",
12: "T",
}
exp = 0
if freq > 0:
exp = int(math.log10(freq) / 3) * 3
num = freq
suffix = ""
if exp in suffixes:
num = freq / 10 ** exp
suffix = suffixes[exp]
return "{num:g} {suffix}Hz".format(num=num, suffix=suffix)
2021-02-13 22:53:16 +00:00
mode = Modes.findByModulation(bookmark.getModulation())
2021-02-13 17:35:15 +00:00
return """
2021-02-14 13:48:32 +00:00
<tr data-id="{id}">
<td data-editor="name" data-value="{name}">{name}</td>
<td data-editor="frequency" data-value="{frequency}" class="frequency">{rendered_frequency}</td>
<td data-editor="modulation" data-value="{modulation}">{modulation_name}</td>
2021-02-13 17:41:42 +00:00
<td>
<button type="button" class="btn btn-sm btn-danger bookmark-delete">delete</button>
2021-02-13 17:41:42 +00:00
</td>
2021-02-13 17:35:15 +00:00
</tr>
""".format(
2021-02-13 17:41:42 +00:00
id=id(bookmark),
2021-02-13 17:35:15 +00:00
name=bookmark.getName(),
# TODO render frequency in si units
2021-02-13 17:35:15 +00:00
frequency=bookmark.getFrequency(),
rendered_frequency=render_frequency(bookmark.getFrequency()),
2021-02-13 22:53:16 +00:00
modulation=bookmark.getModulation() if mode is None else mode.modulation,
modulation_name=bookmark.getModulation() if mode is None else mode.name,
2021-02-13 17:35:15 +00:00
)
2021-02-13 23:41:03 +00:00
def _findBookmark(self, bookmark_id):
bookmarks = Bookmarks.getSharedInstance()
try:
return next(b for b in bookmarks.getBookmarks() if id(b) == bookmark_id)
except StopIteration:
return None
def update(self):
bookmark_id = int(self.request.matches.group(1))
bookmark = self._findBookmark(bookmark_id)
if bookmark is None:
self.send_response("{}", content_type="application/json", code=404)
return
try:
data = json.loads(self.get_body().decode("utf-8"))
2021-02-13 23:41:03 +00:00
for key in ["name", "frequency", "modulation"]:
if key in data:
value = data[key]
if key == "frequency":
value = int(value)
setattr(bookmark, key, value)
Bookmarks.getSharedInstance().store()
# TODO this should not be called explicitly... bookmarks don't have any event capability right now, though
Bookmarks.getSharedInstance().notifySubscriptions(bookmark)
2021-02-13 23:41:03 +00:00
self.send_response("{}", content_type="application/json", code=200)
except json.JSONDecodeError:
self.send_response("{}", content_type="application/json", code=400)
2021-02-14 15:21:09 +00:00
def new(self):
bookmarks = Bookmarks.getSharedInstance()
def create(bookmark_data):
2021-02-14 15:21:09 +00:00
# sanitize
data = {
"name": bookmark_data["name"],
"frequency": int(bookmark_data["frequency"]),
"modulation": bookmark_data["modulation"],
}
2021-02-14 15:21:09 +00:00
bookmark = Bookmark(data)
bookmarks.addBookmark(bookmark)
return {"bookmark_id": id(bookmark)}
try:
data = json.loads(self.get_body().decode("utf-8"))
result = [create(b) for b in data]
2021-02-14 15:21:09 +00:00
bookmarks.store()
self.send_response(json.dumps(result), content_type="application/json", code=200)
2021-02-14 15:21:09 +00:00
except json.JSONDecodeError:
self.send_response("{}", content_type="application/json", code=400)
2021-02-14 15:51:16 +00:00
def delete(self):
bookmark_id = int(self.request.matches.group(1))
bookmark = self._findBookmark(bookmark_id)
if bookmark is None:
self.send_response("{}", content_type="application/json", code=404)
return
bookmarks = Bookmarks.getSharedInstance()
bookmarks.removeBookmark(bookmark)
bookmarks.store()
self.send_response("{}", content_type="application/json", code=200)
def indexAction(self):
self.serve_template("settings/bookmarks.html", **self.template_variables())