├── LICENSE ├── README.md └── smartfilter.pl /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2014, Christian Brassat and Walter Hop 2 | Copyright (c) 2015, Niall Bunting 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without modification, 6 | are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright notice, this 9 | list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above copyright notice, this 12 | list of conditions and the following disclaimer in the documentation and/or 13 | other materials provided with the distribution. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR 19 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 22 | ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | irssi-smartfilter 2 | ================= 3 | 4 | This script filters JOIN, PART, QUIT and NICK event messages to active users only. 5 | 6 | When the script is running, a user's events will only be displayed when they have been active recently. If the user is not active in the channel, their events will be ignored. 7 | 8 | This script limits noise from large channels, while preventing you from talking to a conversation partner who has left (which can happen if you just ignore all events). 9 | 10 | By default, a user is considered active if they have said something in the last 20 minutes. If they leave the channel, change nick etc., they are kept active, so you will not miss re-joins or subsequent nick changes. 11 | 12 | ## Usage 13 | - Download `smartfilter.pl` to your `.irssi/scripts` directory 14 | - To run once: `/run smartfilter` 15 | - To run automatically, create a symlink to `smartfilter.pl` in your `.irssi/scripts/autorun` directory 16 | 17 | ## Optional configuration 18 | - You can specify a space-separated list of channels for which the filtering will be disabled: `/set smartfilter_ignored_chans #channel1 #channel2` 19 | - You can change the recent activity time (in seconds): `/set smartfilter_delay 1200` 20 | - Old nicks are removed from memory periodically. You can change how often the garbage collection runs by picking after how many smartfilter-delays it runs: `/set smartfilter_garbage_multiplier 4` 21 | 22 | ## Contributors 23 | [Christian Brassat](http://crshd.anapnea.net/2012/10/03/Smartfilter-for-Irssi/), [Niall Bunting](http://niallbunting.com/), [Walter Hop](https://lifeforms.nl/) and [Frantisek Sumsal](https://github.com/mrc0mmand) 24 | -------------------------------------------------------------------------------- /smartfilter.pl: -------------------------------------------------------------------------------- 1 | use strict; 2 | use warnings; 3 | use Irssi; 4 | use vars qw($VERSION %IRSSI); 5 | 6 | $VERSION = "0.4"; 7 | 8 | %IRSSI = ( 9 | authors => 'Christian Brassat, Niall Bunting, Walter Hop and Frantisek Sumsal', 10 | contact => 'irssi-smartfilter@spam.lifeforms.nl', 11 | name => 'smartfilter.pl', 12 | description => 'Improved smart filter for join, part, quit, nick messages', 13 | license => 'BSD', 14 | url => 'https://github.com/lifeforms/irssi-smartfilter', 15 | changed => '2015-12-28', 16 | ); 17 | 18 | # Associative array of nick => last active unixtime 19 | our $lastmsg = {}; 20 | our $garbagetime = 1; 21 | our @ignored_chans; 22 | 23 | # Do checks after receving a channel event. 24 | # - If the originating nick is not active, ignore the signal. 25 | # - If nick is active, propagate the signal and display the event message. 26 | # Keep the nick marked as active, so we will not miss a re-join after a PART 27 | # or QUIT, a second nick change, etc. 28 | sub checkactive { 29 | my ($nick, $altnick, $channel) = @_; 30 | 31 | # if channel is not defined do nothing, quits and parts always have 32 | # a channel so I wonder if this is needed 33 | if (not defined($channel)) { 34 | return; 35 | } 36 | 37 | # Skip filtering if current channel is in 'smartfilter_ignored_chans' 38 | # If the channel and nick values match event happened in a query so skip filtering 39 | if (grep {$_ eq $channel} @ignored_chans or $channel eq $nick) { 40 | return; 41 | } 42 | 43 | if (!exists $lastmsg->{$nick} || $lastmsg->{$nick} <= time() - Irssi::settings_get_int('smartfilter_delay')) { 44 | delete $lastmsg->{$nick}; 45 | Irssi::signal_stop(); 46 | } 47 | 48 | if(exists $lastmsg->{$nick} && $altnick) { 49 | $lastmsg->{$altnick} = $lastmsg->{$nick}; 50 | delete $lastmsg->{$nick}; 51 | } 52 | 53 | # Run the garbage collection every interval. 54 | if ($garbagetime <= time() - (Irssi::settings_get_int('smartfilter_delay') * Irssi::settings_get_int('smartfilter_garbage_multiplier') )) { 55 | garbagecollect(); 56 | $garbagetime = time(); 57 | } 58 | } 59 | 60 | # Implements garbage collection. 61 | sub garbagecollect{ 62 | foreach my $key (keys %$lastmsg) { 63 | if ($lastmsg->{$key} <= time() - Irssi::settings_get_int('smartfilter_delay')) { 64 | delete $lastmsg->{$key} 65 | } 66 | } 67 | } 68 | 69 | # JOIN or PART received. 70 | sub smartfilter_chan { 71 | my ($server, $channel, $nick, $address) = @_; 72 | &checkactive($nick, undef, $channel); 73 | }; 74 | 75 | sub smartfilter_text { 76 | my ($dest, $text, $stripped) = @_; 77 | 78 | # Message we attempt to print is nick change or quit notice 79 | if($dest->{'level'} & MSGLEVEL_NICKS) { 80 | if($stripped =~ m/([^ ]+) is now known as ([^ ]+)/) { 81 | &checkactive($1, $2, $dest->{'target'}); 82 | } 83 | } elsif($dest->{'level'} & MSGLEVEL_QUITS) { 84 | if($stripped =~ m/-!- ([^ ]+) .+? has quit/) { 85 | &checkactive($1, undef, $dest->{'target'}); 86 | } 87 | } 88 | } 89 | 90 | sub smartfilter_settings { 91 | undef @ignored_chans if @ignored_chans; 92 | my $ign_chans = Irssi::settings_get_str('smartfilter_ignored_chans'); 93 | @ignored_chans = split /\s+/, $ign_chans; 94 | } 95 | 96 | # Channel message received. Mark the nick as active. 97 | sub log { 98 | my ($server, $msg, $nick, $address, $target) = @_; 99 | $lastmsg->{$nick} = time(); 100 | } 101 | 102 | Irssi::signal_add('message public', 'log'); 103 | Irssi::signal_add('message join', 'smartfilter_chan'); 104 | Irssi::signal_add('message part', 'smartfilter_chan'); 105 | Irssi::signal_add('print text', 'smartfilter_text'); 106 | Irssi::signal_add('setup changed', 'smartfilter_settings'); 107 | 108 | Irssi::settings_add_int('smartfilter', 'smartfilter_garbage_multiplier', 4); 109 | Irssi::settings_add_int('smartfilter', 'smartfilter_delay', 1200); 110 | Irssi::settings_add_str('smartfilter', 'smartfilter_ignored_chans', ''); 111 | 112 | smartfilter_settings(); 113 | --------------------------------------------------------------------------------