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);