Implemented configurable terminal filters

master
Gina Häußge 2013-08-27 21:31:12 +02:00
parent 757294d2e2
commit 46500cea7c
7 changed files with 76 additions and 40 deletions

View File

@ -614,7 +614,8 @@ def getSettings():
"system": {
"actions": s.get(["system", "actions"]),
"events": s.get(["system", "events"])
}
},
"terminalFilters": s.get(["terminalFilters"])
})
@app.route(BASEURL + "settings", methods=["POST"])
@ -682,6 +683,9 @@ def setSettings():
if "temperature" in data.keys():
if "profiles" in data["temperature"].keys(): s.set(["temperature", "profiles"], data["temperature"]["profiles"])
if "terminalFilters" in data.keys():
s.set(["terminalFilters"], data["terminalFilters"])
if "system" in data.keys():
if "actions" in data["system"].keys(): s.set(["system", "actions"], data["system"]["actions"])
if "events" in data["system"].keys(): s.set(["system", "events"], data["system"]["events"])

View File

@ -104,7 +104,11 @@ default_settings = {
"api": {
"enabled": False,
"key": ''.join('%02X' % ord(z) for z in uuid.uuid4().bytes)
}
},
"terminalFilters": [
{ "name": "Suppress M105 requests/responses", "regex": "(Send: M105)|(Recv: ok T:)" },
{ "name": "Suppress M27 requests/responses", "regex": "(Send: M27)|(Recv: SD printing byte)" }
]
}
valid_boolean_trues = ["true", "yes", "y", "1"]

View File

@ -9,7 +9,7 @@ $(function() {
var appearanceViewModel = new AppearanceViewModel(settingsViewModel);
var temperatureViewModel = new TemperatureViewModel(loginStateViewModel, settingsViewModel);
var controlViewModel = new ControlViewModel(loginStateViewModel, settingsViewModel);
var terminalViewModel = new TerminalViewModel(loginStateViewModel);
var terminalViewModel = new TerminalViewModel(loginStateViewModel, settingsViewModel);
var gcodeFilesViewModel = new GcodeFilesViewModel(printerStateViewModel, loginStateViewModel);
var timelapseViewModel = new TimelapseViewModel(loginStateViewModel);
var gcodeViewModel = new GcodeViewModel(loginStateViewModel);

View File

@ -50,6 +50,8 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
self.system_actions = ko.observableArray([]);
self.terminalFilters = ko.observableArray([]);
self.addTemperatureProfile = function() {
self.temperature_profiles.push({name: "New", extruder:0, bed:0});
};
@ -58,6 +60,14 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
self.temperature_profiles.remove(profile);
};
self.addTerminalFilter = function() {
self.terminalFilters.push({name: "New", regex: "(Send: M105)|(Recv: ok T:)"})
};
self.removeTerminalFilter = function(filter) {
self.terminalFilters.remove(filter);
};
self.requestData = function() {
$.ajax({
url: AJAX_BASEURL + "settings",
@ -110,6 +120,8 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
self.temperature_profiles(response.temperature.profiles);
self.system_actions(response.system.actions);
self.terminalFilters(response.terminalFilters);
}
self.saveData = function() {
@ -163,7 +175,8 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
},
"system": {
"actions": self.system_actions()
}
},
"terminalFilters": self.terminalFilters()
}
$.ajax({

View File

@ -1,7 +1,8 @@
function TerminalViewModel(loginStateViewModel) {
function TerminalViewModel(loginStateViewModel, settingsViewModel) {
var self = this;
self.loginState = loginStateViewModel;
self.settings = settingsViewModel;
self.log = [];
@ -16,23 +17,13 @@ function TerminalViewModel(loginStateViewModel) {
self.isLoading = ko.observable(undefined);
self.autoscrollEnabled = ko.observable(true);
self.filterM105 = ko.observable(false);
self.filterM27 = ko.observable(false);
self.filters = ko.observableArray();
self.filters = self.settings.terminalFilters;
self.filterRegex = undefined;
self.regexM105 = /(Send: M105)|(Recv: ok T:)/;
self.regexM27 = /(Send: M27)|(Recv: SD printing byte)/;
self.filterM105.subscribe(function(newValue) {
self.updateOutput();
});
self.filterM27.subscribe(function(newValue) {
self.updateOutput();
});
self.filters.subscribe(function(newValue) {
self.activeFilters = ko.observableArray([]);
self.activeFilters.subscribe(function(e) {
self.updateFilterRegex();
self.updateOutput();
});
@ -69,26 +60,23 @@ function TerminalViewModel(loginStateViewModel) {
self.isLoading(data.flags.loading);
}
self.updateFilterRegex = function() {
var filterRegexStr = self.activeFilters().join("|").trim();
if (filterRegexStr == "") {
self.filterRegex = undefined;
} else {
self.filterRegex = new RegExp(filterRegexStr);
}
console.log("Terminal filter regex: " + filterRegexStr);
}
self.updateOutput = function() {
if (!self.log)
return;
var output = "";
for (var i = 0; i < self.log.length; i++) {
var filters = self.filters();
var filtered = false;
for (var j = 0; j < filters.length; j++) {
var filter = filters[j];
if (self.log[i].match(filter.regex)) {
filtered = true;
break;
}
}
if (filtered) continue;
if (self.filterM105() && self.log[i].match(self.regexM105)) continue;
if (self.filterM27() && self.log[i].match(self.regexM27)) continue;
if (self.filterRegex !== undefined && self.log[i].match(self.filterRegex)) continue;
output += self.log[i] + "\n";
}
@ -127,4 +115,5 @@ function TerminalViewModel(loginStateViewModel) {
self.sendCommand();
}
}
}

View File

@ -511,12 +511,11 @@
<label class="checkbox">
<input type="checkbox" id="terminal-autoscroll" data-bind="checked: autoscrollEnabled"> Autoscroll
</label>
<label class="checkbox">
<input type="checkbox" id="terminal-filterM105" data-bind="checked: filterM105"> Suppress M105 requests/responses
</label>
<label class="checkbox">
<input type="checkbox" id="terminal-filterM27" data-bind="checked: filterM27"> Suppress M27 requests/responses
</label>
<div data-bind="foreach: filters">
<label class="checkbox">
<input type="checkbox" data-bind="attr: { value: regex }, checked: $parent.activeFilters"> <span data-bind="text: name"></span>
</label>
</div>
<div class="input-append" style="display: none;" data-bind="visible: loginState.isUser">
<input type="text" id="terminal-command" data-bind="value: command, event: { keyup: function(d,e) { handleEnter(e); } }, enable: isOperational() && loginState.isUser()">

View File

@ -10,6 +10,7 @@
<li class="active"><a href="#settings_serialConnection" data-toggle="tab">Serial Connection</a></li>
<li><a href="#settings_printerParameters" data-toggle="tab">Printer Parameters</a></li>
<li><a href="#settings_temperature" data-toggle="tab">Temperatures</a></li>
<li><a href="#settings_terminalFilters" data-toggle="tab">Terminal filters</a></li>
<li class="nav-header">Features</li>
<li><a href="#settings_features" data-toggle="tab">Features</a></li>
<li><a href="#settings_webcam" data-toggle="tab">Webcam</a></li>
@ -256,6 +257,32 @@
</div>
</form>
</div>
<div class="tab-pane" id="settings_terminalFilters">
<form class="form-horizontal">
<div class="row-fluid">
<div class="span4"><h4>Name</h4></div>
<div class="span6"><h4>RegExp <small><a href="https://developer.mozilla.org/en/docs/Web/JavaScript/Guide/Regular_Expressions">?</a></small></h4></div>
</div>
<div data-bind="foreach: terminalFilters">
<div class="row-fluid" style="margin-bottom: 5px">
<div class="span4">
<input type="text" class="span12" data-bind="value: name">
</div>
<div class="span6">
<input type="text" class="span12" data-bind="value: regex">
</div>
<div class="span2">
<button title="Remove Filter" class="btn btn-danger" data-bind="click: $parent.removeTerminalFilter"><i class="icon-trash"></i></button>
</div>
</div>
</div>
<div class="row-fluid">
<div class="offset10 span2">
<button title="Add Filter" class="btn btn-primary" data-bind="click: addTerminalFilter"><i class="icon-plus"></i></button>
</div>
</div>
</form>
</div>
<div class="tab-pane" id="settings_appearance">
<form class="form-horizontal">
<div class="control-group">