define(['jquery', 'footable', 'humanize'],
function($, _, Humanize) {
var interface = {};
+ var ft = {};
function unix_time_format(tm) {
var date = new Date(tm ? tm * 1000 : 0);
}, {
"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",
}, {
"name": "size",
"title": "Message size",
- "breakpoints": "xs sm",
+ "breakpoints": "xs sm md",
"style": {
"font-size": "11px",
"width": 90,
}, {
"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); }
}, {
}, {
"name": "user",
"title": "Authenticated user",
- "breakpoints": "xs sm",
+ "breakpoints": "xs sm md",
"style": {
"font-size": "11px",
- "width": 100,
- "maxWidth": 150
+ "minWidth": 150
}
}];
}
}
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);
},
success: function (data) {
var items = process_history_data(data);
-
- $('#historyTable').footable({
+ ft.history = FooTable.init("#historyTable", {
"columns": get_history_columns(data),
"rows": items,
"paging": {
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',
},
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;
define(['jquery', 'footable'],
function($) {
var interface = {}
+ var ft = {}
function saveSymbols(rspamd, action, id, is_cluster) {
var inputs = $('#' + id + ' :input[data-role="numerictextbox"]');
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',
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');
};
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);
+ }
+ });
});
};