From 5a07373d9a07c9400f4c1f4018495cd988d04b86 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 31 Jan 2017 15:01:16 +0000 Subject: [PATCH] [WebUI] Start rework of modules --- interface/js/app/stats.js | 330 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 330 insertions(+) create mode 100644 interface/js/app/stats.js diff --git a/interface/js/app/stats.js b/interface/js/app/stats.js new file mode 100644 index 000000000..966da8806 --- /dev/null +++ b/interface/js/app/stats.js @@ -0,0 +1,330 @@ +/* + The MIT License (MIT) + + Copyright (C) 2017 Vsevolod Stakhov + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. + */ + +define(['jquery', 'd3pie', 'humanize'], +function($, d3pie, Humanize) { + // @ ms to date + function msToTime(seconds) { + years = seconds / 31536000 >> 0; // 3600*24*365 + months = seconds % 31536000 / 2628000 >> 0; //3600*24*365/12 + days = seconds % 31536000 % 2628000 / 86400 >> 0; //24*3600 + hours = seconds % 31536000 % 2628000 % 86400 / 3600 >> 0; + minutes = seconds % 31536000 % 2628000 % 86400 % 3600 / 60 >> 0; + if (years > 0) { + if (months > 0) { + out = years + 'yr ' + months + 'mth'; + } else { + out = years + 'yr ' + days + 'd'; + } + } else if (months > 0) { + out = months + 'mth ' + days + 'd'; + } else if (days > 0) { + out = days + 'd ' + hours + 'hr'; + } else if (hours > 0) { + out = hours + 'hr ' + minutes + 'min'; + } else { + out = minutes + 'min'; + } + return out; + } + + function displayStatWidgets(checked_server) { + var widgets = $('#statWidgets'); + $(widgets).empty().hide(); + + var servers = JSON.parse(sessionStorage.getItem('Credentials')); + var data = {}; + + if (servers && servers[checked_server]) { + data = servers[checked_server].data; + } + var stat_w = []; + + $.each(data, function (i, item) { + var widget = ''; + if (i == 'auth') {} + else if (i == 'error') {} + else if (i == 'version') { + widget = '
' + item + '' + + i + '
'; + $(widget).appendTo(widgets); + } else if (i == 'uptime') { + widget = '
' + msToTime(item) + + '' + i + '
'; + $(widget).appendTo(widgets); + } else { + widget = '
  • ' + + Humanize.compactInteger(item) + '' + i + '
  • '; + if (i == 'scanned') { + stat_w[0] = widget; + } else if (i == 'clean') { + stat_w[1] = widget; + } else if (i == 'greylist') { + stat_w[2] = widget; + } else if (i == 'probable') { + stat_w[3] = widget; + } else if (i == 'reject') { + stat_w[4] = widget; + } else if (i == 'learned') { + stat_w[5] = widget; + } + } + }); + $.each(stat_w, function (i, item) { + $(item).appendTo(widgets); + }); + $('#statWidgets .left,#statWidgets .right').wrapAll('
  • '); + $('#statWidgets').find('li.pull-right').appendTo('#statWidgets'); + + $("#clusterTable tbody").empty(); + $.each(servers, function (key, val) { + var glyph_status; + if (val.status) { + glyph_status = "glyphicon glyphicon-ok-circle"; + } + else { + glyph_status = "glyphicon glyphicon-remove-circle"; + } + if (!('config_id' in val.data)) { + val.data.config_id = ""; + } + if (checked_server == key) { + $('#clusterTable tbody').append('' + + '' + + '' + key + '' + + '' + val.host + '' + + '' + + '' + val.data.config_id.substring(0, 8) + ''); + } else { + if (val.status) { + $('#clusterTable tbody').append('' + + '' + + '' + key + '' + + '' + val.host + '' + + '' + + '' + val.data.config_id.substring(0, 8) + ''); + } + else { + $('#clusterTable tbody').append('' + + '' + + '' + key + '' + + '' + val.host + '' + + '' + + '???'); + } + + } + }); + $(widgets).show(); + } + + function getChart(pie, checked_server) { + var creds = JSON.parse(sessionStorage.getItem('Credentials')); + if (creds && creds[checked_server]) { + var data = creds[checked_server].data; + var new_data = [ { + "color" : "#66CC00", + "label" : "Clean", + "data" : data.clean, + "value" : data.clean + }, { + "color" : "#BF8040", + "label" : "Temporary rejected", + "data" : data.soft_reject, + "value" : data.soft_reject + }, { + "color" : "#FFAD00", + "label" : "Probable spam", + "data" : data.probable, + "value" : data.probable + }, { + "color" : "#436EEE", + "label" : "Greylisted", + "data" : data.greylist, + "value" : data.greylist + }, { + "color" : "#FF0000", + "label" : "Rejected", + "data" : data.reject, + "value" : data.reject + } ]; + return drawPie(pie, "chart", new_data); + } + } + + function drawPie(obj, id, data, conf) { + if (obj) { + obj.updateProp("data.content", + data.filter(function (elt) { + return elt.value > 0; + }) + ); + } else { + obj = new d3pie(id, + $.extend({}, { + "header": { + "title": { + "text": "Rspamd filter stats", + "fontSize": 24, + "font": "open sans" + }, + "subtitle": { + "color": "#999999", + "fontSize": 12, + "font": "open sans" + }, + "titleSubtitlePadding": 9 + }, + "footer": { + "color": "#999999", + "fontSize": 10, + "font": "open sans", + "location": "bottom-left" + }, + "size": { + "canvasWidth": 600, + "canvasHeight": 400, + "pieInnerRadius": "20%", + "pieOuterRadius": "85%" + }, + "data": { + //"sortOrder": "value-desc", + "content": data.filter(function (elt) { + return elt.value > 0; + }) + }, + "labels": { + "outer": { + "hideWhenLessThanPercentage": 1, + "pieDistance": 30 + }, + "inner": { + "hideWhenLessThanPercentage": 4 + }, + "mainLabel": { + "fontSize": 14 + }, + "percentage": { + "color": "#eeeeee", + "fontSize": 14, + "decimalPlaces": 0 + }, + "lines": { + "enabled": true + }, + "truncation": { + "enabled": true + } + }, + "tooltips": { + "enabled": true, + "type": "placeholder", + "string": "{label}: {value}, {percentage}%" + }, + "effects": { + "pullOutSegmentOnClick": { + "effect": "back", + "speed": 400, + "size": 8 + }, + "load": { + "effect": "none" + } + }, + "misc": { + "gradient": { + "enabled": true, + "percentage": 100 + } + } + }, conf)); + } + return obj; + } + + // Public API + var interface = { + statWidgets: function(rspamd, pie, checked_server) { + rspamd.queryNeighbours("/auth", function(neighbours_status) { + var neighbours_sum = { + version: neighbours_status[0].data.version, + auth: "ok", + uptime: 0, + clean: 0, + probable: 0, + greylist: 0, + reject: 0, + soft_reject: 0, + scanned: 0, + learned: 0, + read_only: neighbours_status[0].data.read_only, + config_id: "" + }; + var status_count = 0; + for(var e in neighbours_status) { + if(neighbours_status[e].status === true) { + // Remove alert status + localStorage.removeItem(e + '_alerted'); + neighbours_sum.clean += neighbours_status[e].data.clean; + neighbours_sum.probable += neighbours_status[e].data.probable; + neighbours_sum.greylist += neighbours_status[e].data.greylist; + neighbours_sum.reject += neighbours_status[e].data.reject; + neighbours_sum.soft_reject += neighbours_status[e].data.soft_reject; + neighbours_sum.scanned += neighbours_status[e].data.scanned; + neighbours_sum.learned += neighbours_status[e].data.learned; + neighbours_sum.uptime += neighbours_status[e].data.uptime; + status_count++; + } + } + neighbours_sum.uptime = Math.floor(neighbours_sum.uptime / status_count); + var to_Credentials = {}; + to_Credentials["All SERVERS"] = { name: "All SERVERS", + url: "", + host: "", + checked: true, + data: neighbours_sum, + status: true + }; + neighbours_status.forEach(function (elmt) { + to_Credentials[elmt.name] = elmt; + }); + sessionStorage.setItem("Credentials", JSON.stringify(to_Credentials)); + displayStatWidgets(checked_server); + pie.chart = getChart(pie.chart, checked_server); + }, + function (serv, jqXHR, textStatus, errorThrown) { + var alert_status = serv.name + '_alerted'; + + if (!(alert_status in sessionStorage)) { + sessionStorage.setItem(alert_status, true); + rspamd.alertMessage('alert-error', 'Cannot receive stats data from: ' + + serv.name + ', error: ' + errorThrown); + } + }); + }, + }; + + return interface; +} +); \ No newline at end of file -- 2.39.5