]> git.99rst.org Git - irssi-scripts.irssi.org.git/commitdiff
Update smartfilter.pl to 0.4
authorChris Zehner <redacted>
Tue, 30 Jan 2018 16:20:44 +0000 (08:20 -0800)
committerChris Zehner <redacted>
Tue, 30 Jan 2018 16:20:44 +0000 (08:20 -0800)
_data/scripts.yaml
scripts/smartfilter.pl

index 406f56f203dba36e302d92a28aea6fac6a981ed2..1e97f0f9bea83712978993adb47201a6aef921ea 100644 (file)
   url: 'http://scripts.irssi.org & https://github.com/avar/dotfiles/blob/master/.irssi/scripts/slack_strip_auto_cc.pl'
   version: '1.0'
 -
-  authors: 'Christian Brassat'
-  contact: crshd@mail.com
-  description: 'This script hides join/part messages.'
+  authors: 'Christian Brassat, Niall Bunting, Walter Hop and Frantisek Sumsal'
+  contact: irssi-smartfilter@spam.lifeforms.nl
+  description: 'Improved smart filter for join, part, quit, nick messages`'
   filename: smartfilter.pl
   license: BSD
-  modified: '2014-06-26 18:46:20'
+  modified: '2015-12-28'
   name: smartfilter.pl
-  url: http://crshd.github.io
-  version: '0.1'
+  url: https://github.com/lifeforms/irssi-smartfilter
+  version: '0.4'
 -
   authors: 'Jonne Piittinen'
   commands: smiley
index f82ebb152703bc938060305de25b8c9eb6e9b6c4..d7dec0161e9b9d07258514367b30293a613c9781 100644 (file)
 use strict;
+use warnings;
 use Irssi;
 use vars qw($VERSION %IRSSI);
 
-$VERSION = "0.1";
+$VERSION = "0.4";
 
 %IRSSI = (
-    authors     => 'Christian Brassat',
-    contact     => 'crshd@mail.com',
-    name        => 'smartfilter.pl',
-    description => 'This script hides join/part messages.',
-    license     => 'BSD',
-    url         => 'http://crshd.github.io',
-    changed     => '2012-10-02',
+       authors     => 'Christian Brassat, Niall Bunting, Walter Hop and Frantisek Sumsal',
+       contact     => 'irssi-smartfilter@spam.lifeforms.nl',
+       name        => 'smartfilter.pl',
+       description => 'Improved smart filter for join, part, quit, nick messages',
+       license     => 'BSD',
+       url         => 'https://github.com/lifeforms/irssi-smartfilter',
+       changed     => '2015-12-28',
 );
 
+# Associative array of nick => last active unixtime
 our $lastmsg = {};
+our $garbagetime = 1;
+our @ignored_chans;
 
-sub smartfilter {
-    my ($channel, $nick, $address, $reason) = @_;
-    if ($lastmsg->{$nick} <= time() - Irssi::settings_get_int('smartfilter_delay')) {
-        Irssi::signal_stop();
-    }
+# Do checks after receving a channel event.
+# - If the originating nick is not active, ignore the signal.
+# - If nick is active, propagate the signal and display the event message.
+#   Keep the nick marked as active, so we will not miss a re-join after a PART
+#   or QUIT, a second nick change, etc.
+sub checkactive {
+       my ($nick, $altnick, $channel) = @_;
+
+       # if channel is not defined do nothing, quits and parts always have
+       # a channel so I wonder if this is needed
+       if (not defined($channel)) {
+               return;
+       }
+
+       # Skip filtering if current channel is in 'smartfilter_ignored_chans'
+       # If the channel and nick values match event happened in a query so skip filtering
+       if (grep {$_ eq $channel} @ignored_chans or $channel eq $nick) {
+               return;
+       }
+
+       if (!exists $lastmsg->{$nick} || $lastmsg->{$nick} <= time() - Irssi::settings_get_int('smartfilter_delay')) {
+               delete $lastmsg->{$nick};
+               Irssi::signal_stop();
+       }
+
+       if(exists $lastmsg->{$nick} && $altnick) {
+               $lastmsg->{$altnick} = $lastmsg->{$nick};
+               delete $lastmsg->{$nick};
+       }
+
+       # Run the garbage collection every interval.
+       if ($garbagetime <= time() - (Irssi::settings_get_int('smartfilter_delay') * Irssi::settings_get_int('smartfilter_garbage_multiplier') )) {
+               garbagecollect();
+               $garbagetime = time();
+       }
+}
+
+# Implements garbage collection.
+sub garbagecollect{
+       foreach my $key (keys %$lastmsg) {
+               if ($lastmsg->{$key} <= time() - Irssi::settings_get_int('smartfilter_delay')) {
+                       delete $lastmsg->{$key}
+               }
+       }
+}
+
+# JOIN or PART received.
+sub smartfilter_chan {
+       my ($server, $channel, $nick, $address) = @_;
+       &checkactive($nick, undef, $channel);
 };
 
+sub smartfilter_text {
+       my ($dest, $text, $stripped) = @_;
+
+       # Message we attempt to print is nick change or quit notice
+       if($dest->{'level'} & MSGLEVEL_NICKS) {
+               if($stripped =~ m/([^ ]+) is now known as ([^ ]+)/) {
+                       &checkactive($1, $2, $dest->{'target'});
+               }
+       } elsif($dest->{'level'} & MSGLEVEL_QUITS) {
+               if($stripped =~ m/-!- ([^ ]+) .+? has quit/) {
+                       &checkactive($1, undef, $dest->{'target'});
+               }
+       }
+}
+
+sub smartfilter_settings {
+       undef @ignored_chans if @ignored_chans;
+       my $ign_chans = Irssi::settings_get_str('smartfilter_ignored_chans');
+       @ignored_chans = split /\s+/, $ign_chans;
+}
+
+# Channel message received. Mark the nick as active.
 sub log {
-    my ($server, $msg, $nick, $address, $target) = @_;
-    $lastmsg->{$nick} = time();
+       my ($server, $msg, $nick, $address, $target) = @_;
+       $lastmsg->{$nick} = time();
 }
 
 Irssi::signal_add('message public', 'log');
-Irssi::signal_add('message join', 'smartfilter');
-Irssi::signal_add('message part', 'smartfilter');
-Irssi::signal_add('message quit', 'smartfilter');
+Irssi::signal_add('message join', 'smartfilter_chan');
+Irssi::signal_add('message part', 'smartfilter_chan');
+Irssi::signal_add('print text', 'smartfilter_text');
+Irssi::signal_add('setup changed', 'smartfilter_settings');
+
+Irssi::settings_add_int('smartfilter', 'smartfilter_garbage_multiplier', 4);
+Irssi::settings_add_int('smartfilter', 'smartfilter_delay', 1200);
+Irssi::settings_add_str('smartfilter', 'smartfilter_ignored_chans', '');
 
-Irssi::settings_add_int('smartfilter', 'smartfilter_delay', 300);
+smartfilter_settings();
git clone https://git.99rst.org/PROJECT