diff options
author | andryyy <andre.peters@debinux.de> | 2017-03-23 10:13:57 +0100 |
---|---|---|
committer | andryyy <andre.peters@debinux.de> | 2017-03-23 10:13:57 +0100 |
commit | fcf5395e8a9cced96b29fcb67cbe1364a65d3b80 (patch) | |
tree | 74dcd90a412f8f196fd26937de8222c86c128fb9 /interface/js | |
parent | ab60a0e3fa931d7df2c9a80e711e86c7162042c5 (diff) | |
download | rspamd-fcf5395e8a9cced96b29fcb67cbe1364a65d3b80.tar.gz rspamd-fcf5395e8a9cced96b29fcb67cbe1364a65d3b80.zip |
Better update handling, especially when updating empty table to non-empty table
Diffstat (limited to 'interface/js')
-rw-r--r-- | interface/js/app/history.js | 211 | ||||
-rw-r--r-- | interface/js/app/symbols.js | 315 |
2 files changed, 280 insertions, 246 deletions
diff --git a/interface/js/app/history.js b/interface/js/app/history.js index e5981e1d6..a72d0ca36 100644 --- a/interface/js/app/history.js +++ b/interface/js/app/history.js @@ -25,6 +25,7 @@ define(['jquery', 'footable', 'humanize'], function($, _, Humanize) { var interface = {}; + var ft = {}; function unix_time_format(tm) { var date = new Date(tm ? tm * 1000 : 0); @@ -146,38 +147,36 @@ function($, _, Humanize) { }, { "name": "ip", "title": "IP address", - "breakpoints": "xs sm", + "breakpoints": "xs sm md", "style": { "font-size": "11px", - "width": 150, - "maxWidth": 150 + "minWidth": 150, } }, { "name": "sender_mime", "title": "From", - "breakpoints": "xs sm", + "breakpoints": "xs sm md", "style": { "font-size": "11px", - "width": 150, - "maxWidth": 150 + "minWidth": 150, } }, { "name": "rcpt_mime", "title": "To", - "breakpoints": "xs sm", + "breakpoints": "xs sm md", "style": { "font-size": "11px", - "width": 150, - "maxWidth": 150 + "word-break": "break-all", + "minWidth": 150, + "maxWidth": 300, } }, { "name": "subject", "title": "Subject", - "breakpoints": "xs sm", + "breakpoints": "xs sm md", "style": { "font-size": "11px", - "width": 150, - "maxWidth": 150 + "minWidth": 150, } }, { "name": "action", @@ -207,7 +206,7 @@ function($, _, Humanize) { }, { "name": "size", "title": "Message size", - "breakpoints": "xs sm", + "breakpoints": "xs sm md", "style": { "font-size": "11px", "width": 90, @@ -217,10 +216,10 @@ function($, _, Humanize) { }, { "name": "scan_time", "title": "Scan time", - "breakpoints": "xs sm", + "breakpoints": "xs sm md", "style": { "font-size": "11px", - "maxWidth": 80 + "maxWidth": 120 }, "sortValue": function(val) { return Number(val.options.sortValue); } }, { @@ -235,11 +234,10 @@ function($, _, Humanize) { }, { "name": "user", "title": "Authenticated user", - "breakpoints": "xs sm", + "breakpoints": "xs sm md", "style": { "font-size": "11px", - "width": 100, - "maxWidth": 150 + "minWidth": 150 } }]; } @@ -368,19 +366,6 @@ function($, _, Humanize) { } interface.getHistory = function (rspamd, tables) { - if (tables.history !== undefined) { - var history_length = document.getElementsByName('historyLog_length')[0]; - if (history_length !== undefined) { - history_length = parseInt(history_length.value); - } else { - history_length = 10; - } - tables.history.destroy(); - tables.history = undefined; - $('#historyLog').children('tbody').remove(); - } - - FooTable.actionFilter = FooTable.Filtering.extend({ construct : function(instance) { this._super(instance); @@ -443,8 +428,7 @@ function($, _, Humanize) { }, success: function (data) { var items = process_history_data(data); - - $('#historyTable').footable({ + ft.history = FooTable.init("#historyTable", { "columns": get_history_columns(data), "rows": items, "paging": { @@ -470,12 +454,6 @@ function($, _, Humanize) { interface.getErrors = function(rspamd, tables) { if (rspamd.read_only) return; - if (tables.errors) { - tables.errors.destroy(); - $('#errorsLog').children('tbody').remove(); - tables.errors = undefined; - } - var items = []; $.ajax({ dataType: 'json', @@ -489,70 +467,111 @@ function($, _, Humanize) { }, success: function (data) { $.each(data, function (i, item) { - items.push( - item.ts = unix_time_format(item.ts) - ); - }); - $('#errorsLog').footable({ - "columns": [ - {"sorted": true,"direction": "DESC","name":"ts","title":"Time","style":{"font-size":"11px","width":300,"maxWidth":300}}, - {"name":"type","title":"Worker type","breakpoints":"xs sm","style":{"font-size":"11px","width":150,"maxWidth":150}}, - {"name":"pid","title":"PID","breakpoints":"xs sm","style":{"font-size":"11px","width":110,"maxWidth":110}}, - {"name":"module","title":"Module","style":{"font-size":"11px"}}, - {"name":"id","title":"Internal ID","style":{"font-size":"11px"}}, - {"name":"message","title":"Message","breakpoints":"xs sm","style":{"font-size":"11px"}}, - ], - "rows": data, - "paging": { - "enabled": true, - "limit": 5, - "size": 25 - }, - "filtering": { - "enabled": true, - "position": "left" - }, - "sorting": { - "enabled": true - } - }); + items.push( + item.ts = unix_time_format(item.ts) + ); + }); + ft.errors = FooTable.init("#errorsLog", { + "columns": [ + {"sorted": true,"direction": "DESC","name":"ts","title":"Time","style":{"font-size":"11px","width":300,"maxWidth":300}}, + {"name":"type","title":"Worker type","breakpoints":"xs sm","style":{"font-size":"11px","width":150,"maxWidth":150}}, + {"name":"pid","title":"PID","breakpoints":"xs sm","style":{"font-size":"11px","width":110,"maxWidth":110}}, + {"name":"module","title":"Module","style":{"font-size":"11px"}}, + {"name":"id","title":"Internal ID","style":{"font-size":"11px"}}, + {"name":"message","title":"Message","breakpoints":"xs sm","style":{"font-size":"11px"}}, + ], + "rows": data, + "paging": { + "enabled": true, + "limit": 5, + "size": 25 + }, + "filtering": { + "enabled": true, + "position": "left" + }, + "sorting": { + "enabled": true + } + }); } }); }; interface.setup = function(rspamd, tables) { - $('#updateHistory').on('click', function () { - interface.getHistory(rspamd, tables); + $('#updateHistory').on('click', function (e) { + e.preventDefault(); + $.ajax({ + dataType: 'json', + type: 'GET', + jsonp: false, + url: 'history', + beforeSend: function (xhr) { + xhr.setRequestHeader('Password', rspamd.getPassword()); + }, + success: function (data) { + var items = process_history_data(data); + ft.history.rows.load(items); + }, + error: function (data) { + rspamd.alertMessage('alert-modal alert-error', data.statusText); + } + }); }); - $('#updateErrors').on('click', function () { - interface.getErrors(rspamd, tables); + $('#updateErrors').on('click', function (e) { + e.preventDefault(); + var items = []; + $.ajax({ + dataType: 'json', + type: 'GET', + jsonp: false, + url: 'errors', + beforeSend: function (xhr) { + xhr.setRequestHeader('Password', rspamd.getPassword()); + }, + success: function (data) { + $.each(data, function (i, item) { + items.push( + item.ts = unix_time_format(item.ts) + ); + }); + ft.errors.rows.load(data); + }, + error: function (data) { + rspamd.alertMessage('alert-modal alert-error', data.statusText); + } + }); }); - // @reset history log - $('#resetHistory').on('click', function () { - if (!confirm("Are you sure you want to reset history log?")) { - return; - } - if (tables.history) { - tables.history.destroy(); - tables.history = undefined; - $('#historyLog').children('tbody').remove(); - } - $.ajax({ - dataType: 'json', - type: 'GET', - jsonp: false, - url: 'historyreset', - beforeSend: function (xhr) { - xhr.setRequestHeader('Password', rspamd.getPassword()); - }, - success: function () { - interface.getHistory(rspamd, tables); - interface.getErrors(rspamd, tables); - }, - error: function (data) { - rspamd.alertMessage('alert-modal alert-error', data.statusText); - } - }); + // @reset history log + $('#resetHistory').on('click', function (e) { + e.preventDefault(); + if (!confirm("Are you sure you want to reset history log?")) { + return; + } + if (ft.history) { + ft.history.destroy(); + ft.history = undefined; + } + if (ft.errors) { + ft.errors.destroy(); + ft.errors = undefined; + } + $.ajax({ + dataType: 'json', + type: 'GET', + jsonp: false, + url: 'historyreset', + beforeSend: function (xhr) { + xhr.setRequestHeader('Password', rspamd.getPassword()); + }, + success: function () { + interface.getHistory(rspamd, tables); + interface.getErrors(rspamd, tables); + }, + error: function (data) { + rspamd.alertMessage('alert-modal alert-error', data.statusText); + } + }); }); }; return interface; diff --git a/interface/js/app/symbols.js b/interface/js/app/symbols.js index 0d68c137f..f0c3d4770 100644 --- a/interface/js/app/symbols.js +++ b/interface/js/app/symbols.js @@ -25,6 +25,7 @@ define(['jquery', 'footable'], function($) { var interface = {} + var ft = {} function saveSymbols(rspamd, action, id, is_cluster) { var inputs = $('#' + id + ' :input[data-role="numerictextbox"]'); @@ -76,16 +77,84 @@ function($) { return 1.0 / (Math.pow(10, digits)); } } + function process_symbols_data(data) { + var items = []; + var lookup = {}; + var freqs = []; + var distinct_groups = []; + + $.each(data, function (i, group) { + $.each(group.rules, function (i, item) { + var max = 20; + var min = -20; + if (item.weight > max) { + max = item.weight * 2; + } + item.group = group.group + if (item.weight < min) { + min = item.weight * 2; + } + var label_class = ''; + if (item.weight < 0) { + label_class = 'scorebar-ham'; + } else { + label_class = 'scorebar-spam'; + } + item.weight = '<input class="form-control input-sm mb-disabled ' + label_class + + '" data-role="numerictextbox" autocomplete="off" "type="number" class="input" min="' + + min + '" max="' + + max + '" step="' + decimalStep(item.weight) + + '" tabindex="1" value="' + Number(item.weight).toFixed(3) + + '" id="_sym_' + item.symbol + '"></input>' + if (!item.time) { + item.time = 0; + } + item.time = Number(item.time).toFixed(2) + 's' + if (!item.frequency) { + item.frequency = 0; + } + freqs.push(item.frequency); + item.frequency = Number(item.frequency).toFixed(2) + if (!(item.group in lookup)) { + lookup[item.group] = 1; + distinct_groups.push(item.group); + } + item.save = '<button type="button" data-save="local" class="btn btn-primary btn-sm mb-disabled">Save</button>' + + ' <button data-save="cluster" type="button" class="btn btn-primary btn-sm mb-disabled">Save in cluster</button>'; + items.push(item) + }); + }); + + // For better mean calculations + var avg_freq = freqs.sort(function(a, b) { + return Number(a) < Number(b); + }).reduce(function(f1, acc) { + return f1 + acc; + }) / (freqs.length != 0 ? freqs.length : 1.0); + var mult = 1.0; + var exp = 0.0; + + if (avg_freq > 0.0) { + while (mult * avg_freq < 1.0) { + mult *= 10; + exp ++; + } + } + $.each(items, function (i, item) { + item.frequency = Number(item.frequency) * mult; + + if (exp > 0) { + item.frequency = item.frequency.toFixed(2) + 'e-' + exp; + } + else { + item.frequency = item.frequency.toFixed(2); + } + }); + return [items, distinct_groups] + } // @get symbols into modal form interface.getSymbols = function(rspamd, tables, checked_server) { - var symbols = tables.symbols - if (symbols) { - symbols.destroy(); - tables.symbols = undefined; - $('#symbolsTable').children('tbody').remove(); - } - var items = []; $.ajax({ dataType: 'json', type: 'GET', @@ -95,151 +164,81 @@ function($) { xhr.setRequestHeader('Password', rspamd.getPassword()); }, success: function (data) { - var distinct_groups = []; - var lookup = {}; - var freqs = []; - - $.each(data, function (i, group) { - $.each(group.rules, function (i, item) { - var max = 20; - var min = -20; - if (item.weight > max) { - max = item.weight * 2; - } - item.group = group.group - if (item.weight < min) { - min = item.weight * 2; - } - var label_class = ''; - if (item.weight < 0) { - label_class = 'scorebar-ham'; - } else { - label_class = 'scorebar-spam'; - } - item.weight = '<input class="form-control input-sm mb-disabled ' + label_class + - '" data-role="numerictextbox" autocomplete="off" "type="number" class="input" min="' + - min + '" max="' + - max + '" step="' + decimalStep(item.weight) + - '" tabindex="1" value="' + Number(item.weight).toFixed(3) + - '" id="_sym_' + item.symbol + '"></input>' - if (!item.time) { - item.time = 0; - } - item.time = Number(item.time).toFixed(2) + 's' - if (!item.frequency) { - item.frequency = 0; - } - freqs.push(item.frequency); - item.frequency = Number(item.frequency).toFixed(2) - if (!(item.group in lookup)) { - lookup[item.group] = 1; - distinct_groups.push(item.group); - } - item.save = '<button type="button" data-save="local" class="btn btn-primary btn-sm mb-disabled">Save</button>' + - ' <button data-save="cluster" type="button" class="btn btn-primary btn-sm mb-disabled">Save in cluster</button>'; - items.push(item) - }); - }); - // For better mean calculations - var avg_freq = freqs.sort(function(a, b) { - return Number(a) < Number(b); - }).reduce(function(f1, acc) { - return f1 + acc; - }) / (freqs.length != 0 ? freqs.length : 1.0); - var mult = 1.0; - var exp = 0.0; - - if (avg_freq > 0.0) { - while (mult * avg_freq < 1.0) { - mult *= 10; - exp ++; - } - } - $.each(items, function (i, item) { - item.frequency = Number(item.frequency) * mult; - - if (exp > 0) { - item.frequency = item.frequency.toFixed(2) + 'e-' + exp; - } - else { - item.frequency = item.frequency.toFixed(2); - } - }); + var items = process_symbols_data(data); FooTable.groupFilter = FooTable.Filtering.extend({ - construct : function(instance) { - this._super(instance); - this.groups = distinct_groups; - this.def = 'Any group'; - this.$group = null; - }, - $create : function() { - this._super(); - var self = this, $form_grp = $('<div/>', { - 'class' : 'form-group' - }).append($('<label/>', { - 'class' : 'sr-only', - text : 'Group' - })).prependTo(self.$form); + construct : function(instance) { + this._super(instance); + this.groups = items[1]; + this.def = 'Any group'; + this.$group = null; + }, + $create : function() { + this._super(); + var self = this, $form_grp = $('<div/>', { + 'class' : 'form-group' + }).append($('<label/>', { + 'class' : 'sr-only', + text : 'Group' + })).prependTo(self.$form); - self.$group = $('<select/>', { - 'class' : 'form-control' - }).on('change', { - self : self - }, self._onStatusDropdownChanged).append( - $('<option/>', { - text : self.def - })).appendTo($form_grp); + self.$group = $('<select/>', { + 'class' : 'form-control' + }).on('change', { + self : self + }, self._onStatusDropdownChanged).append( + $('<option/>', { + text : self.def + })).appendTo($form_grp); - $.each(self.groups, function(i, group) { - self.$group.append($('<option/>').text(group)); - }); - }, - _onStatusDropdownChanged : function(e) { - var self = e.data.self, selected = $(this).val(); - if (selected !== self.def) { - self.addFilter('group', selected, [ 'group' ]); - } else { - self.removeFilter('group'); - } - self.filter(); - }, - draw : function() { - this._super(); - var group = this.find('group'); - if (group instanceof FooTable.Filter) { - this.$group.val(group.query.val()); - } else { - this.$group.val(this.def); - } - } + $.each(self.groups, function(i, group) { + self.$group.append($('<option/>').text(group)); + }); + }, + _onStatusDropdownChanged : function(e) { + var self = e.data.self, selected = $(this).val(); + if (selected !== self.def) { + self.addFilter('group', selected, [ 'group' ]); + } else { + self.removeFilter('group'); + } + self.filter(); + }, + draw : function() { + this._super(); + var group = this.find('group'); + if (group instanceof FooTable.Filter) { + this.$group.val(group.query.val()); + } else { + this.$group.val(this.def); + } + } }); - - $('#symbolsTable').footable({ - "columns": [ - {"sorted": true,"direction": "ASC", "name":"group","title":"Group","style":{"font-size":"11px"}}, - {"name":"symbol","title":"Symbol","style":{"font-size":"11px"}}, - {"name":"description","title":"Description","breakpoints":"xs sm","style":{"font-size":"11px"}}, - {"name":"weight","title":"Score","style":{"font-size":"11px"}}, - {"name":"frequency","title":"Frequency","breakpoints":"xs sm","style":{"font-size":"11px"}}, - {"name":"time","title":"Avg. time","breakpoints":"xs sm","style":{"font-size":"11px"}}, - {"name":"save","title":"Save","style":{"font-size":"11px"}}, - ], - "rows": items, - "paging": { - "enabled": true, - "limit": 5, - "size": 25 - }, - "filtering": { - "enabled": true, - "position": "left" - }, - "sorting": { - "enabled": true - }, - components: { - filtering: FooTable.groupFilter - } + ft.symbols = FooTable.init("#symbolsTable", { + "columns": [ + {"sorted": true,"direction": "ASC", "name":"group","title":"Group","style":{"font-size":"11px"}}, + {"name":"symbol","title":"Symbol","style":{"font-size":"11px"}}, + {"name":"description","title":"Description","breakpoints":"xs sm","style":{"font-size":"11px"}}, + {"name":"weight","title":"Score","style":{"font-size":"11px"}}, + {"name":"frequency","title":"Frequency","breakpoints":"xs sm","style":{"font-size":"11px"}}, + {"name":"time","title":"Avg. time","breakpoints":"xs sm","style":{"font-size":"11px"}}, + {"name":"save","title":"Save","style":{"font-size":"11px"}}, + ], + "rows": items[0], + "paging": { + "enabled": true, + "limit": 5, + "size": 25 + }, + "filtering": { + "enabled": true, + "position": "left" + }, + "sorting": { + "enabled": true + }, + components: { + filtering: FooTable.groupFilter + } }, function tableHook() { $('#symbolsTable :button').on('click', function() { var value = $(this).data('save'); @@ -258,8 +257,24 @@ function($) { }; interface.setup = function(rspamd, tables) { - $('#updateSymbols').on('click', function () { - interface.getSymbols(rspamd, tables); + $('#updateSymbols').on('click', function (e) { + e.preventDefault(); + $.ajax({ + dataType: 'json', + type: 'GET', + jsonp: false, + url: 'symbols', + beforeSend: function (xhr) { + xhr.setRequestHeader('Password', rspamd.getPassword()); + }, + success: function (data) { + var items = process_symbols_data(data)[0]; + ft.symbols.rows.load(items); + }, + error: function (data) { + rspamd.alertMessage('alert-modal alert-error', data.statusText); + } + }); }); }; |