Begin improving filters

This commit is contained in:
calzoneman 2013-04-29 12:29:31 -05:00
parent 9350ef6d75
commit 4b0e920dc6
6 changed files with 96 additions and 55 deletions

View file

@ -21,6 +21,7 @@ var io = require("./server.js").io;
var Rank = require("./rank.js");
var Auth = require("./auth.js");
var ChatCommand = require("./chatcommand.js");
var Filter = require("./filter.js").Filter;
var Channel = function(name) {
Logger.syslog.log("Opening channel " + name);
@ -52,10 +53,9 @@ var Channel = function(name) {
chat_antiflood: false
};
this.filters = [
[/`([^`]+)`/g , "<code>$1</code>" , true],
[/\*([^\*]+)\*/g , "<strong>$1</strong>", true],
[/(^| )_([^_]+)_/g , "$1<em>$2</em>" , true],
[/\\\\([-a-zA-Z0-9]+)/g, "[](/$1)" , true]
new Filter("monospace", "`([^`]+)`", "g", "<code>$1</code>"),
new Filter("bold", "\\*([^\\*]+)\\*", "g", "<strong>$1</strong>"),
new Filter("italic", "(^| )_([^_]+)_", "g", "$1<em>$2</em>"),
];
this.motd = {
motd: "",
@ -117,9 +117,16 @@ Channel.prototype.loadDump = function() {
if(data.filters) {
this.filters = new Array(data.filters.length);
for(var i = 0; i < data.filters.length; i++) {
this.filters[i] = [new RegExp(data.filters[i][0], "g"),
data.filters[i][1],
data.filters[i][2]];
var f = data.filters[i];
// Backwards compatibility
if(f[0] != undefined) {
this.filters[i] = new Filter("", f[0], "g", f[1]);
this.filters[i].active = f[2];
}
else {
this.filters[i] = new Filter(f.name, f.source, f.flags, f.replace);
this.filters[i].active = f.active;
}
}
}
if(data.motd) {
@ -136,9 +143,7 @@ Channel.prototype.loadDump = function() {
Channel.prototype.saveDump = function() {
var filts = new Array(this.filters.length);
for(var i = 0; i < this.filters.length; i++) {
filts[i] = [this.filters[i][0].source,
this.filters[i][1],
this.filters[i][2]];
filts[i] = this.filters[i].pack();
}
var dump = {
position: this.position,
@ -400,7 +405,7 @@ Channel.prototype.sendRankStuff = function(user) {
if(Rank.hasPermission(user, "chatFilter")) {
var filts = new Array(this.filters.length);
for(var i = 0; i < this.filters.length; i++) {
filts[i] = [this.filters[i][0].source, this.filters[i][1], this.filters[i][2]];
filts[i] = this.filters[i].pack();
}
user.socket.emit("chatFilters", {filters: filts});
}
@ -545,7 +550,7 @@ Channel.prototype.broadcastRankTable = function() {
Channel.prototype.broadcastChatFilters = function() {
var filts = new Array(this.filters.length);
for(var i = 0; i < this.filters.length; i++) {
filts[i] = [this.filters[i][0].source, this.filters[i][1], this.filters[i][2]];
filts[i] = this.filters[i].pack();
}
for(var i = 0; i < this.users.length; i++) {
if(Rank.hasPermission(this.users[i], "chatFilter")) {
@ -1054,10 +1059,10 @@ Channel.prototype.trySetLock = function(user, data) {
Channel.prototype.updateFilter = function(filter) {
var found = false;
for(var i = 0; i < this.filters.length; i++) {
if(this.filters[i][0].source == filter[0].source) {
if(this.filters[i].name == filter.name
&& this.filters[i].source == filter.source) {
found = true;
this.filters[i][1] = filter[1];
this.filters[i][2] = filter[2];
this.filters[i] = filter;
}
}
if(!found) {
@ -1066,9 +1071,10 @@ Channel.prototype.updateFilter = function(filter) {
this.broadcastChatFilters();
}
Channel.prototype.removeFilter = function(regex) {
Channel.prototype.removeFilter = function(name, source) {
for(var i = 0; i < this.filters.length; i++) {
if(this.filters[i][0].source == regex) {
if(this.filters[i].name == name
&& this.filters[i].source == source) {
this.filters.splice(i, 1);
break;
}
@ -1086,23 +1092,23 @@ Channel.prototype.tryChangeFilter = function(user, data) {
}
if(data.cmd == "update") {
var re = data.filter[0];
var flags = "g";
var slash = re.lastIndexOf("/");
if(slash > 0 && re[slash-1] != "\\") {
flags = re.substring(slash+1);
re = re.substring(0, slash);
}
var re = data.filter.source;
var flags = data.filter.flags;
try {
data.filter[0] = new RegExp(re, flags);
new RegExp(re, flags);
}
catch(e) {
return;
}
this.updateFilter(data.filter);
var f = new Filter(data.filter.name,
data.filter.source,
data.filter.flags,
data.filter.replace);
f.active = data.filter.active;
this.updateFilter(f);
}
else if(data.cmd == "remove") {
this.removeFilter(data.filter[0]);
this.removeFilter(data.filter.name, data.filter.source);
}
}
@ -1182,11 +1188,9 @@ Channel.prototype.filterMessage = function(msg) {
msg = msg.replace(/(((https?)|(ftp))(:\/\/[0-9a-zA-Z\.]+(:[0-9]+)?[^\s$]+))/g, "<a href=\"$1\" target=\"_blank\">$1</a>");
// Apply other filters
for(var i = 0; i < this.filters.length; i++) {
if(!this.filters[i][2])
if(!this.filters[i].active)
continue;
var regex = this.filters[i][0];
var replace = this.filters[i][1];
msg = msg.replace(regex, replace);
msg = this.filters[i].filter(msg);
}
return msg;
}

24
filter.js Normal file
View file

@ -0,0 +1,24 @@
var Filter = function(name, regex, flags, replace) {
this.name = name;
this.source = regex;
this.flags = flags;
this.regex = new RegExp(this.source, this.flags);
this.replace = replace;
this.active = true;
}
Filter.prototype.pack = function() {
return {
name: this.name,
source: this.source,
flags: this.flags,
replace: this.replace,
active: this.active
}
}
Filter.prototype.filter = function(text) {
return text.replace(this.regex, this.replace);
}
exports.Filter = Filter;

View file

@ -2,7 +2,7 @@
"author": "Calvin Montgomery",
"name": "CyTube",
"description": "Online media synchronizer and chat",
"version": "1.4.3",
"version": "1.4.4",
"repository": {
"url": "http://github.com/calzoneman/sync"
},

View file

@ -9,7 +9,7 @@ The above copyright notice and this permission notice shall be included in all c
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.
*/
const VERSION = "1.4.3";
const VERSION = "1.4.4";
var fs = require("fs");
var Logger = require("./logger.js");

View file

@ -618,24 +618,29 @@ function updateChatFilters(entries) {
$(tbl.children()[1]).remove();
}
for(var i = 0; i < entries.length; i++) {
var f = entries[i];
var tr = $("<tr/>").appendTo(tbl);
var remove = $("<button/>").addClass("btn btn-mini btn-danger")
.appendTo($("<td/>").appendTo(tr));
$("<i/>").addClass("icon-remove-circle").appendTo(remove);
var regex = $("<code/>").text(entries[i][0])
var name = $("<code/>").text(f.name)
.appendTo($("<td/>").appendTo(tr));
var replace = $("<code/>").text(entries[i][1])
var regex = $("<code/>").text(f.source)
.appendTo($("<td/>").appendTo(tr));
var flags = $("<code/>").text(f.flags)
.appendTo($("<td/>").appendTo(tr));
var replace = $("<code/>").text(f.replace)
.appendTo($("<td/>").appendTo(tr));
var activetd = $("<td/>").appendTo(tr);
var active = $("<input/>").attr("type", "checkbox")
.prop("checked", entries[i][2]).appendTo(activetd);
.prop("checked", f.active).appendTo(activetd);
var remcallback = (function(filter) { return function() {
socket.emit("chatFilter", {
cmd: "remove",
filter: filter
});
} })(entries[i]);
} })(f);
remove.click(remcallback);
var actcallback = (function(filter) { return function() {
@ -644,33 +649,33 @@ function updateChatFilters(entries) {
// changed before this callback
// [](/amgic)
var enabled = active.prop("checked");
filter[2] = (filter[2] == enabled) ? !enabled : enabled;
filter.active = (filter.active == enabled) ? !enabled : enabled;
socket.emit("chatFilter", {
cmd: "update",
filter: filter
});
} })(entries[i]);
} })(f);
active.click(actcallback);
}
var newfilt = $("<tr/>").appendTo(tbl);
$("<td/>").appendTo(newfilt);
var name = $("<input/>").attr("type", "text")
.appendTo($("<td/>").appendTo(newfilt));
var regex = $("<input/>").attr("type", "text")
.appendTo($("<td/>").appendTo(newfilt));
var flags = $("<input/>").attr("type", "text")
.val("g")
.appendTo($("<td/>").appendTo(newfilt));
var replace = $("<input/>").attr("type", "text")
.appendTo($("<td/>").appendTo(newfilt));
var add = $("<button/>").addClass("btn btn-primary")
.text("Add Filter")
.appendTo($("<td/>").appendTo(newfilt));
var cback = (function(regex, replace) { return function() {
var cback = (function(name, regex, fg, replace) { return function() {
if(regex.val() && replace.val()) {
var re = regex.val();
var flags = "g";
var slash = re.lastIndexOf("/");
if(slash > 0 && re[slash-1] != "\\") {
flags = re.substring(slash+1);
re = re.substring(0, slash);
}
var flags = fg.val();
try {
var dummy = new RegExp(re, flags);
}
@ -679,10 +684,16 @@ function updateChatFilters(entries) {
}
socket.emit("chatFilter", {
cmd: "update",
filter: [regex.val(), replace.val(), true]
filter: {
name: name.val(),
source: re,
flags: flags,
replace: replace.val(),
active: true
}
});
}
} })(regex, replace);
} })(name, regex, flags, replace);
add.click(cback);
}

View file

@ -124,7 +124,7 @@
</div>
</div>
<div class="row" style="display: none;" id="modnav">
<div class="span10 offset1" id="modtabs">
<div class="span12" id="modtabs">
<ul class="nav nav-tabs">
<li class="active">
<a href="javascript:void(0)" id="show_chancontrols">Channel Controls</a>
@ -145,10 +145,10 @@
</div>
</div>
<div class="row modonly" style="display: none" id="chancontrols">
<div class="span10 offset1">
<div class="span12">
<form action="javascript:void(0)">
<fieldset>
<div class="span4">
<div class="span5">
<label>When the queue is open:</label>
<label class="checkbox">
<input type="checkbox" id="opt_qopen_allow_qnext">
@ -203,7 +203,7 @@
</div>
</div>
<div class="row modonly" id="banlist" style="display: none;">
<div class="span10 offset1">
<div class="span12">
<table class="table table-striped">
<thead>
<th></th>
@ -215,17 +215,19 @@
</div>
</div>
<div class="row modonly" id="motdeditor" style="display: none;">
<div class="span10 offset1">
<div class="span12">
<textarea rows="10" id="motdtext"></textarea>
<button class="btn btn-primary" id="updatemotd">Update</button>
</div>
</div>
<div class="row modonly" id="filtereditor" style="display: none;">
<div class="span10 offset1">
<div class="span12">
<table class="table table-striped">
<thead>
<th></th>
<th>Name</th>
<th>Regex</th>
<th>Flags</th>
<th>Replacement</th>
<th>Active</th>
</thead>
@ -233,7 +235,7 @@
</div>
</div>
<div class="row modonly" id="channelranks" style="display: none;">
<div class="span10 offset1">
<div class="span12">
<table class="table table-striped">
<thead>
<th>Name</th>