Added underlying modulation to bookmarks, refactored bookmarks.
This commit is contained in:
parent
309274a6af
commit
ce9d93d4f3
|
|
@ -82,7 +82,8 @@ h1 {
|
|||
|
||||
/* col-1 */
|
||||
.bookmarks table [data-editor="name"] {
|
||||
width: 35%;
|
||||
white-space: nowrap;
|
||||
width: 29%;
|
||||
}
|
||||
|
||||
/* col-2 */
|
||||
|
|
@ -101,11 +102,24 @@ h1 {
|
|||
}
|
||||
|
||||
/* col-4 */
|
||||
.bookmarks table [data-editor="description"] {
|
||||
width: 35%;
|
||||
.bookmarks table [data-editor="underlying"] {
|
||||
white-space: nowrap;
|
||||
min-width: 160px;
|
||||
width: 10%;
|
||||
}
|
||||
|
||||
/* col-5 */
|
||||
.bookmarks table [data-editor="description"] {
|
||||
width: 29%;
|
||||
}
|
||||
|
||||
/* col-6 */
|
||||
.bookmarks table [data-editor="scannable"] {
|
||||
width: 2%;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* col-7 */
|
||||
.bookmarks table tr td:last-child, .bookmarks table tr th:last-child {
|
||||
text-align: right;
|
||||
width: 10%;
|
||||
|
|
|
|||
|
|
@ -1515,14 +1515,13 @@ img.openwebrx-mirror-img
|
|||
background-color: #575757;
|
||||
padding: 10px;
|
||||
color: white;
|
||||
position: fixed;
|
||||
font-size: 10pt;
|
||||
border-radius: 15px;
|
||||
-moz-border-radius: 15px;
|
||||
position: fixed;
|
||||
left: 50%;
|
||||
top: 50%;
|
||||
transform: translate(-50%, 0);
|
||||
transform: translate(-50%, -50%);
|
||||
}
|
||||
|
||||
.openwebrx-dialog .form-field {
|
||||
|
|
|
|||
|
|
@ -378,12 +378,16 @@
|
|||
</div>
|
||||
<div class="form-field">
|
||||
<label for="frequency">Frequency:</label>
|
||||
<input type="number" id="frequency" name="frequency">
|
||||
<input type="number" id="frequency" name="frequency" min="1">
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="modulation">Modulation:</label>
|
||||
<select name="modulation" id="modulation"></select>
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="underlying">Underlying:</label>
|
||||
<select name="underlying" id="underlying"></select>
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="name">Description:</label>
|
||||
<input type="text" id="description" name="description">
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ function BookmarkBar() {
|
|||
var me = this;
|
||||
me.modesToScan = ['lsb', 'usb', 'cw', 'am', 'sam', 'nfm'];
|
||||
me.localBookmarks = new BookmarkLocalStorage();
|
||||
me.$container = $("#openwebrx-bookmarks-container");
|
||||
me.$container = $('#openwebrx-bookmarks-container');
|
||||
me.bookmarks = {};
|
||||
|
||||
me.$container.on('click', '.bookmark', function(e){
|
||||
|
|
@ -11,9 +11,7 @@ function BookmarkBar() {
|
|||
var b = $bookmark.data();
|
||||
if (!b || !b.frequency || !b.modulation) return;
|
||||
me.getDemodulator().set_offset_frequency(b.frequency - center_freq);
|
||||
if (b.modulation) {
|
||||
me.getDemodulatorPanel().setMode(b.modulation, b.underlying);
|
||||
}
|
||||
$bookmark.addClass('selected');
|
||||
stopScanner();
|
||||
});
|
||||
|
|
@ -41,7 +39,7 @@ function BookmarkBar() {
|
|||
me.showEditDialog();
|
||||
});
|
||||
|
||||
me.$dialog = $("#openwebrx-dialog-bookmark");
|
||||
me.$dialog = $('#openwebrx-dialog-bookmark');
|
||||
me.$dialog.find('.openwebrx-button[data-action=cancel]').click(function(){
|
||||
me.$dialog.hide();
|
||||
});
|
||||
|
|
@ -108,25 +106,60 @@ BookmarkBar.prototype.render = function(){
|
|||
|
||||
BookmarkBar.prototype.showEditDialog = function(bookmark) {
|
||||
if (!bookmark) {
|
||||
var mode = this.getDemodulator().get_secondary_demod() || this.getDemodulator().get_modulation();
|
||||
var mode1 = this.getDemodulator().get_secondary_demod()
|
||||
var mode2 = this.getDemodulator().get_modulation();
|
||||
// if no secondary demod, use the primary one
|
||||
if (!mode1) { mode1 = mode2; mode2 = ''; }
|
||||
bookmark = {
|
||||
name: "",
|
||||
name: '',
|
||||
frequency: center_freq + this.getDemodulator().get_offset_frequency(),
|
||||
modulation: mode,
|
||||
description: "",
|
||||
scannable : this.modesToScan.indexOf(mode) >= 0
|
||||
modulation: mode1,
|
||||
underlying: mode2,
|
||||
description: '',
|
||||
scannable : this.modesToScan.indexOf(mode1) >= 0
|
||||
}
|
||||
this.sanitizeBookmark(bookmark);
|
||||
}
|
||||
this.$dialog.bookmarkDialog().setValues(bookmark);
|
||||
this.$dialog.show();
|
||||
this.$dialog.find('#name').focus();
|
||||
};
|
||||
|
||||
BookmarkBar.prototype.sanitizeBookmark = function(b) {
|
||||
// must have name, frequency, and modulation
|
||||
if (!b.name || !b.frequency || !b.modulation)
|
||||
return "Must have name, frequency, and modulation.";
|
||||
|
||||
// must have non-empty name
|
||||
b.name = b.name.trim();
|
||||
if (b.name.length <= 0) return "Must have a non-empty name.";
|
||||
|
||||
// must have positive frequency
|
||||
b.frequency = Number(b.frequency);
|
||||
if (b.frequency <= 0) return "Frequency must be positive.";
|
||||
|
||||
// must have valid modulation
|
||||
var mode = Modes.findByModulation(b.modulation);
|
||||
if (!mode) return "Must have valid modulation."
|
||||
|
||||
// check that underlying demodulator is valid
|
||||
if (!b.underlying)
|
||||
b.underlying = '';
|
||||
else if (!mode.underlying)
|
||||
return "Must not have underlying modulation.";
|
||||
else if (mode.underlying.indexOf(b.underlying) < 0)
|
||||
return "Must have valid underlying modulation.";
|
||||
|
||||
return null;
|
||||
};
|
||||
|
||||
BookmarkBar.prototype.storeBookmark = function() {
|
||||
var me = this;
|
||||
var bookmark = this.$dialog.bookmarkDialog().getValues();
|
||||
if (!bookmark) return;
|
||||
bookmark.frequency = Number(bookmark.frequency);
|
||||
|
||||
var error = this.sanitizeBookmark(bookmark);
|
||||
if (error) { alert(error); return; }
|
||||
|
||||
var bookmarks = me.localBookmarks.getBookmarks();
|
||||
|
||||
|
|
|
|||
|
|
@ -9,9 +9,18 @@ $.fn.bookmarkDialog = function() {
|
|||
}).join(''));
|
||||
return this;
|
||||
},
|
||||
setUnderlying: function(modes) {
|
||||
$el.find('#underlying').html('<option value="">None</option>' +
|
||||
modes.filter(function(m) {
|
||||
return m.isAvailable() && !m.underlying && m.type === 'analog';
|
||||
}).map(function(m) {
|
||||
return '<option value="' + m.modulation + '">' + m.name + '</option>';
|
||||
}).join(''));
|
||||
return this;
|
||||
},
|
||||
setValues: function(bookmark) {
|
||||
var $form = $el.find('form');
|
||||
['name', 'frequency', 'modulation', 'description', 'scannable'].forEach(function(key){
|
||||
['name', 'frequency', 'modulation', 'underlying', 'description', 'scannable'].forEach(function(key) {
|
||||
var $input = $form.find('#' + key);
|
||||
if ($input.is(':checkbox')) {
|
||||
$input.prop('checked', bookmark[key]);
|
||||
|
|
@ -25,7 +34,7 @@ $.fn.bookmarkDialog = function() {
|
|||
getValues: function() {
|
||||
var bookmark = {};
|
||||
var valid = true;
|
||||
['name', 'frequency', 'modulation', 'description', 'scannable'].forEach(function(key){
|
||||
['name', 'frequency', 'modulation', 'underlying', 'description', 'scannable'].forEach(function(key) {
|
||||
var $input = $el.find('#' + key);
|
||||
valid = valid && $input[0].checkValidity();
|
||||
bookmark[key] = $input.is(':checkbox')? $input.is(':checked') : $input.val();
|
||||
|
|
@ -38,4 +47,4 @@ $.fn.bookmarkDialog = function() {
|
|||
return bookmark;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,7 +5,9 @@ var Modes = {
|
|||
setModes:function(json){
|
||||
this.modes = json.map(function(m){ return new Mode(m); });
|
||||
this.updatePanels();
|
||||
$('#openwebrx-dialog-bookmark').bookmarkDialog().setModes(this.modes);
|
||||
var bookmarkDialog = $('#openwebrx-dialog-bookmark').bookmarkDialog();
|
||||
bookmarkDialog.setUnderlying(this.modes);
|
||||
bookmarkDialog.setModes(this.modes);
|
||||
},
|
||||
getModes:function(){
|
||||
return this.modes;
|
||||
|
|
|
|||
|
|
@ -177,8 +177,8 @@ ModulationEditor.prototype = new Editor();
|
|||
|
||||
ModulationEditor.prototype.getInputHtml = function() {
|
||||
return '<select class="form-control form-control-sm">' +
|
||||
$.map(this.modes, function(name, modulation) {
|
||||
return '<option value="' + modulation + '">' + name + '</option>';
|
||||
$.map(this.modes, function(mode, name) {
|
||||
return '<option value="' + name + '">' + mode.name + '</option>';
|
||||
}).join('') +
|
||||
'</select>';
|
||||
};
|
||||
|
|
@ -188,6 +188,30 @@ ModulationEditor.prototype.getHtml = function() {
|
|||
return $option.html();
|
||||
};
|
||||
|
||||
function UnderlyingEditor(table) {
|
||||
Editor.call(this, table);
|
||||
this.modes = table.data('modes');
|
||||
}
|
||||
|
||||
UnderlyingEditor.prototype = new Editor();
|
||||
|
||||
UnderlyingEditor.prototype.getInputHtml = function() {
|
||||
return '<select class="form-control form-control-sm">' +
|
||||
'<option value="">None</option>' +
|
||||
$.map(this.modes, function(mode, name) {
|
||||
if (mode.analog && !mode.underlying.length)
|
||||
return '<option value="' + name + '">' + mode.name + '</option>';
|
||||
else
|
||||
return '';
|
||||
}).join('') +
|
||||
'</select>';
|
||||
};
|
||||
|
||||
UnderlyingEditor.prototype.getHtml = function() {
|
||||
var $option = this.input.find('option:selected')
|
||||
return $option? $option.html() : '';
|
||||
};
|
||||
|
||||
function DescriptionEditor(table) {
|
||||
Editor.call(this, table);
|
||||
}
|
||||
|
|
@ -220,11 +244,16 @@ ScannableEditor.prototype.getHtml = function() {
|
|||
return this.getValue()? '✓' : '';
|
||||
};
|
||||
|
||||
var renderModulation = function(m, modes) {
|
||||
return !m? 'None' : m in modes? modes[m].name : m;
|
||||
}
|
||||
|
||||
$.fn.bookmarktable = function() {
|
||||
var editors = {
|
||||
name: NameEditor,
|
||||
frequency: FrequencyEditor,
|
||||
modulation: ModulationEditor,
|
||||
underlying: UnderlyingEditor,
|
||||
description: DescriptionEditor,
|
||||
scannable: ScannableEditor
|
||||
};
|
||||
|
|
@ -255,6 +284,8 @@ $.fn.bookmarktable = function() {
|
|||
}).done(function() {
|
||||
$cell.data('value', editor.getValue());
|
||||
$cell.html(editor.getHtml());
|
||||
}).fail(function() {
|
||||
$cell.html(html);
|
||||
});
|
||||
};
|
||||
|
||||
|
|
@ -337,6 +368,9 @@ $.fn.bookmarktable = function() {
|
|||
data: JSON.stringify([data]),
|
||||
contentType: 'application/json',
|
||||
method: 'POST'
|
||||
}).fail(function(data) {
|
||||
// adding failed, reenable inputs
|
||||
$.map(inputs, function(input, name) { input.disable(false); });
|
||||
}).done(function(data) {
|
||||
if (data.length && data.length === 1 && 'bookmark_id' in data[0]) {
|
||||
row.attr('data-id', data[0]['bookmark_id']);
|
||||
|
|
@ -347,16 +381,16 @@ $.fn.bookmarktable = function() {
|
|||
td.data('value', input.getValue());
|
||||
td.html(input.getHtml());
|
||||
});
|
||||
}
|
||||
|
||||
// remove inputs
|
||||
var $cell = row.find('td').last();
|
||||
var $group = $cell.find('.btn-group');
|
||||
if ($group.length) {
|
||||
$group.remove;
|
||||
$cell.html('<div class="btn btn-sm btn-danger bookmark-delete">delete</div>');
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
$table.append(row);
|
||||
|
|
@ -372,16 +406,13 @@ $.fn.bookmarktable = function() {
|
|||
var modes = $table.data('modes');
|
||||
var $list = $('<table class="table table-sm">');
|
||||
$list.append(bookmarks.map(function(b) {
|
||||
var modulation = b.modulation;
|
||||
if (modulation in modes) {
|
||||
modulation = modes[modulation];
|
||||
}
|
||||
var row = $(
|
||||
'<tr>' +
|
||||
'<td><input class="form-check-input select" type="checkbox"></td>' +
|
||||
'<td><input class="form-check-input select" type="checkbox"> </td>' +
|
||||
'<td>' + b.name + '</td>' +
|
||||
'<td class="frequency">' + renderFrequency(b.frequency) + '</td>' +
|
||||
'<td>' + modulation + '</td>' +
|
||||
'<td>' + renderModulation(b.modulation, modes) + '</td>' +
|
||||
// '<td>' + renderModulation(b.underlying, modes) + '</td>' +
|
||||
'</tr>'
|
||||
);
|
||||
row.data('bookmark', b);
|
||||
|
|
@ -407,31 +438,30 @@ $.fn.bookmarktable = function() {
|
|||
data: JSON.stringify(selected),
|
||||
contentType: 'application/json',
|
||||
method: 'POST'
|
||||
}).fail(function(data) {
|
||||
// import failed
|
||||
$table.find('.emptytext').remove();
|
||||
}).done(function(data) {
|
||||
$table.find('.emptytext').remove();
|
||||
var modes = $table.data('modes');
|
||||
if (data.length && data.length == selected.length) {
|
||||
$table.append(data.map(function(obj, index) {
|
||||
var bookmark = selected[index];
|
||||
var modulation_name = bookmark.modulation;
|
||||
if (modulation_name in modes) {
|
||||
modulation_name = modes[modulation_name];
|
||||
}
|
||||
// provide reasonable default for missing fields
|
||||
if (!('description' in bookmark)) {
|
||||
bookmark.description = '';
|
||||
}
|
||||
if (!('scannable' in bookmark)) {
|
||||
var b = selected[index];
|
||||
// provide reasonable defaults for missing fields
|
||||
if (!('underlying' in b)) b.underlying = '';
|
||||
if (!('description' in b)) b.description = '';
|
||||
if (!('scannable' in b)) {
|
||||
var modesToScan = ['lsb', 'usb', 'cw', 'am', 'sam', 'nfm'];
|
||||
bookmark.scannable = modesToScan.indexOf(bookmark.modulation) >= 0;
|
||||
b.scannable = modesToScan.indexOf(b.modulation) >= 0;
|
||||
}
|
||||
return $(
|
||||
'<tr data-id="' + obj.bookmark_id + '">' +
|
||||
'<td data-editor="name" data-value="' + bookmark.name + '">' + bookmark.name + '</td>' +
|
||||
'<td data-editor="frequency" data-value="' + bookmark.frequency + '" class="frequency">' + renderFrequency(bookmark.frequency) +'</td>' +
|
||||
'<td data-editor="modulation" data-value="' + bookmark.modulation + '">' + modulation_name + '</td>' +
|
||||
'<td data-editor="description" data-value="' + bookmark.description + '">' + bookmark.description + '</td>' +
|
||||
'<td data-editor="scannable" data-value="' + bookmark.scannable + '">' + (bookmark.scannable? '✓':'') + '</td>' +
|
||||
'<td data-editor="name" data-value="' + b.name + '">' + b.name + '</td>' +
|
||||
'<td data-editor="frequency" data-value="' + b.frequency + '" class="frequency">' + renderFrequency(b.frequency) +'</td>' +
|
||||
'<td data-editor="modulation" data-value="' + b.modulation + '">' + renderModulation(b.modulation, modes) + '</td>' +
|
||||
'<td data-editor="underlying" data-value="' + b.underlying + '">' + renderModulation(b.underlying, modes) + '</td>' +
|
||||
'<td data-editor="description" data-value="' + b.description + '">' + b.description + '</td>' +
|
||||
'<td data-editor="scannable" data-value="' + b.scannable + '">' + (b.scannable? '✓':'') + '</td>' +
|
||||
'<td>' +
|
||||
'<button type="button" class="btn btn-sm btn-danger bookmark-delete">delete</button>' +
|
||||
'</td>' +
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ class Bookmark(object):
|
|||
self.name = j["name"]
|
||||
self.frequency = j["frequency"]
|
||||
self.modulation = j["modulation"]
|
||||
self.underlying = j["underlying"] if "underlying" in j else ""
|
||||
self.description = j["description"] if "description" in j else ""
|
||||
self.srcFile = srcFile
|
||||
# By default, only scan modulations that make sense to scan
|
||||
|
|
@ -33,6 +34,9 @@ class Bookmark(object):
|
|||
def getModulation(self):
|
||||
return self.modulation
|
||||
|
||||
def getUnderlying(self):
|
||||
return self.underlying
|
||||
|
||||
def getDescription(self):
|
||||
return self.description
|
||||
|
||||
|
|
@ -47,6 +51,7 @@ class Bookmark(object):
|
|||
"name": self.getName(),
|
||||
"frequency": self.getFrequency(),
|
||||
"modulation": self.getModulation(),
|
||||
"underlying": self.getUnderlying(),
|
||||
"description": self.getDescription(),
|
||||
"scannable": self.isScannable(),
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ from owrx.controllers.template import WebpageController
|
|||
from owrx.controllers.admin import AuthorizationMixin
|
||||
from owrx.controllers.settings import SettingsBreadcrumb
|
||||
from owrx.bookmarks import Bookmark, Bookmarks
|
||||
from owrx.modes import Modes
|
||||
from owrx.modes import Modes, AnalogMode
|
||||
from owrx.breadcrumb import Breadcrumb, BreadcrumbItem, BreadcrumbMixin
|
||||
import json
|
||||
import math
|
||||
|
|
@ -24,7 +24,7 @@ class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController
|
|||
def render_table(self):
|
||||
bookmarks = Bookmarks.getSharedInstance().getEditableBookmarks()
|
||||
emptyText = """
|
||||
<tr class="emptytext"><td colspan="4">
|
||||
<tr class="emptytext"><td colspan="7">
|
||||
No bookmarks in storage. You can add new bookmarks using the buttons below.
|
||||
</td></tr>
|
||||
"""
|
||||
|
|
@ -35,6 +35,7 @@ class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController
|
|||
<th>Name</th>
|
||||
<th class="frequency">Frequency</th>
|
||||
<th>Modulation</th>
|
||||
<th>Underlying</th>
|
||||
<th>Description</th>
|
||||
<th>Scan</th>
|
||||
<th>Actions</th>
|
||||
|
|
@ -43,7 +44,11 @@ class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController
|
|||
</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()}),
|
||||
modes=json.dumps({m.modulation: {
|
||||
"name" : m.name,
|
||||
"analog" : isinstance(m, AnalogMode),
|
||||
"underlying" : m.underlying if hasattr(m, "underlying") else []
|
||||
} for m in Modes.getAvailableModes()}),
|
||||
)
|
||||
|
||||
def render_bookmark(self, bookmark: Bookmark):
|
||||
|
|
@ -65,13 +70,18 @@ class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController
|
|||
suffix = suffixes[exp]
|
||||
return "{num:g} {suffix}Hz".format(num=num, suffix=suffix)
|
||||
|
||||
mode = Modes.findByModulation(bookmark.getModulation())
|
||||
scan = bookmark.isScannable()
|
||||
name1 = bookmark.getModulation()
|
||||
name2 = bookmark.getUnderlying()
|
||||
mode1 = Modes.findByModulation(name1)
|
||||
mode2 = Modes.findByModulation(name2)
|
||||
|
||||
return """
|
||||
<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>
|
||||
<td data-editor="underlying" data-value="{underlying}">{underlying_name}</td>
|
||||
<td data-editor="description" data-value="{description}">{description}</td>
|
||||
<td data-editor="scannable" data-value="{scannable}">{scannable_check}</td>
|
||||
<td>
|
||||
|
|
@ -84,8 +94,10 @@ class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController
|
|||
# TODO render frequency in si units
|
||||
frequency=bookmark.getFrequency(),
|
||||
rendered_frequency=render_frequency(bookmark.getFrequency()),
|
||||
modulation=bookmark.getModulation() if mode is None else mode.modulation,
|
||||
modulation_name=bookmark.getModulation() if mode is None else mode.name,
|
||||
modulation=name1 if mode1 is None else mode1.modulation,
|
||||
underlying=name2 if mode2 is None else mode2.modulation,
|
||||
modulation_name=name1 if mode1 is None else mode1.name,
|
||||
underlying_name="None" if not name2 else name2 if mode2 is None else mode2.name,
|
||||
description=bookmark.getDescription(),
|
||||
scannable="true" if scan else "false",
|
||||
scannable_check="✓" if scan else "",
|
||||
|
|
@ -98,6 +110,45 @@ class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController
|
|||
except StopIteration:
|
||||
return None
|
||||
|
||||
def _sanitizeBookmark(self, data):
|
||||
try:
|
||||
# Must have name, frequency, modulation
|
||||
if "name" not in data or "frequency" not in data or "modulation" not in data:
|
||||
return "Bookmark missing required fields"
|
||||
# Name must not be empty
|
||||
data["name"] = data["name"].strip()
|
||||
if len(data["name"]) == 0:
|
||||
return "Empty bookmark name"
|
||||
# Frequency must be integer
|
||||
if not isinstance(data["frequency"], int):
|
||||
data["frequency"] = int(data["frequency"])
|
||||
# Frequency must be >0
|
||||
if data["frequency"] <= 0:
|
||||
return "Frequency must be positive"
|
||||
# Get both modes
|
||||
mode1 = Modes.findByModulation(data["modulation"]) if "modulation" in data else None
|
||||
mode2 = Modes.findByModulation(data["underlying"]) if "underlying" in data else None
|
||||
# Unknown main mode
|
||||
if mode1 is None:
|
||||
return "Invalid modulation"
|
||||
# No underlying mode
|
||||
if mode2 is None:
|
||||
data["underlying"] = ""
|
||||
else:
|
||||
# Main mode has no underlying mode or underlying mode incorrect
|
||||
if not hasattr(mode1, "underlying") or mode2.modulation not in mode1.underlying:
|
||||
return "Incorrect underlying modulation"
|
||||
# Underlying mode is at the default value
|
||||
#if mode2.modulation == mode1.underlying[0]:
|
||||
# data["underlying"] = ""
|
||||
|
||||
except Exception as e:
|
||||
# Something else went horribly wrong
|
||||
return str(e)
|
||||
|
||||
# Everything ok
|
||||
return None
|
||||
|
||||
def update(self):
|
||||
bookmark_id = int(self.request.matches.group(1))
|
||||
bookmark = self._findBookmark(bookmark_id)
|
||||
|
|
@ -105,18 +156,26 @@ class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController
|
|||
self.send_response("{}", content_type="application/json", code=404)
|
||||
return
|
||||
try:
|
||||
newd = {}
|
||||
data = json.loads(self.get_body().decode("utf-8"))
|
||||
for key in ["name", "frequency", "modulation", "description", "scannable"]:
|
||||
for key in ["name", "frequency", "modulation", "underlying", "description", "scannable"]:
|
||||
if key in data:
|
||||
value = data[key]
|
||||
if key == "frequency":
|
||||
value = int(value)
|
||||
setattr(bookmark, key, value)
|
||||
newd[key] = data[key]
|
||||
elif hasattr(bookmark, key):
|
||||
newd[key] = getattr(bookmark, key)
|
||||
# Make sure everything is correct
|
||||
error = self._sanitizeBookmark(newd)
|
||||
if error is not None:
|
||||
raise ValueError(error)
|
||||
# Update and store bookmark
|
||||
for key in newd:
|
||||
setattr(bookmark, key, newd[key])
|
||||
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)
|
||||
except json.JSONDecodeError:
|
||||
except (json.JSONDecodeError, ValueError) as e:
|
||||
logger.warning("Failed updating bookmark: " + str(e))
|
||||
self.send_response("{}", content_type="application/json", code=400)
|
||||
|
||||
def new(self):
|
||||
|
|
@ -125,12 +184,12 @@ class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController
|
|||
def create(bookmark_data):
|
||||
# sanitize
|
||||
data = {}
|
||||
for key in ["name", "frequency", "modulation", "description", "scannable"]:
|
||||
for key in ["name", "frequency", "modulation", "underlying", "description", "scannable"]:
|
||||
if key in bookmark_data:
|
||||
if key == "frequency":
|
||||
data[key] = int(bookmark_data[key])
|
||||
else:
|
||||
data[key] = bookmark_data[key]
|
||||
error = self._sanitizeBookmark(data)
|
||||
if error is not None:
|
||||
raise ValueError(error)
|
||||
bookmark = Bookmark(data)
|
||||
bookmarks.addBookmark(bookmark)
|
||||
return {"bookmark_id": id(bookmark)}
|
||||
|
|
@ -140,7 +199,8 @@ class BookmarksController(AuthorizationMixin, BreadcrumbMixin, WebpageController
|
|||
result = [create(b) for b in data]
|
||||
bookmarks.store()
|
||||
self.send_response(json.dumps(result), content_type="application/json", code=200)
|
||||
except json.JSONDecodeError:
|
||||
except (json.JSONDecodeError, ValueError) as e:
|
||||
logger.warning("Failed creating bookmark: " + str(e))
|
||||
self.send_response("{}", content_type="application/json", code=400)
|
||||
|
||||
def delete(self):
|
||||
|
|
|
|||
Loading…
Reference in New Issue