Fixes and improvements

This commit is contained in:
calzoneman 2013-06-23 14:02:20 -04:00
parent c08b89d68a
commit 1a3d92c903
8 changed files with 132 additions and 48 deletions

12
acp.js
View File

@ -7,7 +7,7 @@ module.exports = {
init: function(user) {
ActionLog.record(user.ip, user.name, "acp-init");
user.socket.on("acp-announce", function(data) {
ActionLog.record(user.ip, user.name, ["acp-announce", data]);
ActionLog.record(user.ip, user.name, "acp-announce", [data]);
Server.announcement = data;
Server.io.sockets.emit("announcement", data);
});
@ -18,13 +18,13 @@ module.exports = {
});
user.socket.on("acp-global-ban", function(data) {
ActionLog.record(user.ip, user.name, ["acp-global-ban", data.ip]);
ActionLog.record(user.ip, user.name, "acp-global-ban", [data.ip]);
Database.globalBanIP(data.ip, data.note);
user.socket.emit("acp-global-banlist", Database.refreshGlobalBans());
});
user.socket.on("acp-global-unban", function(ip) {
ActionLog.record(user.ip, user.name, ["acp-global-unban", data.ip]);
ActionLog.record(user.ip, user.name, "acp-global-unban", [data.ip]);
Database.globalUnbanIP(ip);
user.socket.emit("acp-global-banlist", Database.refreshGlobalBans());
});
@ -55,7 +55,7 @@ module.exports = {
return;
try {
var hash = Database.generatePasswordReset(user.ip, data.name, data.email);
ActionLog.record(user.ip, user.name, ["acp-reset-password", data.name]);
ActionLog.record(user.ip, user.name, "acp-reset-password", [data.name]);
}
catch(e) {
user.socket.emit("acp-reset-password", {
@ -90,7 +90,7 @@ module.exports = {
if(!db)
return;
ActionLog.record(user.ip, user.name, ["acp-set-rank", data]);
ActionLog.record(user.ip, user.name, "acp-set-rank", [data]);
var query = Database.createQuery(
"UPDATE registrations SET global_rank=? WHERE uname=?",
[data.name, data.rank]
@ -139,7 +139,7 @@ module.exports = {
user.socket.on("acp-actionlog-clear", function(data) {
ActionLog.clear(data);
ActionLog.record(user.ip, user.name, "acp-actionlog-clear");
ActionLog.record(user.ip, user.name, "acp-actionlog-clear", data);
});
}
}

View File

@ -1,12 +1,14 @@
var fs = require("fs");
var Logger = require("./logger");
var buffer = [];
exports.record = function(ip, name, action) {
exports.record = function(ip, name, action, args) {
buffer.push(JSON.stringify({
ip: ip,
name: name,
action: action,
args: args ? args : [],
time: Date.now()
}));
}
@ -24,11 +26,40 @@ exports.flush = function() {
});
}
exports.clear = function() {
try {
fs.renameSync("action.log", "action-until-"+Date.now()+".log");
exports.clear = function(actions) {
clearInterval(FLUSH_TMR);
var rs = fs.createReadStream("action.log");
var ws = fs.createWriteStream("action.log.tmp");
function handleLine(ln) {
try {
js = JSON.parse(ln);
if(actions.indexOf(js.action) == -1)
ws.write(ln + "\n");
}
catch(e) { }
}
catch(e) { }
var buffer = "";
rs.on("data", function(chunk) {
buffer += chunk;
if(buffer.indexOf("\n") != -1) {
var lines = buffer.split("\n");
buffer = lines[lines.length - 1];
lines.length = lines.length - 1;
lines.forEach(handleLine);
}
});
rs.on("end", function() {
handleLine(buffer);
ws.end();
});
try {
fs.renameSync("action.log.tmp", "action.log");
}
catch(e) {
Logger.errlog.log("Failed to move action.log.tmp => action.log");
Logger.errlog.log(e);
}
FLUSH_TMR = setInterval(exports.flush, 15000);
}
setInterval(exports.flush, 15000);
var FLUSH_TMR = setInterval(exports.flush, 15000);

2
api.js
View File

@ -429,7 +429,7 @@ function handleEmailChange(params, req, res) {
var row = Auth.login(name, pw);
if(row) {
var success = Database.setUserEmail(name, email);
ActionLog.record(getClientIP(req), name, ["email-update", email]);
ActionLog.record(getClientIP(req), name, "email-update", [email]);
sendJSON(res, {
success: success,
error: success ? "" : "Email update failed",

View File

@ -269,14 +269,14 @@ function incrementalDump(chan) {
Channel.prototype.tryRegister = function(user) {
if(this.registered) {
ActionLog.record(user.ip, user.name, ["channel-register-failure", this.name]);
ActionLog.record(user.ip, user.name, "channel-register-failure", [this.name]);
user.socket.emit("registerChannel", {
success: false,
error: "This channel is already registered"
});
}
else if(!user.loggedIn) {
ActionLog.record(user.ip, user.name, ["channel-register-failure", this.name]);
ActionLog.record(user.ip, user.name, "channel-register-failure", [this.name]);
user.socket.emit("registerChannel", {
success: false,
error: "You must log in to register a channel"
@ -284,7 +284,7 @@ Channel.prototype.tryRegister = function(user) {
}
else if(!Rank.hasPermission(user, "registerChannel")) {
ActionLog.record(user.ip, user.name, ["channel-register-failure", this.name]);
ActionLog.record(user.ip, user.name, "channel-register-failure", [this.name]);
user.socket.emit("registerChannel", {
success: false,
error: "You don't have permission to register this channel"
@ -292,7 +292,7 @@ Channel.prototype.tryRegister = function(user) {
}
else {
if(Database.registerChannel(this.name)) {
ActionLog.record(user.ip, user.name, ["channel-register-success", this.name]);
ActionLog.record(user.ip, user.name, "channel-register-success", [this.name]);
this.registered = true;
this.initialized = true;
this.saveDump();

View File

@ -46,6 +46,8 @@
</div>
<div class="container">
<div class="row">
<div class="span12">
<div class="row">
<div class="span12">
<div class="btn-group">
@ -179,19 +181,23 @@
<h3>Action Log</h3>
<select multiple="multiple" id="actionlog_filter">
</select>
<button class="btn btn-danger" id="actionlog_clear">Clear</button>
<button class="btn btn-danger" id="actionlog_clear">Clear Selected</button>
<button class="btn" id="actionlog_refresh">Refresh</button>
<table class="table table-bordered table-striped table-compact">
<thead>
<tr>
<th>IP Address</th>
<th>Name</th>
<th>Action</th>
<th>Time</th>
<th id="actionlog_ip">IP Address</th>
<th id="actionlog_name">Name</th>
<th id="actionlog_action">Action</th>
<th>Args</th>
<th id="actionlog_time">Time</th>
</tr>
</thead>
</table>
</div>
</div>
</div>
</div>
</div> <!-- /container -->
<div class="push"></div>
<div id="sitefooter">

View File

@ -73,21 +73,53 @@ $("#show_actionlog").click(getActionLog);
$("#actionlog_filter").click(function() {
var actions = $(this).val();
$("#actionlog tbody").remove();
$("#actionlog table").data("entries").forEach(function(e) {
if(typeof e.action == "string" && actions.indexOf(e.action) == -1)
var entries = [];
$("#actionlog table").data("allentries").forEach(function(e) {
if(actions.indexOf(e.action) == -1)
return;
if(typeof e.action == "object" && "0" in e.action && actions.indexOf(e.action[0]) == -1)
return;
var tr = $("<tr/>").appendTo($("#actionlog table"));
$("<td/>").text(e.ip).appendTo(tr);
$("<td/>").text(e.name).appendTo(tr);
$("<td/>").text(e.action).appendTo(tr);
$("<td/>").text(new Date(e.time).toTimeString()).appendTo(tr);
entries.push(e);
});
$("#actionlog_pagination").remove();
if(entries.length > 20) {
var pag = $("<div/>").addClass("pagination")
.attr("id", "actionlog_pagination")
.insertAfter($("#actionlog table"));
var btns = $("<ul/>").appendTo(pag);
for(var i = 0; i < data.length / 20; i++) {
var li = $("<li/>").appendTo(btns);
(function(i) {
$("<a/>").attr("href", "javascript:void(0)")
.text(i+1)
.click(function() {
loadPage(tbl, i);
})
.appendTo(li);
})(i);
}
tbl.data("pagination", pag);
}
$("#actionlog table").data("entries", entries);
loadPage($("#actionlog table"), 0);
});
$("#actionlog_clear").click(function() {
socket.emit("acp-actionlog-clear");
socket.emit("acp-actionlog-clear", $("#actionlog_filter").val());
getActionLog();
});
$("#actionlog_refresh").click(function() {
getActionLog();
});
$("#actionlog_ip").click(function() {
tableResort($("#actionlog table"), "ip");
});
$("#actionlog_name").click(function() {
tableResort($("#actionlog table"), "name");
});
$("#actionlog_action").click(function() {
tableResort($("#actionlog table"), "action");
});
$("#actionlog_time").click(function() {
tableResort($("#actionlog table"), "time");
});
function getSyslog() {
@ -110,20 +142,24 @@ function getActionLog() {
var entry;
try {
entry = JSON.parse(ln);
if(typeof entry.action == "string") {
if(actions.indexOf(entry.action) == -1)
actions.push(entry.action);
}
else if(typeof entry.action == "object" && "0" in entry.action) {
if(actions.indexOf(entry.action[0]) == -1)
actions.push(entry.action[0]);
}
if(actions.indexOf(entry.action) == -1)
actions.push(entry.action);
entries.push(entry);
}
catch(e) { }
});
entries.sort(function(a, b) {
return a.time == b.time ? 0 : (a.time < b.time ? 1 : -1);
var tbl = $("#actionlog table");
tbl.data("sortby", "time");
tbl.data("sort_desc", true);
tbl.data("entries", entries);
tbl.data("allentries", entries);
tbl.data("generator", function(e) {
var tr = $("<tr/>").appendTo($("#actionlog table"));
$("<td/>").text(e.ip).appendTo(tr);
$("<td/>").text(e.name).appendTo(tr);
$("<td/>").text(e.action).appendTo(tr);
$("<td/>").text(e.args.join(", ")).appendTo(tr);
$("<td/>").text(new Date(e.time).toTimeString()).appendTo(tr);
});
$("#actionlog table").data("entries", entries);
$("#actionlog_filter").html("");
@ -133,6 +169,7 @@ function getActionLog() {
actions.forEach(function(a) {
$("<option/>").text(a).val(a).appendTo($("#actionlog_filter"));
});
loadPage(tbl, 0);
});
}
function getChanlog() {
@ -201,7 +238,7 @@ function loadPage(tbl, page) {
});
}
for(var i = page * 20; i < page * 20 + 20; i++) {
for(var i = page * 20; i < page * 20 + 20 && i < e.length; i++) {
generator(e[i]);
}
}
@ -356,6 +393,13 @@ function setupCallbacks() {
socket.on("acp-list-loaded", function(data) {
$("#channellist tbody").remove();
data.sort(function(a, b) {
if(a.usercount == b.usercount) {
var x = a.name, y = b.name;
return x == y ? 0 : (x < y ? -1 : 1);
}
return a.usercount < b.usercount ? -1 : 1;
});
var total = 0;
data.forEach(function(c) {
total += c.usercount;

View File

@ -12,6 +12,7 @@ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLI
var NotWebsocket = function() {
this.connected = false;
this.polltmr = false;
this.nws = true;
$.getJSON(WEB_URL + "/nws/connect?callback=?", function(data) {
this.hash = data;
this.connected = true;

View File

@ -515,10 +515,12 @@ function applyOpts() {
}
if(USEROPTS.altsocket) {
if(socket && socket.disconnect)
socket.disconnect();
socket = new NotWebsocket();
setupCallbacks();
if(!socket.nws) {
if(socket && socket.disconnect)
socket.disconnect();
socket = new NotWebsocket();
setupCallbacks();
}
}
// Switch from NotWebsocket => Socket.io
else if(socket && typeof socket.poll !== "undefined") {