-
Notifications
You must be signed in to change notification settings - Fork 8
/
smartfilter.pl
112 lines (94 loc) · 3.39 KB
/
smartfilter.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use strict;
use warnings;
use Irssi;
use vars qw($VERSION %IRSSI);
$VERSION = "0.4";
%IRSSI = (
authors => 'Christian Brassat, Niall Bunting, Walter Hop and Frantisek Sumsal',
contact => '[email protected]',
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;
# 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();
}
Irssi::signal_add('message public', 'log');
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', '');
smartfilter_settings();