Turn dumping filtered content to window on by default
[softsnow_xchat2_filter.git] / SoftSnow_filter.pl
blobebc592202bfba4faee7043801c00102d2a1b97ae
1 #!/usr/bin/perl
3 use strict;
4 use warnings;
7 my $scriptName = "SoftSnow XChat2 Filter";
8 my $scriptVersion = "2.0.2";
9 my $scriptDescr = "Filter out file server announcements and IRC SPAM";
11 my $B = "\cB"; # bold
12 my $U = "\cU"; # underline
13 my $C = "\cC"; # start of color sequence
15 ### config ###
16 my $filter_file = Xchat::get_info("xchatdir") . "/SoftSnow_filter.conf";
18 my $filter_turned_on = 0; # was default turned ON
19 my $limit_to_server = ''; # don't limit to server (host)
20 my $use_filter_allow = 0; # use overrides
22 my $filtered_to_window = 1;
23 my $filter_window = "(filtered)";
24 ### end config ###
26 my $command_list = 'ON|OFF|STATUS|SERVER|SERVERON|ALL|HELP|DEBUG|PRINT|ALLOW|ADD|DELETE|SAVE|LOAD';
28 my $scriptHelp = <<"EOF";
29 ${B}/FILTER $command_list${B}
30 /FILTER ON|OFF - turns filtering on/off
31 /FILTER HELP - prints this help message
32 /FILTER STATUS - prints if filter is turned on, and with what limits
33 /FILTER DEBUG - shows some info; used in debuggin the filter
34 /FILTER PRINT - prints all the rules
35 /FILTER ALLOW - toggle use of ALLOW rules (before DENY).
36 /FILTER SERVER - limits filtering to current server (host)
37 /FILTER SERVERON - limits to server and turns filter on
38 /FILTER ALL - resumes filtering everywhere i.e. removes limits
39 /FILTER SAVE - saves the rules to the file $filter_file
40 /FILTER LOAD - loads the rules from the file, replacing existing rules
41 /FILTER ADD <rule> - add rule at the end of the DENY rules
42 /FILTER DELETE [<num>] - delete rule number <num>, or last rule
43 /FILTER VERSION - prints the name and version of this script
44 /FILTER without parameter is equivalent to /FILTER STATUS
45 EOF
47 Xchat::register($scriptName, $scriptVersion, $scriptDescr);
49 Xchat::hook_command("FILTER", \&filter_command_handler,
50 { help_text => $scriptHelp });
51 Xchat::hook_server("PRIVMSG", \&privmsg_handler);
53 Xchat::print("Loading ${B}$scriptName $scriptVersion${B}\n".
54 " For help: ${B}/FILTER HELP${B}\n");
56 # GUI, windows, etc.
57 if ($filtered_to_window) {
58 Xchat::command("QUERY $filter_window");
61 # information about (default) options used
62 if ($filter_turned_on) {
63 Xchat::print("Filter turned ${B}ON${B}\n");
64 } else {
65 Xchat::print("Filter turned ${B}OFF${B}\n");
67 if ($limit_to_server) {
68 Xchat::print("Filter limited to server $limit_to_server\n")
70 if ($use_filter_allow) {
71 Xchat::print("Filter uses ALLOW rules\n");
74 # ------------------------------------------------------------
76 my @filter_allow = (
77 q/^\@search\s/,
80 my @filter_deny = (
81 q/\@/,
82 q/^\s*\!/,
83 q/slot\(s\)/,
84 #q/~&~&~/,
86 #xdcc
87 q/^\#\d+/,
89 #fserves
90 q/(?i)fserve.*trigger/,
91 q/(?i)trigger.*\!/,
92 q/(?i)trigger.*\/ctcp/,
93 q/(?i)type\:\s*\!/,
94 q/(?i)file server online/,
96 #ftps
97 q/(?i)ftp.*l\/p/,
99 #CTCPs
100 q/SLOTS/,
101 q/MP3 /,
103 #messages for when a file is received/failed to receive
104 q/(?i)DEFINITELY had the right stuff to get/,
105 q/(?i)has just received/,
106 q/(?i)I have just received/,
108 #mp3 play messages
109 q/is listening to/,
110 q/\]\-MP3INFO\-\[/,
112 #spammy scripts
113 q/\]\-SpR\-\[/,
114 q/We are BORG/,
116 #general messages
117 q/brave soldier in the war/,
120 # return 1 (true) if text given as argument is to be filtered out
121 sub isFiltered {
122 my $text = shift;
123 my $regexp = '';
125 #strip colour, underline, bold codes, etc.
126 $text = Xchat::strip_code($text);
128 if ($use_filter_allow) {
129 foreach $regexp (@filter_allow) {
130 return 0 if ($text =~ /$regexp/);
134 foreach $regexp (@filter_deny) {
135 return 1 if ($text =~ /$regexp/);
138 return 0;
141 #called when someone says something in the channel
142 #1: address of speaker
143 #2: PRIVMSG constant
144 #3: channel
145 #4: text said (prefixed with :)
146 sub privmsg_handler {
147 # $_[0] - array reference containing the IRC message or command
148 # and arguments broken into words
149 # $_[1] - array reference containing the Nth word to the last word
150 #my ($address, $constant, $chan) = @{$_[0]};
151 my $text = $_[1][3]; # Get server message
153 my $server = Xchat::get_info("host");
156 return Xchat::EAT_NONE unless $filter_turned_on;
157 if ($limit_to_server) {
158 return Xchat::EAT_NONE unless $server eq $limit_to_server;
161 $text =~ s/^://;
163 if (isFiltered($text)) {
164 Xchat::print($text, $filter_window) if $filtered_to_window;
165 return Xchat::EAT_ALL;
167 return Xchat::EAT_NONE;
170 # ------------------------------------------------------------
172 sub save_filter {
173 open F, ">$filter_file"
174 or do {
175 Xchat::print("${B}FILTER:${B} Couldn't open file to save filter: $!\n");
176 return 1;
179 Xchat::print("${B}FILTER SAVE >$filter_file${B}\n");
180 foreach my $regexp (@filter_deny) {
181 Xchat::print("/".$regexp."/ saved\n");
182 print F $regexp."\n";
184 Xchat::print("${B}FILTER SAVED ----------${B}\n");
185 close F
186 or do {
187 Xchat::print("${B}FILTER:${B} Couldn't close file to save filter: $!\n");
188 return 1;
190 return 1;
193 sub load_filter {
194 Xchat::print("${B}FILTER:${B} ...loading filter patterns\n");
195 open F, "<$filter_file"
196 or do {
197 Xchat::print("${B}FILTER:${B} Couldn't open file to load filter: $!\n");
198 return 1;
200 @filter_deny = <F>;
201 map (chomp, @filter_deny);
202 close F;
204 Xchat::print("${B}FILTER DENY ----------${B}\n");
205 for (my $i = 0; $i <= $#filter_deny; $i++) {
206 Xchat::print(" [$i]: /".$filter_deny[$i]."/\n");
208 Xchat::print("${B}FILTER DENY ----------${B}\n");
211 sub add_rule ( $ ) {
212 my $rule = shift;
214 # always ading rules at the end
215 push @filter_deny, $rule;
218 sub delete_rule ( $ ) {
219 my $num = shift || $#filter_deny;
221 splice @filter_deny, $num, 1;
224 # ============================================================
225 # ============================================================
226 # ============================================================
228 sub filter_command_handler {
229 my $arg = $_[1][1]; # 1st word to the last word
230 my $server = Xchat::get_info("host");
233 if (!$arg || $arg =~ /^STATUS\b/i) {
234 if ($filter_turned_on) {
235 Xchat::print("Filter is turned ${B}ON${B}\n");
236 } else {
237 Xchat::print("Filter is turned ${B}OFF${B}\n");
239 if ($limit_to_server) {
240 if ($server eq $limit_to_server) {
241 Xchat::print("Filter is limited to ${B}current${B} ".
242 "server $limit_to_server\n");
243 } else {
244 Xchat::print("Filter is limited to server ".
245 "$limit_to_server != $server\n");
248 if ($use_filter_allow) {
249 Xchat::print("Filter is using ALLOW rules (before DENY)\n");
252 } elsif ($arg =~ /^ON\b/i) {
253 $filter_turned_on = 1;
254 Xchat::print("Filter turned ON\n");
256 } elsif ($arg =~ /^OFF\b/i) {
257 $filter_turned_on = 0;
258 Xchat::print("Filter turned OFF\n");
260 } elsif ($arg =~ /^SERVER\b/i) {
261 if ($limit_to_server) {
262 Xchat::print("${B}FILTER:${B} Changing server from $limit_to_server to $server\n");
263 } else {
264 Xchat::print("${B}FILTER:${B} Limiting filtering to server $server\n");
266 $limit_to_server = $server;
268 } elsif ($arg =~ /^SERVERON\b/i) {
269 if ($limit_to_server) {
270 Xchat::print("${B}FILTER:${B} Changing server from $limit_to_server to $server\n");
271 } else {
272 Xchat::print("${B}FILTER:${B} Limiting filtering to server $server\n");
274 $limit_to_server = $server;
276 $filter_turned_on = 1;
277 Xchat::print("Filter turned ${B}ON${B}\n");
279 } elsif ($arg =~ /^ALL\b/i) {
280 if ($limit_to_server) {
281 Xchat::print("Filter: Removing limit to server $limit_to_server\n");
283 $limit_to_server = 0;
285 } elsif ($arg =~ /^HELP\b/i) {
286 Xchat::print($scriptHelp);
288 } elsif ($arg =~ /^VERSION\b/i) {
289 Xchat::print("${B}$scriptName $scriptVersion${B}\n");
290 Xchat::print(" * URL: http://github.com/jnareb/softsnow-xchat2-filter\n");
291 Xchat::print(" * URL: http://gitorious.org/projects/softsnow-xchat2-filter\n");
292 Xchat::print(" * URL: http://repo.or.cz/w/softsnow_xchat2_filter.git\n");
294 } elsif ($arg =~ /^DEBUG\b/i || $arg =~ /^INFO\b/i) {
295 Xchat::print("${B}FILTER DEBUG ----------${B}\n");
296 Xchat::print("Channel: ".Xchat::get_info("channel")."\n");
297 Xchat::print("Host: ".Xchat::get_info("host")."\n");
298 Xchat::print("Server: ".Xchat::get_info("server")."\n");
299 Xchat::print("Server Id: ".Xchat::get_info("id")."\n");
300 Xchat::print("Network: ".Xchat::get_info("network")."\n");
301 Xchat::print("\n");
302 Xchat::printf("%3u %s rules\n", scalar(@filter_allow), "allow");
303 Xchat::printf("%3u %s rules\n", scalar(@filter_deny), "deny");
304 Xchat::print("${B}FILTER DEBUG ----------${B}\n");
306 } elsif ($arg =~ /^(?:PRINT|LIST)\b/i) {
307 Xchat::print("${B}FILTER PRINT ----------${B}\n");
308 Xchat::print("${B}ALLOW${B}".($use_filter_allow ? ' (on)' : ' (off)')."\n");
309 for (my $i = 0; $i <= $#filter_allow; $i++) {
310 Xchat::print("[$i]: /".$filter_allow[$i]."/\n");
312 Xchat::print("${B}DENY${B}\n");
313 for (my $i = 0; $i <= $#filter_deny; $i++) {
314 Xchat::print("[$i]: /".$filter_deny[$i]."/\n");
316 Xchat::print("${B}FILTER PRINT ----------${B}\n");
318 } elsif ($arg =~ /^ALLOW/i) {
319 $use_filter_allow = !$use_filter_allow;
320 Xchat::print("${B}FILTER:${B} ALLOW rules ".
321 ($use_filter_allow ? "enabled" : "disabled")."\n");
323 } elsif ($arg =~ /^ADD\s+(.*)/i) {
324 my $rule = $1;
325 if ($rule) {
326 add_rule($rule);
327 Xchat::print("${B}FILTER RULE [$#filter_deny]:${B} /$rule/\n");
328 } else {
329 Xchat::print("Syntax: ${B}/FILTER ADD ${U}rule${U}${B} to add\n")
332 } elsif ($arg =~ /^DEL(?:ETE)?(.*)/i) {
333 my $num = $1;
334 $num =~ s/^\s*(.*?)\s*$/$1/g;
335 SWITCH: {
336 unless ($num) {
337 Xchat::print("${B}FILTER:${B} deleting /".$filter_deny[-1]."/\n");
338 $#filter_deny--;
339 Xchat::print("${B}FILTER:${B} deleted successfully last rule\n");
340 last SWITCH;
342 if ($num !~ /^\d+$/) {
343 Xchat::print("${B}FILTER:${B} $num is not a number\n");
344 last SWITCH;
346 if ($num < 0 || $num > $#filter_deny) {
347 Xchat::print("${B}FILTER:${B} $num outside range [0,$#filter_deny]\n");
348 last SWITCH;
350 # default
351 Xchat::print("${B}FILTER:${B} deleting /".$filter_deny[$num]."/\n");
352 delete_rule($num);
353 Xchat::print("${B}FILTER:${B} deleted successfully rule $num\n");
356 } elsif ($arg =~ /^SAVE\b/i) {
357 save_filter();
358 Xchat::print("${B}FILTER:${B} saved DENY rules to $filter_file\n");
360 } elsif ($arg =~ /^(RE)?LOAD\b/i) {
361 load_filter();
362 Xchat::print("${B}FILTER:${B} loaded DENY rules from $filter_file\n");
364 } else {
365 Xchat::print("Unknown command $ {B}/FILTER $arg${B}\n") if $arg;
367 return 1;