@@ -23,165 +23,165 @@ | |||
*/ | |||
define(["jquery"], | |||
function($) { | |||
var interface = {} | |||
function($) { | |||
var interface = {} | |||
function save_map_success(rspamd) { | |||
rspamd.alertMessage("alert-modal alert-success", "Map data successfully saved"); | |||
$("#modalDialog").modal("hide"); | |||
} | |||
function save_map_error(rspamd, serv, jqXHR, textStatus, errorThrown) { | |||
rspamd.alertMessage("alert-modal alert-error", "Save map error on " + | |||
function save_map_success(rspamd) { | |||
rspamd.alertMessage("alert-modal alert-success", "Map data successfully saved"); | |||
$("#modalDialog").modal("hide"); | |||
} | |||
function save_map_error(rspamd, serv, jqXHR, textStatus, errorThrown) { | |||
rspamd.alertMessage("alert-modal alert-error", "Save map error on " + | |||
serv.name + ": " + errorThrown); | |||
} | |||
// @upload map from modal | |||
function saveMap(rspamd, action, id) { | |||
var data = $("#" + id).find("textarea").val(); | |||
$.ajax({ | |||
data: data, | |||
dataType: "text", | |||
type: "POST", | |||
jsonp: false, | |||
url: action, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
xhr.setRequestHeader("Map", id); | |||
xhr.setRequestHeader("Debug", true); | |||
}, | |||
error: function (data) { | |||
save_map_error(rspamd, "local", null, null, data.statusText); | |||
}, | |||
success: function() {save_map_success(rspamd)}, | |||
}); | |||
} | |||
} | |||
// @upload map from modal | |||
function saveMap(rspamd, action, id) { | |||
var data = $("#" + id).find("textarea").val(); | |||
$.ajax({ | |||
data: data, | |||
dataType: "text", | |||
type: "POST", | |||
jsonp: false, | |||
url: action, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
xhr.setRequestHeader("Map", id); | |||
xhr.setRequestHeader("Debug", true); | |||
}, | |||
error: function (data) { | |||
save_map_error(rspamd, "local", null, null, data.statusText); | |||
}, | |||
success: function() {save_map_success(rspamd)}, | |||
}); | |||
} | |||
// @get maps id | |||
function getMaps(rspamd) { | |||
var items = []; | |||
var $listmaps = $("#listMaps") | |||
$listmaps.closest(".widget-box").hide(); | |||
$.ajax({ | |||
dataType: "json", | |||
url: "maps", | |||
jsonp: false, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
}, | |||
error: function (data) { | |||
rspamd.alertMessage("alert-modal alert-error", data.statusText); | |||
}, | |||
success: function (data) { | |||
$listmaps.empty(); | |||
$("#modalBody").empty(); | |||
$tbody = $("<tbody>"); | |||
// @get maps id | |||
function getMaps(rspamd) { | |||
var items = []; | |||
var $listmaps = $("#listMaps") | |||
$listmaps.closest(".widget-box").hide(); | |||
$.ajax({ | |||
dataType: "json", | |||
url: "maps", | |||
jsonp: false, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
}, | |||
error: function (data) { | |||
rspamd.alertMessage("alert-modal alert-error", data.statusText); | |||
}, | |||
success: function (data) { | |||
$listmaps.empty(); | |||
$("#modalBody").empty(); | |||
$tbody = $("<tbody>"); | |||
$.each(data, function (i, item) { | |||
$.each(data, function (i, item) { | |||
if ((item.editable === false || rspamd.read_only)) { | |||
var label = "<span class=\"label label-default\">Read</span>"; | |||
} else { | |||
var label = "<span class=\"label label-default\">Read</span> <span class=\"label label-success\">Write</span>"; | |||
} | |||
var $tr = $("<tr>"); | |||
$("<td class=\"col-md-2 maps-cell\">" + label + "</td>").appendTo($tr); | |||
$span = $("<span class=\"map-link\" data-toggle=\"modal\" data-target=\"#modalDialog\">" + item.uri + "</span>").data("item",item); | |||
$span.wrap("<td>").parent().appendTo($tr); | |||
$("<td>" + item.description + "</td>").appendTo($tr); | |||
$tr.appendTo($tbody); | |||
}); | |||
$tbody.appendTo($listmaps); | |||
$listmaps.closest(".widget-box").show(); | |||
} | |||
}); | |||
} | |||
// @get map by id | |||
function getMapById(rspamd, item) { | |||
return $.ajax({ | |||
dataType: "text", | |||
url: "getmap", | |||
jsonp: false, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
xhr.setRequestHeader("Map", item.map); | |||
}, | |||
error: function () { | |||
rspamd.alertMessage("alert-error", "Cannot receive maps data"); | |||
}, | |||
success: function (text) { | |||
var disabled = ""; | |||
if ((item.editable === false || rspamd.read_only)) { | |||
var label = "<span class=\"label label-default\">Read</span>"; | |||
} else { | |||
var label = "<span class=\"label label-default\">Read</span> <span class=\"label label-success\">Write</span>"; | |||
disabled = "disabled=\"disabled\""; | |||
} | |||
var $tr = $("<tr>"); | |||
$("<td class=\"col-md-2 maps-cell\">" + label + "</td>").appendTo($tr); | |||
$span = $("<span class=\"map-link\" data-toggle=\"modal\" data-target=\"#modalDialog\">" + item.uri + "</span>").data("item",item); | |||
$span.wrap("<td>").parent().appendTo($tr); | |||
$("<td>" + item.description + "</td>").appendTo($tr); | |||
$tr.appendTo($tbody); | |||
}); | |||
$tbody.appendTo($listmaps); | |||
$listmaps.closest(".widget-box").show(); | |||
} | |||
}); | |||
} | |||
// @get map by id | |||
function getMapById(rspamd, item) { | |||
return $.ajax({ | |||
dataType: "text", | |||
url: "getmap", | |||
jsonp: false, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
xhr.setRequestHeader("Map", item.map); | |||
}, | |||
error: function () { | |||
rspamd.alertMessage("alert-error", "Cannot receive maps data"); | |||
}, | |||
success: function (text) { | |||
var disabled = ""; | |||
if ((item.editable === false || rspamd.read_only)) { | |||
disabled = "disabled=\"disabled\""; | |||
} | |||
$("#"+item.map).remove(); | |||
$("<form class=\"form-horizontal form-map\" method=\"post\" action=\"savemap\" data-type=\"map\" id=\"" + | |||
$("#"+item.map).remove(); | |||
$("<form class=\"form-horizontal form-map\" method=\"post\" action=\"savemap\" data-type=\"map\" id=\"" + | |||
item.map + "\" style=\"display:none\">" + | |||
"<textarea class=\"list-textarea\"" + disabled + ">" + text + | |||
"</textarea>" + | |||
"</form").appendTo("#modalBody"); | |||
} | |||
}); | |||
} | |||
} | |||
}); | |||
} | |||
function loadActionsFromForm() { | |||
var values = []; | |||
var inputs = $("#actionsForm :input[data-id=\"action\"]"); | |||
// Rspamd order: [spam, rewrite_subject, probable_spam, greylist] | |||
values[0] = parseFloat(inputs[3].value); | |||
values[1] = parseFloat(inputs[2].value); | |||
values[2] = parseFloat(inputs[1].value); | |||
values[3] = parseFloat(inputs[0].value); | |||
function loadActionsFromForm() { | |||
var values = []; | |||
var inputs = $("#actionsForm :input[data-id=\"action\"]"); | |||
// Rspamd order: [spam, rewrite_subject, probable_spam, greylist] | |||
values[0] = parseFloat(inputs[3].value); | |||
values[1] = parseFloat(inputs[2].value); | |||
values[2] = parseFloat(inputs[1].value); | |||
values[3] = parseFloat(inputs[0].value); | |||
return JSON.stringify(values); | |||
} | |||
return JSON.stringify(values); | |||
} | |||
function getActions(rspamd) { | |||
$.ajax({ | |||
dataType: "json", | |||
type: "GET", | |||
url: "actions", | |||
jsonp: false, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
}, | |||
success: function (data) { | |||
function getActions(rspamd) { | |||
$.ajax({ | |||
dataType: "json", | |||
type: "GET", | |||
url: "actions", | |||
jsonp: false, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
}, | |||
success: function (data) { | |||
// Order of sliders greylist -> probable spam -> rewrite subject -> spam | |||
$("#actionsBody").empty(); | |||
$("#actionsForm").empty(); | |||
var items = []; | |||
$.each(data, function (i, item) { | |||
var idx = -1; | |||
var label; | |||
if (item.action === "add header") { | |||
label = "Probably Spam"; | |||
idx = 1; | |||
} else if (item.action === "greylist") { | |||
label = "Greylist"; | |||
idx = 0; | |||
} else if (item.action === "rewrite subject") { | |||
label = "Rewrite subject"; | |||
idx = 2; | |||
} else if (item.action === "reject") { | |||
label = "Spam"; | |||
idx = 3; | |||
} | |||
if (idx >= 0) { | |||
items.push({ | |||
idx: idx, | |||
html: "<div class=\"form-group\">" + | |||
$("#actionsBody").empty(); | |||
$("#actionsForm").empty(); | |||
var items = []; | |||
$.each(data, function (i, item) { | |||
var idx = -1; | |||
var label; | |||
if (item.action === "add header") { | |||
label = "Probably Spam"; | |||
idx = 1; | |||
} else if (item.action === "greylist") { | |||
label = "Greylist"; | |||
idx = 0; | |||
} else if (item.action === "rewrite subject") { | |||
label = "Rewrite subject"; | |||
idx = 2; | |||
} else if (item.action === "reject") { | |||
label = "Spam"; | |||
idx = 3; | |||
} | |||
if (idx >= 0) { | |||
items.push({ | |||
idx: idx, | |||
html: "<div class=\"form-group\">" + | |||
"<label class=\"control-label col-sm-2\">" + label + "</label>" + | |||
"<div class=\"controls slider-controls col-sm-10\">" + | |||
"<input class=\"action-scores form-control\" data-id=\"action\" type=\"number\" value=\"" + item.value + "\">" + | |||
"</div>" + | |||
"</div>" | |||
}); | |||
} | |||
}); | |||
}); | |||
} | |||
}); | |||
items.sort(function (a, b) { | |||
return a.idx - b.idx; | |||
}); | |||
items.sort(function (a, b) { | |||
return a.idx - b.idx; | |||
}); | |||
$("#actionsBody").html("<form id=\"actionsForm\"><fieldset id=\"actionsFormField\">" + | |||
$("#actionsBody").html("<form id=\"actionsForm\"><fieldset id=\"actionsFormField\">" + | |||
items.map(function (e) { | |||
return e.html; | |||
}).join("") + | |||
@@ -190,95 +190,95 @@ function($) { | |||
"<button class=\"btn btn-primary\" type=\"button\" id=\"saveActionsBtn\">Save actions</button>" + | |||
"<button class=\"btn btn-primary\" type=\"button\" id=\"saveActionsClusterBtn\">Save cluster</button>" + | |||
"</div></div></fieldset></form>"); | |||
if (rspamd.read_only) { | |||
$("#saveActionsClusterBtn").attr("disabled", true); | |||
$("#saveActionsBtn").attr("disabled", true); | |||
$("#actionsFormField").attr("disabled", true); | |||
} | |||
if (rspamd.read_only) { | |||
$("#saveActionsClusterBtn").attr("disabled", true); | |||
$("#saveActionsBtn").attr("disabled", true); | |||
$("#actionsFormField").attr("disabled", true); | |||
} | |||
function saveActions(callback) { | |||
var elts = loadActionsFromForm(); | |||
// String to array for comparison | |||
var eltsArray = JSON.parse(loadActionsFromForm()); | |||
if (eltsArray[0] < 0) { | |||
rspamd.alertMessage("alert-modal alert-error", "Spam can not be negative"); | |||
} else if (eltsArray[1] < 0) { | |||
rspamd.alertMessage("alert-modal alert-error", "Rewrite subject can not be negative"); | |||
} else if (eltsArray[2] < 0) { | |||
rspamd.alertMessage("alert-modal alert-error", "Probable spam can not be negative"); | |||
} else if (eltsArray[3] < 0) { | |||
rspamd.alertMessage("alert-modal alert-error", "Greylist can not be negative"); | |||
} else if ( | |||
(eltsArray[2] === null || eltsArray[3] < eltsArray[2]) && | |||
function saveActions(callback) { | |||
var elts = loadActionsFromForm(); | |||
// String to array for comparison | |||
var eltsArray = JSON.parse(loadActionsFromForm()); | |||
if (eltsArray[0] < 0) { | |||
rspamd.alertMessage("alert-modal alert-error", "Spam can not be negative"); | |||
} else if (eltsArray[1] < 0) { | |||
rspamd.alertMessage("alert-modal alert-error", "Rewrite subject can not be negative"); | |||
} else if (eltsArray[2] < 0) { | |||
rspamd.alertMessage("alert-modal alert-error", "Probable spam can not be negative"); | |||
} else if (eltsArray[3] < 0) { | |||
rspamd.alertMessage("alert-modal alert-error", "Greylist can not be negative"); | |||
} else if ( | |||
(eltsArray[2] === null || eltsArray[3] < eltsArray[2]) && | |||
(eltsArray[1] === null || eltsArray[2] < eltsArray[1]) && | |||
(eltsArray[0] === null || eltsArray[1] < eltsArray[0]) | |||
) { | |||
callback("saveactions", null, null, "POST", {}, { | |||
data: elts, | |||
dataType: "json" | |||
}); | |||
} else { | |||
rspamd.alertMessage("alert-modal alert-error", "Incorrect order of metric actions threshold"); | |||
) { | |||
callback("saveactions", null, null, "POST", {}, { | |||
data: elts, | |||
dataType: "json" | |||
}); | |||
} else { | |||
rspamd.alertMessage("alert-modal alert-error", "Incorrect order of metric actions threshold"); | |||
} | |||
} | |||
} | |||
$("#saveActionsBtn").on("click", function() { | |||
saveActions(rspamd.queryLocal); | |||
}); | |||
$("#saveActionsClusterBtn").on("click", function() { | |||
saveActions(rspamd.queryNeighbours); | |||
}); | |||
}, | |||
}); | |||
} | |||
$("#saveActionsBtn").on("click", function() { | |||
saveActions(rspamd.queryLocal); | |||
}); | |||
$("#saveActionsClusterBtn").on("click", function() { | |||
saveActions(rspamd.queryNeighbours); | |||
}); | |||
}, | |||
}); | |||
} | |||
// @upload edited actions | |||
interface.setup = function(rspamd) { | |||
// @upload edited actions | |||
interface.setup = function(rspamd) { | |||
// Modal form for maps | |||
$(document).on("click", "[data-toggle=\"modal\"]", function () { | |||
var item = $(this).data("item"); | |||
getMapById(rspamd, item).done(function() { | |||
$("#modalTitle").html(item.uri); | |||
$("#" + item.map).first().show(); | |||
$("#modalDialog .progress").hide(); | |||
$("#modalDialog").modal(show = true, backdrop = true, keyboard = show); | |||
if (item.editable === false) { | |||
$("#modalSave").hide(); | |||
$("#modalSaveAll").hide(); | |||
} else { | |||
$("#modalSave").show(); | |||
$("#modalSaveAll").show(); | |||
} | |||
$(document).on("click", "[data-toggle=\"modal\"]", function () { | |||
var item = $(this).data("item"); | |||
getMapById(rspamd, item).done(function() { | |||
$("#modalTitle").html(item.uri); | |||
$("#" + item.map).first().show(); | |||
$("#modalDialog .progress").hide(); | |||
$("#modalDialog").modal(show = true, backdrop = true, keyboard = show); | |||
if (item.editable === false) { | |||
$("#modalSave").hide(); | |||
$("#modalSaveAll").hide(); | |||
} else { | |||
$("#modalSave").show(); | |||
$("#modalSaveAll").show(); | |||
} | |||
}); | |||
return false; | |||
}); | |||
return false; | |||
}); | |||
// close modal without saving | |||
$("[data-dismiss=\"modal\"]").on("click", function () { | |||
$("#modalBody form").hide(); | |||
}); | |||
// @save forms from modal | |||
$("#modalSave").on("click", function () { | |||
var form = $("#modalBody").children().filter(":visible"); | |||
var action = $(form).attr("action"); | |||
var id = $(form).attr("id"); | |||
saveMap(rspamd, action, id); | |||
}); | |||
$("#modalSaveAll").on("click", function () { | |||
var form = $("#modalBody").children().filter(":visible"); | |||
var action = $(form).attr("action"); | |||
var id = $(form).attr("id"); | |||
var data = $("#" + id).find("textarea").val(); | |||
rspamd.queryNeighbours(action, save_map_success, save_map_error, "POST", { | |||
"Map": id, | |||
}, { | |||
data: data, | |||
dataType: "text", | |||
// close modal without saving | |||
$("[data-dismiss=\"modal\"]").on("click", function () { | |||
$("#modalBody form").hide(); | |||
}); | |||
// @save forms from modal | |||
$("#modalSave").on("click", function () { | |||
var form = $("#modalBody").children().filter(":visible"); | |||
var action = $(form).attr("action"); | |||
var id = $(form).attr("id"); | |||
saveMap(rspamd, action, id); | |||
}); | |||
$("#modalSaveAll").on("click", function () { | |||
var form = $("#modalBody").children().filter(":visible"); | |||
var action = $(form).attr("action"); | |||
var id = $(form).attr("id"); | |||
var data = $("#" + id).find("textarea").val(); | |||
rspamd.queryNeighbours(action, save_map_success, save_map_error, "POST", { | |||
"Map": id, | |||
}, { | |||
data: data, | |||
dataType: "text", | |||
}); | |||
}); | |||
}); | |||
} | |||
} | |||
interface.getActions = getActions; | |||
interface.getMaps = getMaps; | |||
interface.getActions = getActions; | |||
interface.getMaps = getMaps; | |||
return interface; | |||
}); | |||
return interface; | |||
}); |
@@ -24,273 +24,273 @@ | |||
*/ | |||
define(["jquery", "d3evolution", "footable"], | |||
function($, D3Evolution, unused) { | |||
var rrd_pie_config = { | |||
header: {}, | |||
size: { | |||
canvasWidth: 400, | |||
canvasHeight: 180, | |||
pieInnerRadius: "20%", | |||
pieOuterRadius: "80%" | |||
}, | |||
labels: { | |||
outer: { | |||
format: "none" | |||
function($, D3Evolution, unused) { | |||
var rrd_pie_config = { | |||
header: {}, | |||
size: { | |||
canvasWidth: 400, | |||
canvasHeight: 180, | |||
pieInnerRadius: "20%", | |||
pieOuterRadius: "80%" | |||
}, | |||
inner: { | |||
hideWhenLessThanPercentage: 8 | |||
}, | |||
}, | |||
misc: { | |||
pieCenterOffset: { | |||
x: -120, | |||
y: 10, | |||
labels: { | |||
outer: { | |||
format: "none" | |||
}, | |||
inner: { | |||
hideWhenLessThanPercentage: 8 | |||
}, | |||
}, | |||
gradient: { | |||
enabled: true, | |||
misc: { | |||
pieCenterOffset: { | |||
x: -120, | |||
y: 10, | |||
}, | |||
gradient: { | |||
enabled: true, | |||
}, | |||
}, | |||
}, | |||
}; | |||
}; | |||
var graph_options = { | |||
title: "Rspamd throughput", | |||
width: 1060, | |||
height: 370, | |||
yAxisLabel: "Message rate, msg/s", | |||
var graph_options = { | |||
title: "Rspamd throughput", | |||
width: 1060, | |||
height: 370, | |||
yAxisLabel: "Message rate, msg/s", | |||
legend: { | |||
space: 140, | |||
entries: [{ | |||
label: "Rejected", | |||
color: "#FF0000" | |||
}, { | |||
label: "Temporarily rejected", | |||
color: "#BF8040" | |||
}, { | |||
label: "Subject rewritten", | |||
color: "#FF6600" | |||
}, { | |||
label: "Probable spam", | |||
color: "#FFAD00" | |||
}, { | |||
label: "Greylisted", | |||
color: "#436EEE" | |||
}, { | |||
label: "Clean", | |||
color: "#66CC00" | |||
}] | |||
} | |||
}; | |||
legend: { | |||
space: 140, | |||
entries: [{ | |||
label: "Rejected", | |||
color: "#FF0000" | |||
}, { | |||
label: "Temporarily rejected", | |||
color: "#BF8040" | |||
}, { | |||
label: "Subject rewritten", | |||
color: "#FF6600" | |||
}, { | |||
label: "Probable spam", | |||
color: "#FFAD00" | |||
}, { | |||
label: "Greylisted", | |||
color: "#436EEE" | |||
}, { | |||
label: "Clean", | |||
color: "#66CC00" | |||
}] | |||
} | |||
}; | |||
// Get selectors' current state | |||
function getSelector(id) { | |||
var e = document.getElementById(id); | |||
return e.options[e.selectedIndex].value; | |||
} | |||
// Get selectors' current state | |||
function getSelector(id) { | |||
var e = document.getElementById(id); | |||
return e.options[e.selectedIndex].value; | |||
} | |||
function initGraph() { | |||
var graph = new D3Evolution("graph", $.extend({}, graph_options, { | |||
yScale: getSelector("selYScale"), | |||
type: getSelector("selType"), | |||
interpolate: getSelector("selInterpolate"), | |||
convert: getSelector("selConvert"), | |||
})); | |||
$("#selYScale").change(function() { | |||
graph.yScale(this.value); | |||
}); | |||
$("#selConvert").change(function () { | |||
graph.convert(this.value); | |||
}); | |||
$("#selType").change(function () { | |||
graph.type(this.value); | |||
}); | |||
$("#selInterpolate").change(function () { | |||
graph.interpolate(this.value); | |||
}); | |||
function initGraph() { | |||
var graph = new D3Evolution("graph", $.extend({}, graph_options, { | |||
yScale: getSelector("selYScale"), | |||
type: getSelector("selType"), | |||
interpolate: getSelector("selInterpolate"), | |||
convert: getSelector("selConvert"), | |||
})); | |||
$("#selYScale").change(function() { | |||
graph.yScale(this.value); | |||
}); | |||
$("#selConvert").change(function () { | |||
graph.convert(this.value); | |||
}); | |||
$("#selType").change(function () { | |||
graph.type(this.value); | |||
}); | |||
$("#selInterpolate").change(function () { | |||
graph.interpolate(this.value); | |||
}); | |||
return graph; | |||
} | |||
return graph; | |||
} | |||
function getRrdSummary(json, scaleFactor) { | |||
var xExtents = d3.extent(d3.merge(json), function (d) { return d.x; }); | |||
var timeInterval = xExtents[1] - xExtents[0]; | |||
function getRrdSummary(json, scaleFactor) { | |||
var xExtents = d3.extent(d3.merge(json), function (d) { return d.x; }); | |||
var timeInterval = xExtents[1] - xExtents[0]; | |||
return json.map(function (curr, i) { | |||
return json.map(function (curr, i) { | |||
// Time intervals that don't have data are excluded from average calculation as d3.mean()ignores nulls | |||
var avg = d3.mean(curr, function (d) { return d.y; }); | |||
// To find an integral on the whole time interval we need to convert nulls to zeroes | |||
var value = d3.mean(curr, function (d) { return +d.y; }) * timeInterval / scaleFactor; | |||
var yExtents = d3.extent(curr, function (d) { return d.y; }); | |||
var avg = d3.mean(curr, function (d) { return d.y; }); | |||
// To find an integral on the whole time interval we need to convert nulls to zeroes | |||
var value = d3.mean(curr, function (d) { return +d.y; }) * timeInterval / scaleFactor; | |||
var yExtents = d3.extent(curr, function (d) { return d.y; }); | |||
return { | |||
label: graph_options.legend.entries[i].label, | |||
value: value ^ 0, | |||
min: +yExtents[0].toFixed(6), | |||
avg: +avg.toFixed(6), | |||
max: +yExtents[1].toFixed(6), | |||
last: +curr[curr.length - 1].y.toFixed(6), | |||
color: graph_options.legend.entries[i].color, | |||
}; | |||
}, []); | |||
} | |||
return { | |||
label: graph_options.legend.entries[i].label, | |||
value: value ^ 0, | |||
min: +yExtents[0].toFixed(6), | |||
avg: +avg.toFixed(6), | |||
max: +yExtents[1].toFixed(6), | |||
last: +curr[curr.length - 1].y.toFixed(6), | |||
color: graph_options.legend.entries[i].color, | |||
}; | |||
}, []); | |||
} | |||
function drawRrdTable(data, unit) { | |||
var total_messages = 0; | |||
var rows = data.map(function (curr, i) { | |||
total_messages += curr.value; | |||
return { | |||
options: { | |||
style: { | |||
color: graph_options.legend.entries[i].color | |||
} | |||
}, | |||
value: curr | |||
}; | |||
}, []); | |||
function drawRrdTable(data, unit) { | |||
var total_messages = 0; | |||
var rows = data.map(function (curr, i) { | |||
total_messages += curr.value; | |||
return { | |||
options: { | |||
style: { | |||
color: graph_options.legend.entries[i].color | |||
} | |||
}, | |||
value: curr | |||
}; | |||
}, []); | |||
document.getElementById("rrd-total-value").innerHTML = total_messages; | |||
document.getElementById("rrd-total-value").innerHTML = total_messages; | |||
$("#rrd-table").footable({ | |||
sorting: { | |||
enabled: true | |||
}, | |||
columns: [ | |||
{ name: "label", title: "Action" }, | |||
{ name: "value", title: "Messages", defaultContent: "" }, | |||
{ name: "min", title: "Minimum, " + unit, defaultContent: "" }, | |||
{ name: "avg", title: "Average, " + unit, defaultContent: "" }, | |||
{ name: "max", title: "Maximum, " + unit, defaultContent: "" }, | |||
{ name: "last", title: "Last, " + unit }, | |||
], | |||
rows: rows | |||
}); | |||
} | |||
$("#rrd-table").footable({ | |||
sorting: { | |||
enabled: true | |||
}, | |||
columns: [ | |||
{ name: "label", title: "Action" }, | |||
{ name: "value", title: "Messages", defaultContent: "" }, | |||
{ name: "min", title: "Minimum, " + unit, defaultContent: "" }, | |||
{ name: "avg", title: "Average, " + unit, defaultContent: "" }, | |||
{ name: "max", title: "Maximum, " + unit, defaultContent: "" }, | |||
{ name: "last", title: "Last, " + unit }, | |||
], | |||
rows: rows | |||
}); | |||
} | |||
var interface = {}; | |||
var prevUnit = "msg/s"; | |||
var interface = {}; | |||
var prevUnit = "msg/s"; | |||
interface.draw = function(rspamd, graphs, neighbours, checked_server, type) { | |||
interface.draw = function(rspamd, graphs, neighbours, checked_server, type) { | |||
function updateWidgets(data) { | |||
function updateWidgets(data) { | |||
// Autoranging | |||
var scaleFactor = 1; | |||
var unit = "msg/s"; | |||
var yMax = d3.max(d3.merge(data), function (d) { return d.y; }); | |||
if (yMax < 1) { | |||
scaleFactor = 60; | |||
unit = "msg/min"; | |||
data.forEach(function (s) { | |||
s.forEach(function (d) { | |||
if (d.y !== null) { d.y *= scaleFactor; } | |||
var scaleFactor = 1; | |||
var unit = "msg/s"; | |||
var yMax = d3.max(d3.merge(data), function (d) { return d.y; }); | |||
if (yMax < 1) { | |||
scaleFactor = 60; | |||
unit = "msg/min"; | |||
data.forEach(function (s) { | |||
s.forEach(function (d) { | |||
if (d.y !== null) { d.y *= scaleFactor; } | |||
}); | |||
}); | |||
}); | |||
} | |||
} | |||
graphs.graph.data(data); | |||
if (unit != prevUnit) { | |||
graphs.graph.yAxisLabel("Message rate, " + unit); | |||
prevUnit = unit; | |||
} | |||
graphs.graph.data(data); | |||
if (unit != prevUnit) { | |||
graphs.graph.yAxisLabel("Message rate, " + unit); | |||
prevUnit = unit; | |||
} | |||
if (!data) { | |||
graphs.rrd_pie.destroy(); | |||
drawRrdTable([]); | |||
return; | |||
if (!data) { | |||
graphs.rrd_pie.destroy(); | |||
drawRrdTable([]); | |||
return; | |||
} | |||
var rrd_summary = getRrdSummary(data, scaleFactor); | |||
graphs.rrd_pie = rspamd.drawPie(graphs.rrd_pie, | |||
"rrd-pie", | |||
rrd_summary, | |||
rrd_pie_config); | |||
drawRrdTable(rrd_summary, unit); | |||
} | |||
var rrd_summary = getRrdSummary(data, scaleFactor); | |||
graphs.rrd_pie = rspamd.drawPie(graphs.rrd_pie, | |||
"rrd-pie", | |||
rrd_summary, | |||
rrd_pie_config); | |||
drawRrdTable(rrd_summary, unit); | |||
} | |||
if (graphs.graph === undefined) { | |||
graphs.graph = initGraph(); | |||
} | |||
if (graphs.graph === undefined) { | |||
graphs.graph = initGraph(); | |||
} | |||
if (checked_server === "All SERVERS") { | |||
rspamd.queryNeighbours("graph", function (req_data) { | |||
var neighbours_data = req_data | |||
.filter(function (d) { return d.status }) // filter out unavailable neighbours | |||
.map(function (d){ return d.data; }); | |||
if (checked_server === "All SERVERS") { | |||
rspamd.queryNeighbours("graph", function (req_data) { | |||
var neighbours_data = req_data | |||
.filter(function (d) { return d.status }) // filter out unavailable neighbours | |||
.map(function (d){ return d.data; }); | |||
if (neighbours_data.length > 1) { | |||
neighbours_data.reduce(function (res, curr) { | |||
if ((curr[0][0].x !== res[0][0].x) || | |||
if (neighbours_data.length > 1) { | |||
neighbours_data.reduce(function (res, curr) { | |||
if ((curr[0][0].x !== res[0][0].x) || | |||
(curr[0][curr[0].length - 1].x !== res[0][res[0].length - 1].x)) { | |||
rspamd.alertMessage("alert-error", | |||
"Neighbours time extents do not match. Check if time is synchronized on all servers."); | |||
updateWidgets(); | |||
return; | |||
} | |||
rspamd.alertMessage("alert-error", | |||
"Neighbours time extents do not match. Check if time is synchronized on all servers."); | |||
updateWidgets(); | |||
return; | |||
} | |||
var data = []; | |||
curr.forEach(function (action, j) { | |||
data.push( | |||
action.map(function (d, i) { | |||
return { | |||
x: d.x, | |||
y: ((res[j][i].y === null) ? d.y : res[j][i].y + d.y) | |||
}; | |||
}) | |||
); | |||
var data = []; | |||
curr.forEach(function (action, j) { | |||
data.push( | |||
action.map(function (d, i) { | |||
return { | |||
x: d.x, | |||
y: ((res[j][i].y === null) ? d.y : res[j][i].y + d.y) | |||
}; | |||
}) | |||
); | |||
}); | |||
updateWidgets(data); | |||
}); | |||
updateWidgets(data); | |||
}); | |||
} | |||
else { | |||
updateWidgets(neighbours_data[0]); | |||
} | |||
}, | |||
function (serv, jqXHR, textStatus, errorThrown) { | |||
var alert_status = serv.name + "_alerted"; | |||
} | |||
else { | |||
updateWidgets(neighbours_data[0]); | |||
} | |||
}, | |||
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 RRD data from: " + | |||
if (!(alert_status in sessionStorage)) { | |||
sessionStorage.setItem(alert_status, true); | |||
rspamd.alertMessage("alert-error", "Cannot receive RRD data from: " + | |||
serv.name + ", error: " + errorThrown); | |||
} | |||
}, "GET", {}, {}, { | |||
type: type | |||
}); | |||
return; | |||
} | |||
} | |||
}, "GET", {}, {}, { | |||
type: type | |||
}); | |||
return; | |||
} | |||
$.ajax({ | |||
dataType: "json", | |||
type: "GET", | |||
url: neighbours[checked_server].url + "graph", | |||
jsonp: false, | |||
data: { | |||
"type": type | |||
}, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
}, | |||
success: function (data) { | |||
updateWidgets(data); | |||
}, | |||
error: function (jqXHR, textStatus, errorThrown) { | |||
rspamd.alertMessage("alert-error", "Cannot receive throughput data: " + | |||
$.ajax({ | |||
dataType: "json", | |||
type: "GET", | |||
url: neighbours[checked_server].url + "graph", | |||
jsonp: false, | |||
data: { | |||
"type": type | |||
}, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
}, | |||
success: function (data) { | |||
updateWidgets(data); | |||
}, | |||
error: function (jqXHR, textStatus, errorThrown) { | |||
rspamd.alertMessage("alert-error", "Cannot receive throughput data: " + | |||
textStatus + " " + jqXHR.status + " " + errorThrown); | |||
} | |||
}); | |||
}; | |||
} | |||
}); | |||
}; | |||
interface.setup = function() { | |||
interface.setup = function() { | |||
// Handling mouse events on overlapping elements | |||
$("#rrd-pie").mouseover(function () { | |||
$("#rrd-pie").css("z-index", "200"); | |||
$("#rrd-table_toggle").css("z-index", "300"); | |||
}); | |||
$("#rrd-table_toggle").mouseover(function () { | |||
$("#rrd-pie").css("z-index", "0"); | |||
$("#rrd-table_toggle").css("z-index", "0"); | |||
}); | |||
$("#rrd-pie").mouseover(function () { | |||
$("#rrd-pie").css("z-index", "200"); | |||
$("#rrd-table_toggle").css("z-index", "300"); | |||
}); | |||
$("#rrd-table_toggle").mouseover(function () { | |||
$("#rrd-pie").css("z-index", "0"); | |||
$("#rrd-table_toggle").css("z-index", "0"); | |||
}); | |||
return getSelector("selData"); | |||
}; | |||
return getSelector("selData"); | |||
}; | |||
return interface; | |||
}); | |||
return interface; | |||
}); |
@@ -23,158 +23,158 @@ | |||
*/ | |||
define(["jquery", "d3pie", "humanize"], | |||
function($, d3pie, Humanize) { | |||
function($, d3pie, Humanize) { | |||
// @ ms to date | |||
function msToTime(seconds) { | |||
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"; | |||
} | |||
if (months > 0) { | |||
out = years + "yr " + months + "mth"; | |||
} else { | |||
out = years + "yr " + days + "d"; | |||
} | |||
} else if (months > 0) { | |||
out = months + "mth " + days + "d"; | |||
out = months + "mth " + days + "d"; | |||
} else if (days > 0) { | |||
out = days + "d " + hours + "hr"; | |||
out = days + "d " + hours + "hr"; | |||
} else if (hours > 0) { | |||
out = hours + "hr " + minutes + "min"; | |||
out = hours + "hr " + minutes + "min"; | |||
} else { | |||
out = minutes + "min"; | |||
out = minutes + "min"; | |||
} | |||
return out; | |||
} | |||
} | |||
function displayStatWidgets(checked_server) { | |||
var widgets = $("#statWidgets"); | |||
$(widgets).empty().hide(); | |||
function displayStatWidgets(checked_server) { | |||
var widgets = $("#statWidgets"); | |||
$(widgets).empty().hide(); | |||
var servers = JSON.parse(sessionStorage.getItem("Credentials")); | |||
var data = {}; | |||
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 = "<div class=\"left\"><strong>" + item + "</strong>" + | |||
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 = "<div class=\"left\"><strong>" + item + "</strong>" + | |||
i + "</div>"; | |||
$(widget).appendTo(widgets); | |||
} else if (i == "uptime") { | |||
widget = "<div class=\"right\"><strong>" + msToTime(item) + | |||
$(widget).appendTo(widgets); | |||
} else if (i == "uptime") { | |||
widget = "<div class=\"right\"><strong>" + msToTime(item) + | |||
"</strong>" + i + "</div>"; | |||
$(widget).appendTo(widgets); | |||
} else { | |||
var titleAtt = Humanize.intComma(item) + " " + i; | |||
widget = "<li class=\"stat-box\"><div class=\"widget\" title=\"" + titleAtt + "\"><strong>" + | |||
$(widget).appendTo(widgets); | |||
} else { | |||
var titleAtt = Humanize.intComma(item) + " " + i; | |||
widget = "<li class=\"stat-box\"><div class=\"widget\" title=\"" + titleAtt + "\"><strong>" + | |||
Humanize.compactInteger(item) + "</strong>" + i + "</div></li>"; | |||
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; | |||
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("<li class=\"stat-box pull-right\"><div class=\"widget\"></div></li>"); | |||
$("#statWidgets").find("li.pull-right").appendTo("#statWidgets"); | |||
$("#clusterTable tbody").empty(); | |||
$("#selSrv").empty(); | |||
$.each(servers, function (key, val) { | |||
var glyph_status; | |||
var short_id; | |||
if (!("config_id" in val.data)) { | |||
val.data.config_id = ""; | |||
} | |||
if (val.status) { | |||
glyph_status = "glyphicon glyphicon-ok-circle"; | |||
short_id = val.data.config_id.substring(0, 8); | |||
} | |||
else { | |||
glyph_status = "glyphicon glyphicon-remove-circle"; | |||
short_id = "???"; | |||
} | |||
} | |||
}); | |||
$.each(stat_w, function (i, item) { | |||
$(item).appendTo(widgets); | |||
}); | |||
$("#statWidgets .left,#statWidgets .right").wrapAll("<li class=\"stat-box pull-right\"><div class=\"widget\"></div></li>"); | |||
$("#statWidgets").find("li.pull-right").appendTo("#statWidgets"); | |||
$("#clusterTable tbody").empty(); | |||
$("#selSrv").empty(); | |||
$.each(servers, function (key, val) { | |||
var glyph_status; | |||
var short_id; | |||
if (!("config_id" in val.data)) { | |||
val.data.config_id = ""; | |||
} | |||
if (val.status) { | |||
glyph_status = "glyphicon glyphicon-ok-circle"; | |||
short_id = val.data.config_id.substring(0, 8); | |||
} | |||
else { | |||
glyph_status = "glyphicon glyphicon-remove-circle"; | |||
short_id = "???"; | |||
} | |||
$("#clusterTable tbody").append("<tr>" + | |||
$("#clusterTable tbody").append("<tr>" + | |||
"<td class=\"col1\" title=\"Radio\"><input type=\"radio\" class=\"form-control radio\" name=\"clusterName\" value=\"" + key + "\"></td>" + | |||
"<td class=\"col2\" title=\"SNAme\">" + key + "</td>" + | |||
"<td class=\"col3\" title=\"SHost\">" + val.host + "</td>" + | |||
"<td class=\"col4\" title=\"SStatus\"><span class=\"icon\"><i class=\"" + glyph_status + "\"></i></span></td>" + | |||
"<td class=\"col5\" title=\"short_id\">" + short_id + "</td></tr>"); | |||
$("#selSrv").append( $("<option value=\"" + key + "\">" + key + "</option>")); | |||
$("#selSrv").append( $("<option value=\"" + key + "\">" + key + "</option>")); | |||
if (checked_server == key) { | |||
$("#clusterTable tbody [value=\"" + key + "\"]").prop("checked", true); | |||
$("#selSrv [value=\"" + key + "\"]").prop("selected", true); | |||
} | |||
else if (!val.status) { | |||
$("#clusterTable tbody [value=\"" + key + "\"]").prop("disabled", true); | |||
$("#selSrv [value=\"" + key + "\"]").prop("disabled", true); | |||
} | |||
}); | |||
$(widgets).show(); | |||
} | |||
if (checked_server == key) { | |||
$("#clusterTable tbody [value=\"" + key + "\"]").prop("checked", true); | |||
$("#selSrv [value=\"" + key + "\"]").prop("selected", true); | |||
} | |||
else if (!val.status) { | |||
$("#clusterTable tbody [value=\"" + key + "\"]").prop("disabled", true); | |||
$("#selSrv [value=\"" + key + "\"]").prop("disabled", true); | |||
} | |||
}); | |||
$(widgets).show(); | |||
} | |||
function getChart(rspamd, 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" : "Temporarily 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 rspamd.drawPie(pie, "chart", new_data); | |||
function getChart(rspamd, 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" : "Temporarily 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 rspamd.drawPie(pie, "chart", new_data); | |||
} | |||
} | |||
} | |||
// Public API | |||
var interface = { | |||
statWidgets: function(rspamd, graphs, checked_server) { | |||
rspamd.queryNeighbours("/auth", function(neighbours_status) { | |||
var neighbours_sum = { | |||
// Public API | |||
var interface = { | |||
statWidgets: function(rspamd, graphs, checked_server) { | |||
rspamd.queryNeighbours("/auth", function(neighbours_status) { | |||
var neighbours_sum = { | |||
version: neighbours_status[0].data.version, | |||
auth: "ok", | |||
uptime: 0, | |||
@@ -187,51 +187,51 @@ function($, d3pie, Humanize) { | |||
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) { | |||
}; | |||
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++; | |||
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", | |||
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; | |||
}; | |||
neighbours_status.forEach(function (elmt) { | |||
to_Credentials[elmt.name] = elmt; | |||
}); | |||
sessionStorage.setItem("Credentials", JSON.stringify(to_Credentials)); | |||
displayStatWidgets(checked_server); | |||
graphs.chart = getChart(rspamd, graphs.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); | |||
} | |||
}); | |||
sessionStorage.setItem("Credentials", JSON.stringify(to_Credentials)); | |||
displayStatWidgets(checked_server); | |||
graphs.chart = getChart(rspamd, graphs.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; | |||
} | |||
return interface; | |||
} | |||
); |
@@ -23,264 +23,264 @@ | |||
*/ | |||
define(["jquery", "footable"], | |||
function($) { | |||
var interface = {} | |||
var ft = {} | |||
function($) { | |||
var interface = {} | |||
var ft = {} | |||
function saveSymbols(rspamd, action, id, is_cluster) { | |||
var inputs = $("#" + id + " :input[data-role=\"numerictextbox\"]"); | |||
var url = action; | |||
var values = []; | |||
$(inputs).each(function () { | |||
values.push({ | |||
name: $(this).attr("id").substring(5), | |||
value: parseFloat($(this).val()) | |||
function saveSymbols(rspamd, action, id, is_cluster) { | |||
var inputs = $("#" + id + " :input[data-role=\"numerictextbox\"]"); | |||
var url = action; | |||
var values = []; | |||
$(inputs).each(function () { | |||
values.push({ | |||
name: $(this).attr("id").substring(5), | |||
value: parseFloat($(this).val()) | |||
}); | |||
}); | |||
}); | |||
if (is_cluster) { | |||
rspamd.queryNeighbours(url, function () { | |||
rspamd.alertMessage("alert-modal alert-success", "Symbols successfully saved"); | |||
}, function (serv, qXHR, textStatus, errorThrown) { | |||
rspamd.alertMessage("alert-modal alert-error", | |||
if (is_cluster) { | |||
rspamd.queryNeighbours(url, function () { | |||
rspamd.alertMessage("alert-modal alert-success", "Symbols successfully saved"); | |||
}, function (serv, qXHR, textStatus, errorThrown) { | |||
rspamd.alertMessage("alert-modal alert-error", | |||
"Save symbols error on " + | |||
serv.name + ": " + errorThrown); | |||
}, "POST", {}, { | |||
data: JSON.stringify(values), | |||
dataType: "json", | |||
}); | |||
} | |||
else { | |||
$.ajax({ | |||
data: JSON.stringify(values), | |||
dataType: "json", | |||
type: "POST", | |||
url: url, | |||
jsonp: false, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
}, | |||
success: function () { | |||
rspamd.alertMessage("alert-modal alert-success", "Symbols successfully saved"); | |||
}, | |||
error: function (data) { | |||
rspamd.alertMessage("alert-modal alert-error", data.statusText); | |||
} | |||
}); | |||
}, "POST", {}, { | |||
data: JSON.stringify(values), | |||
dataType: "json", | |||
}); | |||
} | |||
else { | |||
$.ajax({ | |||
data: JSON.stringify(values), | |||
dataType: "json", | |||
type: "POST", | |||
url: url, | |||
jsonp: false, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
}, | |||
success: function () { | |||
rspamd.alertMessage("alert-modal alert-success", "Symbols successfully saved"); | |||
}, | |||
error: function (data) { | |||
rspamd.alertMessage("alert-modal alert-error", data.statusText); | |||
} | |||
}); | |||
} | |||
} | |||
} | |||
function decimalStep(number) { | |||
var digits = ((+number).toFixed(20)).replace(/^-?\d*\.?|0+$/g, "").length; | |||
if (digits === 0 || digits > 4) { | |||
return 0.1; | |||
} else { | |||
return 1.0 / (Math.pow(10, digits)); | |||
function decimalStep(number) { | |||
var digits = ((+number).toFixed(20)).replace(/^-?\d*\.?|0+$/g, "").length; | |||
if (digits === 0 || digits > 4) { | |||
return 0.1; | |||
} else { | |||
return 1.0 / (Math.pow(10, digits)); | |||
} | |||
} | |||
} | |||
function process_symbols_data(data) { | |||
var items = []; | |||
var lookup = {}; | |||
var freqs = []; | |||
var distinct_groups = []; | |||
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 if (item.weight > 0) { | |||
label_class = "scorebar-spam"; | |||
} | |||
item.weight = "<input class=\"form-control input-sm mb-disabled " + label_class + | |||
$.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 if (item.weight > 0) { | |||
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>" + | |||
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) | |||
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; | |||
// 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 ++; | |||
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; | |||
$.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) { | |||
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) { | |||
$.ajax({ | |||
dataType: "json", | |||
type: "GET", | |||
url: "symbols", | |||
jsonp: false, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
}, | |||
success: function (data) { | |||
var items = process_symbols_data(data); | |||
FooTable.groupFilter = FooTable.Filtering.extend({ | |||
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); | |||
$.ajax({ | |||
dataType: "json", | |||
type: "GET", | |||
url: "symbols", | |||
jsonp: false, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
}, | |||
success: function (data) { | |||
var items = process_symbols_data(data); | |||
FooTable.groupFilter = FooTable.Filtering.extend({ | |||
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); | |||
} | |||
} | |||
}); | |||
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"},"sortValue": function(value){return Number(value).toFixed(2)}}, | |||
{"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", | |||
"connectors": false | |||
}, | |||
"sorting": { | |||
"enabled": true | |||
}, | |||
components: { | |||
filtering: FooTable.groupFilter | |||
}, | |||
"on": { | |||
"ready.ft.table": function () { | |||
if (rspamd.read_only) { | |||
$(".mb-disabled").attr("disabled", true); | |||
$.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); | |||
} | |||
} | |||
}); | |||
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"},"sortValue": function(value){return Number(value).toFixed(2)}}, | |||
{"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", | |||
"connectors": false | |||
}, | |||
"sorting": { | |||
"enabled": true | |||
}, | |||
components: { | |||
filtering: FooTable.groupFilter | |||
}, | |||
"on": { | |||
"ready.ft.table": function () { | |||
if (rspamd.read_only) { | |||
$(".mb-disabled").attr("disabled", true); | |||
} | |||
} | |||
} | |||
}); | |||
}, | |||
error: function (data) { | |||
rspamd.alertMessage("alert-modal alert-error", data.statusText); | |||
} | |||
}); | |||
$(document).on("click", "#symbolsTable :button", function(event){ | |||
var value = $(this).data("save"); | |||
if (!value) return | |||
saveSymbols(rspamd, "./savesymbols", "symbolsTable", value == "cluster"); | |||
}); | |||
}; | |||
interface.setup = function(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); | |||
} | |||
} | |||
}); | |||
}, | |||
error: function (data) { | |||
rspamd.alertMessage("alert-modal alert-error", data.statusText); | |||
} | |||
}); | |||
$(document).on("click", "#symbolsTable :button", function(event){ | |||
var value = $(this).data("save"); | |||
if (!value) return | |||
saveSymbols(rspamd, "./savesymbols", "symbolsTable", value == "cluster"); | |||
}); | |||
}; | |||
interface.setup = function(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); | |||
} | |||
}); | |||
}); | |||
}; | |||
}); | |||
}; | |||
return interface; | |||
}); | |||
return interface; | |||
}); |
@@ -23,192 +23,192 @@ | |||
*/ | |||
define(["jquery"], | |||
function($) { | |||
var interface = {} | |||
function($) { | |||
var interface = {} | |||
function cleanTextUpload(source) { | |||
$("#" + source + "TextSource").val(""); | |||
} | |||
// @upload text | |||
function uploadText(rspamd, data, source, headers) { | |||
var url; | |||
if (source === "spam") { | |||
url = "learnspam"; | |||
} else if (source === "ham") { | |||
url = "learnham"; | |||
} else if (source == "fuzzy") { | |||
url = "fuzzyadd"; | |||
} else if (source === "scan") { | |||
url = "scan"; | |||
function cleanTextUpload(source) { | |||
$("#" + source + "TextSource").val(""); | |||
} | |||
$.ajax({ | |||
data: data, | |||
dataType: "json", | |||
type: "POST", | |||
url: url, | |||
processData: false, | |||
jsonp: false, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
$.each(headers, function (name, value) { | |||
xhr.setRequestHeader(name, value); | |||
}); | |||
}, | |||
success: function (data) { | |||
cleanTextUpload(source); | |||
if (data.success) { | |||
rspamd.alertMessage("alert-success", "Data successfully uploaded"); | |||
} | |||
}, | |||
error: function (xhr, textStatus, errorThrown) { | |||
var errorMsg; | |||
try { | |||
var json = $.parseJSON(xhr.responseText); | |||
errorMsg = $("<a>").text(json.error).html(); | |||
} catch (err) { | |||
errorMsg = $("<a>").text("Error: [" + textStatus + "] " + errorThrown).html(); | |||
} | |||
rspamd.alertMessage("alert-error", errorMsg); | |||
// @upload text | |||
function uploadText(rspamd, data, source, headers) { | |||
var url; | |||
if (source === "spam") { | |||
url = "learnspam"; | |||
} else if (source === "ham") { | |||
url = "learnham"; | |||
} else if (source == "fuzzy") { | |||
url = "fuzzyadd"; | |||
} else if (source === "scan") { | |||
url = "scan"; | |||
} | |||
}); | |||
} | |||
// @upload text | |||
function scanText(rspamd, data) { | |||
var url = "scan"; | |||
var items = []; | |||
$.ajax({ | |||
data: data, | |||
dataType: "json", | |||
type: "POST", | |||
url: url, | |||
processData: false, | |||
jsonp: false, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
}, | |||
success: function (input) { | |||
var data = input; | |||
if (data.action) { | |||
rspamd.alertMessage("alert-success", "Data successfully scanned"); | |||
var action = ""; | |||
if (data.action === "clean" || "no action") { | |||
action = "label-success"; | |||
} | |||
else if (data.action === "rewrite subject" || "add header" || "probable spam") { | |||
action = "label-warning"; | |||
} | |||
else if (data.action === "spam") { | |||
action = "label-danger"; | |||
$.ajax({ | |||
data: data, | |||
dataType: "json", | |||
type: "POST", | |||
url: url, | |||
processData: false, | |||
jsonp: false, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
$.each(headers, function (name, value) { | |||
xhr.setRequestHeader(name, value); | |||
}); | |||
}, | |||
success: function (data) { | |||
cleanTextUpload(source); | |||
if (data.success) { | |||
rspamd.alertMessage("alert-success", "Data successfully uploaded"); | |||
} | |||
}, | |||
error: function (xhr, textStatus, errorThrown) { | |||
var errorMsg; | |||
var score = ""; | |||
if (data.score <= data.required_score) { | |||
score = "label-success"; | |||
try { | |||
var json = $.parseJSON(xhr.responseText); | |||
errorMsg = $("<a>").text(json.error).html(); | |||
} catch (err) { | |||
errorMsg = $("<a>").text("Error: [" + textStatus + "] " + errorThrown).html(); | |||
} | |||
else if (data.score >= data.required_score) { | |||
score = "label-danger"; | |||
} | |||
$("<tbody id=\"tmpBody\"><tr>" + | |||
rspamd.alertMessage("alert-error", errorMsg); | |||
} | |||
}); | |||
} | |||
// @upload text | |||
function scanText(rspamd, data) { | |||
var url = "scan"; | |||
var items = []; | |||
$.ajax({ | |||
data: data, | |||
dataType: "json", | |||
type: "POST", | |||
url: url, | |||
processData: false, | |||
jsonp: false, | |||
beforeSend: function (xhr) { | |||
xhr.setRequestHeader("Password", rspamd.getPassword()); | |||
}, | |||
success: function (input) { | |||
var data = input; | |||
if (data.action) { | |||
rspamd.alertMessage("alert-success", "Data successfully scanned"); | |||
var action = ""; | |||
if (data.action === "clean" || "no action") { | |||
action = "label-success"; | |||
} | |||
else if (data.action === "rewrite subject" || "add header" || "probable spam") { | |||
action = "label-warning"; | |||
} | |||
else if (data.action === "spam") { | |||
action = "label-danger"; | |||
} | |||
var score = ""; | |||
if (data.score <= data.required_score) { | |||
score = "label-success"; | |||
} | |||
else if (data.score >= data.required_score) { | |||
score = "label-danger"; | |||
} | |||
$("<tbody id=\"tmpBody\"><tr>" + | |||
"<td><span class=\"label " + action + "\">" + data.action + "</span></td>" + | |||
"<td><span class=\"label " + score + "\">" + data.score.toFixed(2) + "/" + data.required_score.toFixed(2) + "</span></td>" + | |||
"</tr></tbody>") | |||
.insertAfter("#scanOutput thead"); | |||
var sym_desc = {}; | |||
var nsym = 0; | |||
.insertAfter("#scanOutput thead"); | |||
var sym_desc = {}; | |||
var nsym = 0; | |||
$.each(data.symbols, function (i, item) { | |||
if (typeof item == "object") { | |||
var sym_id = "sym_" + nsym; | |||
if (item.description) { | |||
sym_desc[sym_id] = item.description; | |||
} | |||
items.push("<div class=\"cell-overflow\" tabindex=\"1\"><abbr id=\"" + sym_id + | |||
$.each(data.symbols, function (i, item) { | |||
if (typeof item == "object") { | |||
var sym_id = "sym_" + nsym; | |||
if (item.description) { | |||
sym_desc[sym_id] = item.description; | |||
} | |||
items.push("<div class=\"cell-overflow\" tabindex=\"1\"><abbr id=\"" + sym_id + | |||
"\">" + item.name + "</abbr>: " + item.score.toFixed(2) + "</div>"); | |||
nsym++; | |||
} | |||
}); | |||
$("<td/>", { | |||
id: "tmpSymbols", | |||
html: items.join("") | |||
}).appendTo("#scanResult"); | |||
$("#tmpSymbols").insertAfter("#tmpBody td:last").removeAttr("id"); | |||
$("#tmpBody").removeAttr("id"); | |||
$("#scanResult").show(); | |||
// Show tooltips | |||
$.each(sym_desc, function (k, v) { | |||
$("#" + k).tooltip({ | |||
"placement": "bottom", | |||
"title": v | |||
nsym++; | |||
} | |||
}); | |||
}); | |||
$("html, body").animate({ | |||
scrollTop: $("#scanResult").offset().top | |||
}, 1000); | |||
} else { | |||
rspamd.alertMessage("alert-error", "Cannot scan data"); | |||
} | |||
}, | |||
error: function (jqXHR, textStatus, errorThrown) { | |||
rspamd.alertMessage("alert-error", "Cannot upload data: " + | |||
textStatus + ", " + errorThrown); | |||
}, | |||
statusCode: { | |||
404: function () { | |||
rspamd.alertMessage("alert-error", "Cannot upload data, no server found"); | |||
$("<td/>", { | |||
id: "tmpSymbols", | |||
html: items.join("") | |||
}).appendTo("#scanResult"); | |||
$("#tmpSymbols").insertAfter("#tmpBody td:last").removeAttr("id"); | |||
$("#tmpBody").removeAttr("id"); | |||
$("#scanResult").show(); | |||
// Show tooltips | |||
$.each(sym_desc, function (k, v) { | |||
$("#" + k).tooltip({ | |||
"placement": "bottom", | |||
"title": v | |||
}); | |||
}); | |||
$("html, body").animate({ | |||
scrollTop: $("#scanResult").offset().top | |||
}, 1000); | |||
} else { | |||
rspamd.alertMessage("alert-error", "Cannot scan data"); | |||
} | |||
}, | |||
500: function () { | |||
rspamd.alertMessage("alert-error", "Cannot tokenize message: no text data"); | |||
error: function (jqXHR, textStatus, errorThrown) { | |||
rspamd.alertMessage("alert-error", "Cannot upload data: " + | |||
textStatus + ", " + errorThrown); | |||
}, | |||
503: function () { | |||
rspamd.alertMessage("alert-error", "Cannot tokenize message: no text data"); | |||
statusCode: { | |||
404: function () { | |||
rspamd.alertMessage("alert-error", "Cannot upload data, no server found"); | |||
}, | |||
500: function () { | |||
rspamd.alertMessage("alert-error", "Cannot tokenize message: no text data"); | |||
}, | |||
503: function () { | |||
rspamd.alertMessage("alert-error", "Cannot tokenize message: no text data"); | |||
} | |||
} | |||
} | |||
}); | |||
} | |||
}); | |||
} | |||
interface.setup = function(rspamd) { | |||
$("textarea").change(function () { | |||
if ($(this).val().length !== "") { | |||
$(this).closest("form").find("button").removeAttr("disabled").removeClass("disabled"); | |||
} else { | |||
$(this).closest("form").find("button").attr("disabled").addClass("disabled"); | |||
} | |||
}); | |||
interface.setup = function(rspamd) { | |||
$("textarea").change(function () { | |||
if ($(this).val().length !== "") { | |||
$(this).closest("form").find("button").removeAttr("disabled").removeClass("disabled"); | |||
} else { | |||
$(this).closest("form").find("button").attr("disabled").addClass("disabled"); | |||
} | |||
}); | |||
$("#scanClean").on("click", function () { | |||
$("#scanTextSource").val(""); | |||
$("#scanResult").hide(); | |||
$("#scanOutput tbody").remove(); | |||
$("html, body").animate({scrollTop: 0}, 1000); | |||
return false; | |||
}); | |||
// @init upload | |||
$("[data-upload]").on("click", function () { | |||
var source = $(this).data("upload"); | |||
var data; | |||
var headers = {}; | |||
data = $("#" + source + "TextSource").val(); | |||
if (source == "fuzzy") { | |||
//To access the proper | |||
headers.flag = $("#fuzzyFlagText").val(); | |||
headers.weight = $("#fuzzyWeightText").val(); | |||
} else { | |||
$("#scanClean").on("click", function () { | |||
$("#scanTextSource").val(""); | |||
$("#scanResult").hide(); | |||
$("#scanOutput tbody").remove(); | |||
$("html, body").animate({scrollTop: 0}, 1000); | |||
return false; | |||
}); | |||
// @init upload | |||
$("[data-upload]").on("click", function () { | |||
var source = $(this).data("upload"); | |||
var data; | |||
var headers = {}; | |||
data = $("#" + source + "TextSource").val(); | |||
} | |||
if (data.length > 0) { | |||
if (source == "scan") { | |||
scanText(rspamd, data); | |||
if (source == "fuzzy") { | |||
//To access the proper | |||
headers.flag = $("#fuzzyFlagText").val(); | |||
headers.weight = $("#fuzzyWeightText").val(); | |||
} else { | |||
uploadText(rspamd, data, source, headers); | |||
data = $("#" + source + "TextSource").val(); | |||
} | |||
} | |||
return false; | |||
}); | |||
}; | |||
if (data.length > 0) { | |||
if (source == "scan") { | |||
scanText(rspamd, data); | |||
} else { | |||
uploadText(rspamd, data, source, headers); | |||
} | |||
} | |||
return false; | |||
}); | |||
}; | |||
return interface; | |||
}); | |||
return interface; | |||
}); |
@@ -27,17 +27,17 @@ document.title = window.location.hostname + | |||
" - Rspamd Web Interface"; | |||
define("d3.global", ["d3"], function(_) { | |||
d3 = _; | |||
d3 = _; | |||
}); | |||
// Load main UI | |||
require(["domReady"], | |||
function(domReady) { | |||
domReady(function () { | |||
require(["jquery", "d3", "app/rspamd"], | |||
function ($, d3, rspamd) { | |||
rspamd.setup(); | |||
rspamd.connect(); | |||
}); | |||
function(domReady) { | |||
domReady(function () { | |||
require(["jquery", "d3", "app/rspamd"], | |||
function ($, d3, rspamd) { | |||
rspamd.setup(); | |||
rspamd.connect(); | |||
}); | |||
}); | |||
}); | |||
}); |