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 40use strict; 41use Irssi; 42use Data::Dumper; 43 44use 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 55my %lastmsgs = (); 56my %count = (); 57my %window = (); 58 59sub 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 89sub 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 100sub window_destroyed { 101 my $ref = shift->{refnum}; 102 103 delete $count{$ref}; 104 delete $lastmsgs{$ref}; 105} 106 107Irssi::settings_add_int ('doublefilter', 'filter_length' => '5'); 108Irssi::settings_add_bool('doublefilter', 'show_repeat' => 0); 109Irssi::settings_add_bool('doublefilter', 'ignore_window' => 1); 110 111Irssi::signal_add_first('event privmsg', \&filter_check); 112Irssi::signal_add_last('window refnum changed', \&window_change); 113Irssi::signal_add_last('window destroyed', \&window_destroyed); 114