1#!/usr/local/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# 23use strict; 24use Irssi; 25use Irssi::Irc; 26use vars qw($VERSION %IRSSI); 27 28$VERSION = "0.2"; 29%IRSSI = ( 30 authors => 'Sander Smeenk', 31 contact => 'irssi@freshdot.net', 32 name => 'lastspoke', 33 description => 'Remembers what people said last on what channels', 34 license => 'GNU GPLv2 or later', 35 url => 'http://irssi.freshdot.net/', 36); 37 38my $target; 39 40# Storage for the data. 41my %lasthash; 42 43# Calculates the difference between two unix times and returns 44# a string like '15d 23h 42m 15s ago.' 45sub calcDiff { 46 my ($when) = @_; 47 48 my $diff = (time() - $when); 49 my $day = int($diff / 86400); $diff -= ($day * 86400); 50 my $hrs = int($diff / 3600); $diff -= ($hrs * 3600); 51 my $min = int($diff / 60); $diff -= ($min * 60); 52 my $sec = $diff; 53 54 return "${day}d ${hrs}h ${min}m ${sec}s ago."; 55} 56 57# Hook for nick changes 58sub on_nick { 59 my ($server, $new, $old, $address) = @_; 60 61 my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)"; 62 if (index($allowedChans, $target) >= 0) { 63 $lasthash{lc($old)}{'last'} = time(); 64 $lasthash{lc($old)}{'words'} = "$old changed nick to $new"; 65 $lasthash{lc($new)}{'last'} = time(); 66 $lasthash{lc($new)}{'words'} = "$new changed nick from $old"; 67 } 68} 69 70# Hook for people quitting 71sub on_quit { 72 my ($server, $nick, $address, $reason) = @_; 73 74 my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)"; 75 if (index($allowedChans, $target) >= 0) { 76 $lasthash{lc($nick)}{'last'} = time(); 77 if (! $reason) { 78 $lasthash{lc($nick)}{'words'} = "$nick quit IRC with no reason"; 79 } else { 80 $lasthash{lc($nick)}{'words'} = "$nick quit IRC stating '$reason'"; 81 } 82 } 83} 84 85# Hook for people joining 86sub on_join { 87 my ($server, $channel, $nick, $address) = @_; 88 89 my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)"; 90 if (index($allowedChans, $channel) >= 0) { 91 $lasthash{lc($nick)}{'last'} = time(); 92 $lasthash{lc($nick)}{'words'} = "$nick joined $channel"; 93 } 94} 95 96# Hook for people parting 97sub on_part { 98 my ($server, $channel, $nick, $address, $reason) = @_; 99 100 my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)"; 101 if (index($allowedChans, $channel) >= 0) { 102 $lasthash{lc($nick)}{'last'} = time(); 103 if (! $reason) { 104 $lasthash{lc($nick)}{'words'} = "$nick left from $channel with no reason"; 105 } else { 106 $lasthash{lc($nick)}{'words'} = "$nick left from $channel stating '$reason'"; 107 } 108 } 109} 110 111# Hook for public messages. 112# Only act on channels we are supposed to act on (settings_get_str) 113sub on_public { 114 my ($server, $msg, $nick, $addr, $_target) = @_; 115 116 $_target = $nick if ( ! $_target ); 117 $nick = $server->{'nick'} if ($nick =~ /^#/); 118 $target = lc($target); 119 120 my $allowedChans = lc(Irssi::settings_get_str("lastspoke_channels")) || "(null)"; 121 122 # Debug 123 # Irssi::active_win()->print("Server: $server"); 124 # Irssi::active_win()->print("Msg : $msg"); 125 # Irssi::active_win()->print("Nick : $nick"); 126 # Irssi::active_win()->print("Addr : $addr"); 127 # Irssi::active_win()->print("Target: $target"); 128 # /Debug 129 130 if (index($allowedChans, $target) >= 0) { 131 if ( ($msg =~ /^!lastspoke /) || ($msg =~ /^!seen /) || ($msg =~ /^!lastseen /)) { 132 my @parts = split(/ /,$msg); 133 134 $lasthash{lc($nick)}{'last'} = time(); 135 $lasthash{lc($nick)}{'words'} = "$nick last queried information about " . $parts[1] . " on $target"; 136 137 if (exists $lasthash{lc($parts[1])}) { 138 $server->command("MSG $target " . $lasthash{lc($parts[1])}{'words'} . " " . calcDiff($lasthash{lc($parts[1])}{'last'})); 139 } else { 140 $server->command("MSG $target I don't know anything about " . $parts[1]); 141 } 142 } else { 143 $lasthash{lc($nick)}{'last'} = time(); 144 $lasthash{lc($nick)}{'words'} = "$nick last said '$msg' on $target"; 145 } 146 } 147} 148 149# Put hooks on events 150Irssi::signal_add_last("message public", "on_public"); 151Irssi::signal_add_last("message own_public", "on_public"); 152Irssi::signal_add_last("message part", "on_part"); 153Irssi::signal_add_last("message join", "on_join"); 154Irssi::signal_add_last("message quit", "on_quit"); 155Irssi::signal_add_last("message nick", "on_nick"); 156 157# Add setting 158Irssi::settings_add_str("lastspoke", "lastspoke_channels", '%s'); 159