html/doublefilter.pl
1 ##
2 # doublefilter.pl
3 #
4 # Removes double messages, even if they appear on different channels.
5 # The script stores every message it sees in a query or a channel into
6 # a FIFO (a queue), if new, or increases the counter for that message.
7 # Any message already in the FIFO is further ignored (e.g. doesn't show
8 # up in any window).
9 #
10 # Customization:
11 #
12 # /set filter_length <n>
13 # Sets the number of lines the script remembers in a FIFO to <n>.
14 # Setting filter_length to 1 simulates the behaviour of repeat.pl, but
15 # it depends on ignore_window if doublefilter.pl ignores the windows the
16 # message gets to.
17 # Default is currently set to 5.
18 #
19 # /set show_repeat on/off
20 # If set to ON, shows the count for lines the script moves out of the FIFO.
21 # Default is OFF.
22 # (Idea is blatantly ripped from repeat.pl.)
23 #
24 # /set ignore_window on/off
25 # If set to OFF, and if filter_length is set to 1, it emulates repeat.pl.
26 # If set to ON, double messages get also filtered if they appear in different
27 # windows (queries or channels).
28 # Default is ON.
29 # (This idea was also inspired by repeat.pl.)
30 #
31 # History:
32 #
33 # 0.1 Initial release.
34 #
35 # 0.2 Counter for messages
36 #
37 # 0.3 If desired, filters per message window, thus emulating repeat.pl
38 ##
39
40 use strict;
41 use Irssi;
42 use Data::Dumper;
43
44 use vars qw($VERSION %IRSSI);
45 $VERSION = "0.3";
46 %IRSSI = (
47 authors => "Karl Siegemund",
48 contact => "q \[at\] spuk.de",
49 name => "doublefilter",
50 description => "Filters msgs which appear the same on different channels.",
51 license => "GPLv2",
52 changed => "22.04.2005 9:50GMT"
53 );
54
55 my %lastmsgs = ();
56 my %count = ();
57 my %window = ();
58
59 sub filter_check {
60 my $max = Irssi::settings_get_int('filter_length');
61 my $show = Irssi::settings_get_bool('show_repeat');
62 my $win = Irssi::settings_get_bool('ignore_window');
63 my ($server, $msg, $nick, undef, $target) = @_;
64 my $refnum = -1;
65 ($target, $msg) = split / :/,$msg,2;
66 if (!$win) {
67 $refnum = $server->window_find_item($target)->{refnum};
68 }
69 $msg = "<$nick> $msg";
70 if (exists $count{$refnum}{$msg}) {
71 Irssi::signal_stop();
72 ++$count{$refnum}{$msg};
73 return;
74 }
75 if(exists $lastmsgs{$refnum}) {
76 $lastmsgs{$refnum} = [ $msg, @{$lastmsgs{$refnum}} ];
77 } else {
78 $lastmsgs{$refnum} = [ $msg ];
79 }
80 if(scalar @{$lastmsgs{$refnum}} > $max) {
81 my $last = pop @{$lastmsgs{$refnum}};
82 print "$last\n*** Repeated $count{$refnum}{$last} times."
83 if $show && $count{$refnum}{$last};
84 delete $count{$refnum}{$last};
85 }
86 $count{$refnum}{$msg} = 0;
87 }
88
89 sub window_change {
90 my $new = shift->{refnum};
91 my $old = shift;
92
93 $count{$new} = $count{$old};
94 $lastmsgs{$new} = $lastmsgs{$old};
95
96 delete $count{$old};
97 delete $lastmsgs{$old};
98 }
99
100 sub window_destroyed {
101 my $ref = shift->{refnum};
102
103 delete $count{$ref};
104 delete $lastmsgs{$ref};
105 }
106
107 Irssi::settings_add_int ('doublefilter', 'filter_length' => '5');
108 Irssi::settings_add_bool('doublefilter', 'show_repeat' => 0);
109 Irssi::settings_add_bool('doublefilter', 'ignore_window' => 1);
110
111 Irssi::signal_add_first('event privmsg', \&filter_check);
112 Irssi::signal_add_last('window refnum changed', \&window_change);
113 Irssi::signal_add_last('window destroyed', \&window_destroyed);