html/lastspoke.pl
1 #!/usr/bin/perl -w
2 #
3 # LastSpoke.pl
4 #
5 # irssi script
6 #
7 # This script, when loaded into irssi, will monitor and remember everyones
8 # last action on one or more channels specified in the lastspoke_channels
9 # setting
10 #
11 # [settings]
12 # lastspoke_channels
13 # - Should contain a list of channels that lastspoke should monitor
14 # this list can be in any format as long as theres full channelnames
15 # in it. For example:
16 # "#foo,#bar,#baz" is correct
17 # "#foo#bar#baz" is correct
18 # "#foo #bar #baz" is correct
19 # "foo bar baz" is incorrect
20 #
21 # Triggers on !lastspoke <nick>, !seen <nick> and !lastseen <nick>
22 #
23 use Irssi;
24 use Irssi::Irc;
25
26 $VERSION = "0.2";
27 %IRSSI = (
28 authors => 'Sander Smeenk',
29 contact => 'irssi@freshdot.net',
30 name => 'lastspoke',
31 description => 'Remembers what people said last on what channels',
32 license => 'GNU GPLv2 or later',
33 url => 'http://irssi.freshdot.net/',
34 );
35
36 # Storage for the data.
37 my %lasthash;
38
39 # Calculates the difference between two unix times and returns
40 # a string like '15d 23h 42m 15s ago.'
41 sub calcDiff {
42 my ($when) = @_;
43
44 my $diff = (time() - $when);
45 my $day = int($diff / 86400); $diff -= ($day * 86400);
46 my $hrs = int($diff / 3600); $diff -= ($hrs * 3600);
47 my $min = int($diff / 60); $diff -= ($min * 60);
48 my $sec = $diff;
49
50 return "${day}d ${hrs}h ${min}m ${sec}s ago.";
51 }
52
53 # Hook for nick changes
54 sub on_nick {
55 my ($server, $new, $old, $address) = @_;
56
57 my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)";
58 if (index($allowedChans, $target) >= 0) {
59 $lasthash{lc($old)}{'last'} = time();
60 $lasthash{lc($old)}{'words'} = "$old changed nick to $new";
61 $lasthash{lc($new)}{'last'} = time();
62 $lasthash{lc($new)}{'words'} = "$new changed nick from $old";
63 }
64 }
65
66 # Hook for people quitting
67 sub on_quit {
68 my ($server, $nick, $address, $reason) = @_;
69
70 my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)";
71 if (index($allowedChans, $target) >= 0) {
72 $lasthash{lc($nick)}{'last'} = time();
73 if (! $reason) {
74 $lasthash{lc($nick)}{'words'} = "$nick quit IRC with no reason";
75 } else {
76 $lasthash{lc($nick)}{'words'} = "$nick quit IRC stating '$reason'";
77 }
78 }
79 }
80
81 # Hook for people joining
82 sub on_join {
83 my ($server, $channel, $nick, $address) = @_;
84
85 my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)";
86 if (index($allowedChans, $target) >= 0) {
87 $lasthash{lc($nick)}{'last'} = time();
88 $lasthash{lc($nick)}{'words'} = "$nick joined $channel";
89 }
90 }
91
92 # Hook for people parting
93 sub on_part {
94 my ($server, $channel, $nick, $address, $reason) = @_;
95
96 my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)";
97 if (index($allowedChans, $target) >= 0) {
98 $lasthash{lc($nick)}{'last'} = time();
99 if (! $reason) {
100 $lasthash{lc($nick)}{'words'} = "$nick left from $channel with no reason";
101 } else {
102 $lasthash{lc($nick)}{'words'} = "$nick left from $channel stating '$reason'";
103 }
104 }
105 }
106
107 # Hook for public messages.
108 # Only act on channels we are supposed to act on (settings_get_str)
109 sub on_public {
110 my ($server, $msg, $nick, $addr, $target) = @_;
111
112 $target = $nick if ( ! $target );
113 $nick = $server->{'nick'} if ($nick =~ /^#/);
114 $target = lc($target);
115
116 my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)";
117
118 # Debug
119 # Irssi::active_win()->print("Server: $server");
120 # Irssi::active_win()->print("Msg : $msg");
121 # Irssi::active_win()->print("Nick : $nick");
122 # Irssi::active_win()->print("Addr : $addr");
123 # Irssi::active_win()->print("Target: $target");
124 # /Debug
125
126 if (index($allowedChans, $target) >= 0) {
127 if ( ($msg =~ /^!lastspoke /) || ($msg =~ /^!seen /) || ($msg =~ /^!lastseen /)) {
128 my @parts = split(/ /,$msg);
129
130 $lasthash{lc($nick)}{'last'} = time();
131 $lasthash{lc($nick)}{'words'} = "$nick last queried information about " . $parts[1] . " on $target";
132
133 if (exists $lasthash{lc($parts[1])}) {
134 $server->command("MSG $target " . $lasthash{lc($parts[1])}{'words'} . " " . calcDiff($lasthash{lc($parts[1])}{'last'}));
135 } else {
136 $server->command("MSG $target I don't know anything about " . $parts[1]);
137 }
138 } else {
139 $lasthash{lc($nick)}{'last'} = time();
140 $lasthash{lc($nick)}{'words'} = "$nick last said '$msg' on $target";
141 }
142 }
143 }
144
145 # Put hooks on events
146 Irssi::signal_add_last("message public", "on_public");
147 Irssi::signal_add_last("message own_public", "on_public");
148 Irssi::signal_add_last("message part", "on_part");
149 Irssi::signal_add_last("message join", "on_join");
150 Irssi::signal_add_last("message quit", "on_quit");
151 Irssi::signal_add_last("message nick", "on_nick");
152
153 # Add setting
154 Irssi::settings_add_str("lastspoke", "lastspoke_channels", '%s');