Add URLs to git repositories for this plugin to '/FILTER VERSION' output
[softsnow_xchat2_filter.git] / SoftSnow_filter.pl
blob60c785751a9b804cb1e2c7ff0ded461d9994a531
1 #!/usr/bin/perl
3 use strict;
4 use warnings;
6 ### config ###
7 my $filter_file = Xchat::get_info("xchatdir") . "/SoftSnow_filter.conf";
8 ### end config ###
10 my $scriptName = "SoftSnow XChat2 Filter";
11 my $scriptVersion = "2.0.1";
12 my $scriptDescr = "Filter out file server announcements and IRC SPAM";
14 my $B = "\cB"; # bold
15 my $U = "\cU"; # underline
16 my $C = "\cC"; # start of color sequence
18 my $command_list = 'ON|OFF|STATUS|SERVER|SERVERON|ALL|HELP|DEBUG|PRINT|ALLOW|ADD|DELETE|SAVE|LOAD';
20 my $scriptHelp = <<"EOF";
21 ${B}/FILTER $command_list${B}
22 /FILTER ON|OFF - turns filtering on/off
23 /FILTER HELP - prints this help message
24 /FILTER STATUS - prints if filter is turned on, and with what limits
25 /FILTER DEBUG - shows some info; used in debuggin the filter
26 /FILTER PRINT - prints all the rules
27 /FILTER ALLOW - toggle use of ALLOW rules (before DENY).
28 /FILTER SERVER - limits filtering to current server (host)
29 /FILTER SERVERON - limits to server and turns filter on
30 /FILTER ALL - resumes filtering everywhere i.e. removes limits
31 /FILTER SAVE - saves the rules to the file $filter_file
32 /FILTER LOAD - loads the rules from the file, replacing existing rules
33 /FILTER ADD <rule> - add rule at the end of the DENY rules
34 /FILTER DELETE [<num>] - delete rule number <num>, or last rule
35 /FILTER VERSION - prints the name and version of this script
36 /FILTER without parameter is equivalent to /FILTER STATUS
37 EOF
39 Xchat::register($scriptName, $scriptVersion, $scriptDescr);
41 Xchat::hook_command("FILTER", \&filter_command_handler,
42 { help_text => $scriptHelp });
43 Xchat::hook_server("PRIVMSG", \&privmsg_handler);
45 Xchat::print("Loading ${B}$scriptName $scriptVersion${B}\n".
46 " For help: ${B}/FILTER HELP${B}\n");
48 my $filter_turned_on = 0; # was default turned ON
49 my $limit_to_server = 0; # don't limit to server (host)
50 my $use_filter_allow = 0; # use overrides
52 # information about (default) options used
53 if ($filter_turned_on) {
54 Xchat::print("Filter turned ${B}ON${B}\n");
55 } else {
56 Xchat::print("Filter turned ${B}OFF${B}\n");
58 if ($limit_to_server) {
59 Xchat::print("Filter limited to server $limit_to_server\n")
61 if ($use_filter_allow) {
62 Xchat::print("Filter uses ALLOW rules\n");
65 # ------------------------------------------------------------
67 my @filter_allow = (
68 q/^\@search\s/,
71 my @filter_deny = (
72 q/\@/,
73 q/^\s*\!/,
74 q/slot\(s\)/,
75 #q/~&~&~/,
77 #xdcc
78 q/^\#\d+/,
80 #fserves
81 q/(?i)fserve.*trigger/,
82 q/(?i)trigger.*\!/,
83 q/(?i)trigger.*\/ctcp/,
84 q/(?i)type\:\s*\!/,
85 q/(?i)file server online/,
87 #ftps
88 q/(?i)ftp.*l\/p/,
90 #CTCPs
91 q/SLOTS/,
92 q/MP3 /,
94 #messages for when a file is received/failed to receive
95 q/(?i)DEFINITELY had the right stuff to get/,
96 q/(?i)has just received/,
97 q/(?i)I have just received/,
99 #mp3 play messages
100 q/is listening to/,
101 q/\]\-MP3INFO\-\[/,
103 #spammy scripts
104 q/\]\-SpR\-\[/,
105 q/We are BORG/,
107 #general messages
108 q/brave soldier in the war/,
111 # return 1 (true) if text given as argument is to be filtered out
112 sub isFiltered {
113 my $text = shift;
114 my $regexp = '';
116 #strip colour, underline, bold codes, etc.
117 $text = Xchat::strip_code($text);
119 if ($use_filter_allow) {
120 foreach $regexp (@filter_allow) {
121 return 0 if ($text =~ /$regexp/);
125 foreach $regexp (@filter_deny) {
126 return 1 if ($text =~ /$regexp/);
129 return 0;
132 #called when someone says something in the channel
133 #1: address of speaker
134 #2: PRIVMSG constant
135 #3: channel
136 #4: text said (prefixed with :)
137 sub privmsg_handler {
138 # $_[0] - array reference containing the IRC message or command
139 # and arguments broken into words
140 # $_[1] - array reference containing the Nth word to the last word
141 #my ($address, $constant, $chan) = @{$_[0]};
142 my $text = $_[1][3]; # Get server message
144 my $server = Xchat::get_info("host");
147 return Xchat::EAT_NONE unless $filter_turned_on;
148 if ($limit_to_server) {
149 return Xchat::EAT_NONE unless $server eq $limit_to_server;
152 $text =~ s/^://;
154 return isFiltered($text) ? Xchat::EAT_ALL : Xchat::EAT_NONE;
157 # ------------------------------------------------------------
159 sub save_filter {
160 open F, ">$filter_file"
161 or do {
162 Xchat::print("${B}FILTER:${B} Couldn't open file to save filter: $!\n");
163 return 1;
166 Xchat::print("${B}FILTER SAVE >$filter_file${B}\n");
167 foreach my $regexp (@filter_deny) {
168 Xchat::print("/".$regexp."/ saved\n");
169 print F $regexp."\n";
171 Xchat::print("${B}FILTER SAVED ----------${B}\n");
172 close F
173 or do {
174 Xchat::print("${B}FILTER:${B} Couldn't close file to save filter: $!\n");
175 return 1;
177 return 1;
180 sub load_filter {
181 Xchat::print("${B}FILTER:${B} ...loading filter patterns\n");
182 open F, "<$filter_file"
183 or do {
184 Xchat::print("${B}FILTER:${B} Couldn't open file to load filter: $!\n");
185 return 1;
187 @filter_deny = <F>;
188 map (chomp, @filter_deny);
189 close F;
191 Xchat::print("${B}FILTER DENY ----------${B}\n");
192 for (my $i = 0; $i <= $#filter_deny; $i++) {
193 Xchat::print(" [$i]: /".$filter_deny[$i]."/\n");
195 Xchat::print("${B}FILTER DENY ----------${B}\n");
198 sub add_rule ( $ ) {
199 my $rule = shift;
201 # always ading rules at the end
202 push @filter_deny, $rule;
205 sub delete_rule ( $ ) {
206 my $num = shift || $#filter_deny;
208 splice @filter_deny, $num, 1;
211 # ============================================================
212 # ============================================================
213 # ============================================================
215 sub filter_command_handler {
216 my $arg = $_[1][1]; # 1st word to the last word
217 my $server = Xchat::get_info("host");
219 #Xchat::print("/filter arg: |$arg|\n");
220 if (!$arg || $arg =~ /^STATUS\b/i) {
221 if ($filter_turned_on) {
222 Xchat::print("Filter is turned ${B}ON${B}\n");
223 } else {
224 Xchat::print("Filter is turned ${B}OFF${B}\n");
226 if ($limit_to_server) {
227 Xchat::print("Filter is limited to ".
228 ($server eq $limit_to_server ? "${B}current${B} " : "" ).
229 "server $limit_to_server");
231 if ($use_filter_allow) {
232 Xchat::print("Filter is using ALLOW rules (before DENY)\n");
235 } elsif ($arg =~ /^ON\b/i) {
236 $filter_turned_on = 1;
237 Xchat::print("Filter turned ON\n");
239 } elsif ($arg =~ /^OFF\b/i) {
240 $filter_turned_on = 0;
241 Xchat::print("Filter turned OFF\n");
243 } elsif ($arg =~ /^SERVER\b/i) {
244 if ($limit_to_server) {
245 Xchat::print("${B}FILTER:${B} Changing server from $limit_to_server to $server\n");
246 } else {
247 Xchat::print("${B}FILTER:${B} Limiting filtering to server $server\n");
249 $limit_to_server = $server;
251 } elsif ($arg =~ /^SERVERON\b/i) {
252 if ($limit_to_server) {
253 Xchat::print("${B}FILTER:${B} Changing server from $limit_to_server to $server\n");
254 } else {
255 Xchat::print("${B}FILTER:${B} Limiting filtering to server $server\n");
257 $limit_to_server = $server;
259 $filter_turned_on = 1;
260 Xchat::print("Filter turned ${B}ON${B}\n");
261 } elsif ($arg =~ /^ALL\b/i) {
262 if ($limit_to_server) {
263 Xchat::print("Filter: Removing limit to server $limit_to_server\n");
265 $limit_to_server = 0;
267 } elsif ($arg =~ /^HELP\b/i) {
268 Xchat::print($scriptHelp);
270 } elsif ($arg =~ /^VERSION\b/i) {
271 Xchat::print("${B}$scriptName $scriptVersion${B}\n");
272 Xchat::print(" * URL: http://github.com/jnareb/softsnow-xchat2-filter\n");
273 Xchat::print(" * URL: http://gitorious.org/projects/softsnow-xchat2-filter\n");
274 Xchat::print(" * URL: http://repo.or.cz/w/softsnow_xchat2_filter.git\n");
276 } elsif ($arg =~ /^DEBUG\b/i || $arg =~ /^INFO\b/i) {
277 Xchat::print("${B}FILTER DEBUG ----------${B}\n");
278 Xchat::print("Channel: ".Xchat::get_info("channel")."\n");
279 Xchat::print("Server: ".Xchat::get_info("server")."\n");
280 Xchat::print("Network: ".Xchat::get_info("network")."\n");
281 Xchat::print("Host: ".Xchat::get_info("host")."\n");
282 Xchat::print("${B}FILTER DEBUG ----------${B}\n");
284 } elsif ($arg =~ /^PRINT/i) {
285 Xchat::print("${B}FILTER PRINT ----------${B}\n");
286 Xchat::print("${B}ALLOW${B}".($use_filter_allow ? ' (on)' : ' (off)')."\n");
287 for (my $i = 0; $i <= $#filter_allow; $i++) {
288 Xchat::print("[$i]: /".$filter_allow[$i]."/\n");
290 Xchat::print("${B}DENY${B}\n");
291 for (my $i = 0; $i <= $#filter_deny; $i++) {
292 Xchat::print("[$i]: /".$filter_deny[$i]."/\n");
294 Xchat::print("${B}FILTER PRINT ----------${B}\n");
296 } elsif ($arg =~ /^ALLOW/i) {
297 $use_filter_allow = !$use_filter_allow;
298 Xchat::print("${B}FILTER:${B} ALLOW rules ".
299 ($use_filter_allow ? "enabled" : "disabled")."\n");
301 } elsif ($arg =~ /^ADD\s+(.*)/i) {
302 if ($1) {
303 add_rule($1);
304 Xchat::print("${B}FILTER RULE [$#filter_deny]:${B} /$1/\n");
305 } else {
306 Xchat::print("Syntax: ${B}/FILTER ADD ${U}rule${U}${B} to add\n")
309 } elsif ($arg =~ /^DELETE(.*)/i) {
310 my $num = $1;
311 $num =~ s/^\s*(.*?)\s*$/$1/g;
312 SWITCH: {
313 unless ($num) {
314 Xchat::print("${B}FILTER:${B} deleting /".$filter_deny[-1]."/\n");
315 $#filter_deny--;
316 Xchat::print("${B}FILTER:${B} deleted successfully last rule\n");
317 last SWITCH;
319 if ($num !~ /^\d+$/) {
320 Xchat::print("${B}FILTER:${B} $num is not a number\n");
321 last SWITCH;
323 if ($num < 0 || $num > $#filter_deny) {
324 Xchat::print("${B}FILTER:${B} $num outside range [0,$#filter_deny]\n");
325 last SWITCH;
327 Xchat::print("${B}FILTER:${B} deleting /".$filter_deny[$num]."/\n");
328 delete_rule($num);
329 Xchat::print("${B}FILTER:${B} deleted successfully rule $num\n");
332 } elsif ($arg =~ /^SAVE/i) {
333 save_filter();
334 Xchat::print("${B}FILTER:${B} saved DENY rules to $filter_file\n");
336 } elsif ($arg =~ /^(RE)?LOAD/i) {
337 load_filter();
338 Xchat::print("${B}FILTER:${B} loaded DENY rules from $filter_file\n");
340 } else {
341 Xchat::print("/filter arg: |$arg|\n") if $arg;
343 return 1;