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');