diff --git a/lib/acp.js b/lib/acp.js index 0c0edfd7..21f157e3 100644 --- a/lib/acp.js +++ b/lib/acp.js @@ -188,6 +188,58 @@ function handleResetPassword(user, data) { }); } +function handleListChannels(user, data) { + var field = data.field; + var value = data.value; + if (typeof field !== "string" || typeof value !== "string") { + return; + } + + var dbfunc; + if (field === "owner") { + dbfunc = db.channels.searchOwner; + } else { + dbfunc = db.channels.search; + } + + dbfunc(value, function (err, rows) { + if (err) { + user.socket.emit("errMessage", { + msg: err + }); + return; + } + + user.socket.emit("acp-list-channels", rows); + }); +} + +function handleDeleteChannel(user, data) { + var name = data.name; + if (typeof data.name !== "string") { + return; + } + + var sv = Server.getServer(); + if (sv.isChannelLoaded(name)) { + sv.getChannel(name).users.forEach(function (u) { + u.kick("Channel shutting down"); + }); + } + + db.channels.drop(name, function (err) { + if (err) { + user.socket.emit("errMessage", { + msg: err + }); + } else { + user.socket.emit("acp-delete-channel", { + name: name + }); + } + }); +} + function init(user) { var s = user.socket; s.on("acp-announce", handleAnnounce.bind(this, user)); @@ -197,6 +249,8 @@ function init(user) { s.on("acp-list-users", handleListUsers.bind(this, user)); s.on("acp-set-rank", handleSetRank.bind(this, user)); s.on("acp-reset-password", handleResetPassword.bind(this, user)); + s.on("acp-list-channels", handleListChannels.bind(this, user)); + s.on("acp-delete-channel", handleDeleteChannel.bind(this, user)); db.listGlobalBans(function (err, bans) { if (err) { diff --git a/lib/database/channels.js b/lib/database/channels.js index 2a806c09..477bb7c0 100644 --- a/lib/database/channels.js +++ b/lib/database/channels.js @@ -175,6 +175,25 @@ module.exports = { }); }, + /** + * Searches for a channel by owner + */ + searchOwner: function (name, callback) { + if (typeof callback !== "function") { + return; + } + + db.query("SELECT * FROM `channels` WHERE owner LIKE ?", + ["%" + name + "%"], + function (err, rows) { + if (err) { + callback(err, null); + return; + } + callback(null, rows); + }); + }, + /** * Validates and registers a new channel */ @@ -266,7 +285,7 @@ module.exports = { fs.unlink(path.join(__dirname, "..", "..", "chandump", name), function (err) { - if (err) { + if (err && err.code !== "ENOENT") { Logger.errlog.log("Deleting chandump failed:"); Logger.errlog.log(err); } diff --git a/templates/acp.jade b/templates/acp.jade index 45fcf3f1..ffacaf9d 100644 --- a/templates/acp.jade +++ b/templates/acp.jade @@ -94,9 +94,10 @@ html(lang="en") table.table.table-bordered.table-striped(style="margin-top: 20px") thead tr - th ID - th Name - th Owner + th.sort(data-key="id") ID + th.sort(data-key="name") Name + th.sort(data-key="owner") Owner + th Control #acp-loaded-channels.acp-panel.col-md-12(style="display: none") h3 Loaded Channels button#acp-lchannels-refresh.btn.btn-default Refresh diff --git a/www/js/acp.js b/www/js/acp.js index e879a534..ab89d167 100644 --- a/www/js/acp.js +++ b/www/js/acp.js @@ -253,6 +253,99 @@ socket.on("acp-set-rank", function (data) { .innerHTML = data.rank; }); +/* Channel listing */ +(function () { + var doSearch = function () { + if ($("#acp-clookup-value").val().trim() === "") { + if (!confirm("You are about to list the entire channels table. " + + "This table might be very large and take a long " + + "time to query. Continue?")) { + return; + } + } + socket.emit("acp-list-channels", { + field: $("#acp-clookup-field").val(), + value: $("#acp-clookup-value").val() + }); + }; + + $("#acp-clookup-submit").click(doSearch); + $("#acp-clookup-value").keyup(function (ev) { + if (ev.keyCode === 13) { + doSearch(); + } + }); +})(); + +socket.on("acp-list-channels", function (channels) { + var tbl = $("#acp-channel-lookup table"); + tbl.data("entries", channels); + var p = tbl.data("paginator"); + if (p) { + p.paginator.remove(); + } + + var opts = { + preLoadPage: function () { + tbl.find("tbody").remove(); + }, + + generator: function (c, page, index) { + var tr = $("