diff options
Diffstat (limited to 'scripts/lastspoke.pl')
-rw-r--r-- | scripts/lastspoke.pl | 210 |
1 files changed, 210 insertions, 0 deletions
diff --git a/scripts/lastspoke.pl b/scripts/lastspoke.pl new file mode 100644 index 0000000..32c55f3 --- /dev/null +++ b/scripts/lastspoke.pl @@ -0,0 +1,210 @@ +#!/usr/bin/perl -w +# +# LastSpoke.pl +# +# irssi script +# +# This script, when loaded into irssi, will monitor and remember everyones +# last action on one or more channels specified in the lastspoke_channels +# setting +# +# [settings] +# lastspoke_channels +# - Should contain a list of channels that lastspoke should monitor +# this list can be in any format as long as theres full channelnames +# in it. For example: +# "#foo,#bar,#baz" is correct +# "#foo#bar#baz" is correct +# "#foo #bar #baz" is correct +# +# Triggers on !lastspoke <nick>, !seen <nick> and !lastseen <nick> +# +use strict; +use utf8; +use Encode qw/decode encode/; +use Irssi; +use Irssi::Irc; +use CPAN::Meta::YAML; +use vars qw($VERSION %IRSSI); + +$VERSION = "0.4"; +%IRSSI = ( + authors => 'Sander Smeenk', + contact => 'irssi@freshdot.net', + name => 'lastspoke', + description => 'Remembers what people said last on what channels', + license => 'GNU GPLv2 or later', + url => 'http://irssi.freshdot.net/', + modules => 'CPAN::Meta::YAML', +); + +# Storage for the data. +my %lasthash; + +my $filename=Irssi::get_irssi_dir().'/lastspoke.yaml'; + +# Calculates the difference between two unix times and returns +# a string like '15d 23h 42m 15s ago.' +sub calcDiff { + my ($when) = @_; + + my $diff = (time() - $when); + my $day = int($diff / 86400); $diff -= ($day * 86400); + my $hrs = int($diff / 3600); $diff -= ($hrs * 3600); + my $min = int($diff / 60); $diff -= ($min * 60); + my $sec = $diff; + + return "${day}d ${hrs}h ${min}m ${sec}s ago."; +} + +# Hook for nick changes +sub on_nick { + my ($server, $new, $old, $address) = @_; + + my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)"; + my @cl=split(/,/,$server->get_channels()); + my $ok=0; + foreach (@cl) { + $ok += index($allowedChans, $_) >= 0; + } + if ( $ok >= 0) { + $lasthash{lc($old)}{'last'} = time(); + $lasthash{lc($old)}{'words'} = "$old changed nick to $new"; + $lasthash{lc($new)}{'last'} = time(); + $lasthash{lc($new)}{'words'} = "$new changed nick from $old"; + } +} + +# Hook for people quitting +sub on_quit { + my ($server, $nick, $address, $reason) = @_; + + my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)"; + my @cl=split(/,/,$server->get_channels()); + my $ok=0; + foreach (@cl) { + $ok += index($allowedChans, $_) >= 0; + } + if ( $ok >= 0) { + $lasthash{lc($nick)}{'last'} = time(); + if (! $reason) { + $lasthash{lc($nick)}{'words'} = "$nick quit IRC with no reason"; + } else { + $lasthash{lc($nick)}{'words'} = "$nick quit IRC stating '$reason'"; + } + } +} + +# Hook for people joining +sub on_join { + my ($server, $channel, $nick, $address) = @_; + + my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)"; + if (index($allowedChans, $channel) >= 0) { + $lasthash{lc($nick)}{'last'} = time(); + $lasthash{lc($nick)}{'words'} = "$nick joined $channel"; + } +} + +# Hook for people parting +sub on_part { + my ($server, $channel, $nick, $address, $reason) = @_; + + my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)"; + if (index($allowedChans, $channel) >= 0) { + $lasthash{lc($nick)}{'last'} = time(); + if (! $reason) { + $lasthash{lc($nick)}{'words'} = "$nick left from $channel with no reason"; + } else { + $lasthash{lc($nick)}{'words'} = "$nick left from $channel stating '$reason'"; + } + } +} + +# Hook for public messages. +# Only act on channels we are supposed to act on (settings_get_str) +sub on_public { + my ($server, $msg, $nick, $addr, $target) = @_; + utf8::decode($msg); + + $target = $nick if ( ! $target ); + $nick = $server->{'nick'} if ($nick =~ /^#/); + $target = lc($target); + + my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)"; + + # Debug + # Irssi::active_win()->print("Server: $server"); + # Irssi::active_win()->print("Msg : $msg"); + # Irssi::active_win()->print("Nick : $nick"); + # Irssi::active_win()->print("Addr : $addr"); + # Irssi::active_win()->print("Target: $target"); + # /Debug + + if (index($allowedChans, $target) >= 0) { + if ( ($msg =~ /^!lastspoke /) || ($msg =~ /^!seen /) || ($msg =~ /^!lastseen /)) { + my @parts = split(/ /,$msg); + + $lasthash{lc($nick)}{'last'} = time(); + $lasthash{lc($nick)}{'words'} = "$nick last queried information about " . $parts[1] . " on $target"; + + if (exists $lasthash{lc($parts[1])}) { + $server->command("MSG $target " . + to_term_enc($lasthash{lc($parts[1])}{'words'}) . + " " . calcDiff($lasthash{lc($parts[1])}{'last'})); + } else { + $server->command("MSG $target I don't know anything about " . $parts[1]); + } + } else { + $lasthash{lc($nick)}{'last'} = time(); + $lasthash{lc($nick)}{'words'} = "$nick last said '$msg' on $target"; + } + } +} + +# encode the words to term_charset +sub to_term_enc { + my ($words)= @_; + my $charset= Irssi::settings_get_str('term_charset'); + return encode($charset, $words); +} + +# write the memory to disk +sub save { + my $fa; + open($fa, '>:utf8', $filename); + my $yml = CPAN::Meta::YAML->new( \%lasthash ); + print $fa $yml->write_string(); + close($fa); +} + +# read form the disk to memory +sub load { + my $fi; + if (-e $filename) { + local $/; + open($fi, '<:utf8', $filename); + my $s= <$fi>; + my $yml= CPAN::Meta::YAML->read_string($s); + %lasthash = %{ $yml->[0] }; + close($fi); + } +} + +# hook for unload, /quit +sub UNLOAD { + save(); +} + +# Put hooks on events +Irssi::signal_add_last("message public", "on_public"); +Irssi::signal_add_last("message own_public", "on_public"); +Irssi::signal_add_last("message part", "on_part"); +Irssi::signal_add_last("message join", "on_join"); +Irssi::signal_add_last("message quit", "on_quit"); +Irssi::signal_add_last("message nick", "on_nick"); + +# Add setting +Irssi::settings_add_str("lastspoke", "lastspoke_channels", '%s'); + +load(); |