Begin improving filters
This commit is contained in:
parent
9350ef6d75
commit
4b0e920dc6
66
channel.js
66
channel.js
|
|
@ -21,6 +21,7 @@ var io = require("./server.js").io;
|
||||||
var Rank = require("./rank.js");
|
var Rank = require("./rank.js");
|
||||||
var Auth = require("./auth.js");
|
var Auth = require("./auth.js");
|
||||||
var ChatCommand = require("./chatcommand.js");
|
var ChatCommand = require("./chatcommand.js");
|
||||||
|
var Filter = require("./filter.js").Filter;
|
||||||
|
|
||||||
var Channel = function(name) {
|
var Channel = function(name) {
|
||||||
Logger.syslog.log("Opening channel " + name);
|
Logger.syslog.log("Opening channel " + name);
|
||||||
|
|
@ -52,10 +53,9 @@ var Channel = function(name) {
|
||||||
chat_antiflood: false
|
chat_antiflood: false
|
||||||
};
|
};
|
||||||
this.filters = [
|
this.filters = [
|
||||||
[/`([^`]+)`/g , "<code>$1</code>" , true],
|
new Filter("monospace", "`([^`]+)`", "g", "<code>$1</code>"),
|
||||||
[/\*([^\*]+)\*/g , "<strong>$1</strong>", true],
|
new Filter("bold", "\\*([^\\*]+)\\*", "g", "<strong>$1</strong>"),
|
||||||
[/(^| )_([^_]+)_/g , "$1<em>$2</em>" , true],
|
new Filter("italic", "(^| )_([^_]+)_", "g", "$1<em>$2</em>"),
|
||||||
[/\\\\([-a-zA-Z0-9]+)/g, "[](/$1)" , true]
|
|
||||||
];
|
];
|
||||||
this.motd = {
|
this.motd = {
|
||||||
motd: "",
|
motd: "",
|
||||||
|
|
@ -117,9 +117,16 @@ Channel.prototype.loadDump = function() {
|
||||||
if(data.filters) {
|
if(data.filters) {
|
||||||
this.filters = new Array(data.filters.length);
|
this.filters = new Array(data.filters.length);
|
||||||
for(var i = 0; i < data.filters.length; i++) {
|
for(var i = 0; i < data.filters.length; i++) {
|
||||||
this.filters[i] = [new RegExp(data.filters[i][0], "g"),
|
var f = data.filters[i];
|
||||||
data.filters[i][1],
|
// Backwards compatibility
|
||||||
data.filters[i][2]];
|
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) {
|
if(data.motd) {
|
||||||
|
|
@ -136,9 +143,7 @@ Channel.prototype.loadDump = function() {
|
||||||
Channel.prototype.saveDump = function() {
|
Channel.prototype.saveDump = function() {
|
||||||
var filts = new Array(this.filters.length);
|
var filts = new Array(this.filters.length);
|
||||||
for(var i = 0; i < this.filters.length; i++) {
|
for(var i = 0; i < this.filters.length; i++) {
|
||||||
filts[i] = [this.filters[i][0].source,
|
filts[i] = this.filters[i].pack();
|
||||||
this.filters[i][1],
|
|
||||||
this.filters[i][2]];
|
|
||||||
}
|
}
|
||||||
var dump = {
|
var dump = {
|
||||||
position: this.position,
|
position: this.position,
|
||||||
|
|
@ -400,7 +405,7 @@ Channel.prototype.sendRankStuff = function(user) {
|
||||||
if(Rank.hasPermission(user, "chatFilter")) {
|
if(Rank.hasPermission(user, "chatFilter")) {
|
||||||
var filts = new Array(this.filters.length);
|
var filts = new Array(this.filters.length);
|
||||||
for(var i = 0; i < this.filters.length; i++) {
|
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});
|
user.socket.emit("chatFilters", {filters: filts});
|
||||||
}
|
}
|
||||||
|
|
@ -545,7 +550,7 @@ Channel.prototype.broadcastRankTable = function() {
|
||||||
Channel.prototype.broadcastChatFilters = function() {
|
Channel.prototype.broadcastChatFilters = function() {
|
||||||
var filts = new Array(this.filters.length);
|
var filts = new Array(this.filters.length);
|
||||||
for(var i = 0; i < this.filters.length; i++) {
|
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++) {
|
for(var i = 0; i < this.users.length; i++) {
|
||||||
if(Rank.hasPermission(this.users[i], "chatFilter")) {
|
if(Rank.hasPermission(this.users[i], "chatFilter")) {
|
||||||
|
|
@ -1054,10 +1059,10 @@ Channel.prototype.trySetLock = function(user, data) {
|
||||||
Channel.prototype.updateFilter = function(filter) {
|
Channel.prototype.updateFilter = function(filter) {
|
||||||
var found = false;
|
var found = false;
|
||||||
for(var i = 0; i < this.filters.length; i++) {
|
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;
|
found = true;
|
||||||
this.filters[i][1] = filter[1];
|
this.filters[i] = filter;
|
||||||
this.filters[i][2] = filter[2];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!found) {
|
if(!found) {
|
||||||
|
|
@ -1066,9 +1071,10 @@ Channel.prototype.updateFilter = function(filter) {
|
||||||
this.broadcastChatFilters();
|
this.broadcastChatFilters();
|
||||||
}
|
}
|
||||||
|
|
||||||
Channel.prototype.removeFilter = function(regex) {
|
Channel.prototype.removeFilter = function(name, source) {
|
||||||
for(var i = 0; i < this.filters.length; i++) {
|
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);
|
this.filters.splice(i, 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1086,23 +1092,23 @@ Channel.prototype.tryChangeFilter = function(user, data) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data.cmd == "update") {
|
if(data.cmd == "update") {
|
||||||
var re = data.filter[0];
|
var re = data.filter.source;
|
||||||
var flags = "g";
|
var flags = data.filter.flags;
|
||||||
var slash = re.lastIndexOf("/");
|
|
||||||
if(slash > 0 && re[slash-1] != "\\") {
|
|
||||||
flags = re.substring(slash+1);
|
|
||||||
re = re.substring(0, slash);
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
data.filter[0] = new RegExp(re, flags);
|
new RegExp(re, flags);
|
||||||
}
|
}
|
||||||
catch(e) {
|
catch(e) {
|
||||||
return;
|
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") {
|
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>");
|
msg = msg.replace(/(((https?)|(ftp))(:\/\/[0-9a-zA-Z\.]+(:[0-9]+)?[^\s$]+))/g, "<a href=\"$1\" target=\"_blank\">$1</a>");
|
||||||
// Apply other filters
|
// Apply other filters
|
||||||
for(var i = 0; i < this.filters.length; i++) {
|
for(var i = 0; i < this.filters.length; i++) {
|
||||||
if(!this.filters[i][2])
|
if(!this.filters[i].active)
|
||||||
continue;
|
continue;
|
||||||
var regex = this.filters[i][0];
|
msg = this.filters[i].filter(msg);
|
||||||
var replace = this.filters[i][1];
|
|
||||||
msg = msg.replace(regex, replace);
|
|
||||||
}
|
}
|
||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
24
filter.js
Normal file
24
filter.js
Normal 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;
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
"author": "Calvin Montgomery",
|
"author": "Calvin Montgomery",
|
||||||
"name": "CyTube",
|
"name": "CyTube",
|
||||||
"description": "Online media synchronizer and chat",
|
"description": "Online media synchronizer and chat",
|
||||||
"version": "1.4.3",
|
"version": "1.4.4",
|
||||||
"repository": {
|
"repository": {
|
||||||
"url": "http://github.com/calzoneman/sync"
|
"url": "http://github.com/calzoneman/sync"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -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.
|
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 fs = require("fs");
|
||||||
var Logger = require("./logger.js");
|
var Logger = require("./logger.js");
|
||||||
|
|
|
||||||
|
|
@ -618,24 +618,29 @@ function updateChatFilters(entries) {
|
||||||
$(tbl.children()[1]).remove();
|
$(tbl.children()[1]).remove();
|
||||||
}
|
}
|
||||||
for(var i = 0; i < entries.length; i++) {
|
for(var i = 0; i < entries.length; i++) {
|
||||||
|
var f = entries[i];
|
||||||
var tr = $("<tr/>").appendTo(tbl);
|
var tr = $("<tr/>").appendTo(tbl);
|
||||||
var remove = $("<button/>").addClass("btn btn-mini btn-danger")
|
var remove = $("<button/>").addClass("btn btn-mini btn-danger")
|
||||||
.appendTo($("<td/>").appendTo(tr));
|
.appendTo($("<td/>").appendTo(tr));
|
||||||
$("<i/>").addClass("icon-remove-circle").appendTo(remove);
|
$("<i/>").addClass("icon-remove-circle").appendTo(remove);
|
||||||
var regex = $("<code/>").text(entries[i][0])
|
var name = $("<code/>").text(f.name)
|
||||||
.appendTo($("<td/>").appendTo(tr));
|
.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));
|
.appendTo($("<td/>").appendTo(tr));
|
||||||
var activetd = $("<td/>").appendTo(tr);
|
var activetd = $("<td/>").appendTo(tr);
|
||||||
var active = $("<input/>").attr("type", "checkbox")
|
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() {
|
var remcallback = (function(filter) { return function() {
|
||||||
socket.emit("chatFilter", {
|
socket.emit("chatFilter", {
|
||||||
cmd: "remove",
|
cmd: "remove",
|
||||||
filter: filter
|
filter: filter
|
||||||
});
|
});
|
||||||
} })(entries[i]);
|
} })(f);
|
||||||
remove.click(remcallback);
|
remove.click(remcallback);
|
||||||
|
|
||||||
var actcallback = (function(filter) { return function() {
|
var actcallback = (function(filter) { return function() {
|
||||||
|
|
@ -644,33 +649,33 @@ function updateChatFilters(entries) {
|
||||||
// changed before this callback
|
// changed before this callback
|
||||||
// [](/amgic)
|
// [](/amgic)
|
||||||
var enabled = active.prop("checked");
|
var enabled = active.prop("checked");
|
||||||
filter[2] = (filter[2] == enabled) ? !enabled : enabled;
|
filter.active = (filter.active == enabled) ? !enabled : enabled;
|
||||||
socket.emit("chatFilter", {
|
socket.emit("chatFilter", {
|
||||||
cmd: "update",
|
cmd: "update",
|
||||||
filter: filter
|
filter: filter
|
||||||
});
|
});
|
||||||
} })(entries[i]);
|
} })(f);
|
||||||
active.click(actcallback);
|
active.click(actcallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
var newfilt = $("<tr/>").appendTo(tbl);
|
var newfilt = $("<tr/>").appendTo(tbl);
|
||||||
$("<td/>").appendTo(newfilt);
|
$("<td/>").appendTo(newfilt);
|
||||||
|
var name = $("<input/>").attr("type", "text")
|
||||||
|
.appendTo($("<td/>").appendTo(newfilt));
|
||||||
var regex = $("<input/>").attr("type", "text")
|
var regex = $("<input/>").attr("type", "text")
|
||||||
.appendTo($("<td/>").appendTo(newfilt));
|
.appendTo($("<td/>").appendTo(newfilt));
|
||||||
|
var flags = $("<input/>").attr("type", "text")
|
||||||
|
.val("g")
|
||||||
|
.appendTo($("<td/>").appendTo(newfilt));
|
||||||
var replace = $("<input/>").attr("type", "text")
|
var replace = $("<input/>").attr("type", "text")
|
||||||
.appendTo($("<td/>").appendTo(newfilt));
|
.appendTo($("<td/>").appendTo(newfilt));
|
||||||
var add = $("<button/>").addClass("btn btn-primary")
|
var add = $("<button/>").addClass("btn btn-primary")
|
||||||
.text("Add Filter")
|
.text("Add Filter")
|
||||||
.appendTo($("<td/>").appendTo(newfilt));
|
.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()) {
|
if(regex.val() && replace.val()) {
|
||||||
var re = regex.val();
|
var re = regex.val();
|
||||||
var flags = "g";
|
var flags = fg.val();
|
||||||
var slash = re.lastIndexOf("/");
|
|
||||||
if(slash > 0 && re[slash-1] != "\\") {
|
|
||||||
flags = re.substring(slash+1);
|
|
||||||
re = re.substring(0, slash);
|
|
||||||
}
|
|
||||||
try {
|
try {
|
||||||
var dummy = new RegExp(re, flags);
|
var dummy = new RegExp(re, flags);
|
||||||
}
|
}
|
||||||
|
|
@ -679,10 +684,16 @@ function updateChatFilters(entries) {
|
||||||
}
|
}
|
||||||
socket.emit("chatFilter", {
|
socket.emit("chatFilter", {
|
||||||
cmd: "update",
|
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);
|
add.click(cback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -124,7 +124,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row" style="display: none;" id="modnav">
|
<div class="row" style="display: none;" id="modnav">
|
||||||
<div class="span10 offset1" id="modtabs">
|
<div class="span12" id="modtabs">
|
||||||
<ul class="nav nav-tabs">
|
<ul class="nav nav-tabs">
|
||||||
<li class="active">
|
<li class="active">
|
||||||
<a href="javascript:void(0)" id="show_chancontrols">Channel Controls</a>
|
<a href="javascript:void(0)" id="show_chancontrols">Channel Controls</a>
|
||||||
|
|
@ -145,10 +145,10 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row modonly" style="display: none" id="chancontrols">
|
<div class="row modonly" style="display: none" id="chancontrols">
|
||||||
<div class="span10 offset1">
|
<div class="span12">
|
||||||
<form action="javascript:void(0)">
|
<form action="javascript:void(0)">
|
||||||
<fieldset>
|
<fieldset>
|
||||||
<div class="span4">
|
<div class="span5">
|
||||||
<label>When the queue is open:</label>
|
<label>When the queue is open:</label>
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
<input type="checkbox" id="opt_qopen_allow_qnext">
|
<input type="checkbox" id="opt_qopen_allow_qnext">
|
||||||
|
|
@ -203,7 +203,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row modonly" id="banlist" style="display: none;">
|
<div class="row modonly" id="banlist" style="display: none;">
|
||||||
<div class="span10 offset1">
|
<div class="span12">
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<th></th>
|
<th></th>
|
||||||
|
|
@ -215,17 +215,19 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row modonly" id="motdeditor" style="display: none;">
|
<div class="row modonly" id="motdeditor" style="display: none;">
|
||||||
<div class="span10 offset1">
|
<div class="span12">
|
||||||
<textarea rows="10" id="motdtext"></textarea>
|
<textarea rows="10" id="motdtext"></textarea>
|
||||||
<button class="btn btn-primary" id="updatemotd">Update</button>
|
<button class="btn btn-primary" id="updatemotd">Update</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row modonly" id="filtereditor" style="display: none;">
|
<div class="row modonly" id="filtereditor" style="display: none;">
|
||||||
<div class="span10 offset1">
|
<div class="span12">
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<th></th>
|
<th></th>
|
||||||
|
<th>Name</th>
|
||||||
<th>Regex</th>
|
<th>Regex</th>
|
||||||
|
<th>Flags</th>
|
||||||
<th>Replacement</th>
|
<th>Replacement</th>
|
||||||
<th>Active</th>
|
<th>Active</th>
|
||||||
</thead>
|
</thead>
|
||||||
|
|
@ -233,7 +235,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row modonly" id="channelranks" style="display: none;">
|
<div class="row modonly" id="channelranks" style="display: none;">
|
||||||
<div class="span10 offset1">
|
<div class="span12">
|
||||||
<table class="table table-striped">
|
<table class="table table-striped">
|
||||||
<thead>
|
<thead>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue