html/mood.pl


   1 #!/usr/bin/perl
   2 #
   3 # This script tracks the general mood in a channel.
   4 # 
   5 #
   6 # Changelog:
   7 # 19.03.2002
   8 # *first release
   9 #
  10 # 20.03.2002
  11 # *some regexp tweaking
  12 #
  13 # 07.04.2002
  14 # *own messages can be interpreted
  15 
  16 use strict;
  17 
  18 use vars qw($VERSION %IRSSI);
  19 
  20 $VERSION = "20031207";
  21 %IRSSI = (
  22     authors     => "Stefan 'tommie' Tomanek",
  23     contact     => "stefan\@pico.ruhr.de",
  24     name        => "Mood",
  25     description => "Keeps track of the channel mood",
  26     license     => "GPLv2",
  27     sbitems     => "moodbar",
  28     changed     => "$VERSION",
  29 );
  30 
  31 use Irssi;
  32 use Irssi::TextUI;
  33 use vars qw(%channels $eye $refresh $shouting $bored_mouth);
  34 
  35 sub find_smiley {
  36     my ($msg) = @_;
  37     my $eyes = '[:=8;]';
  38     my $noses = '[\-\o]?';
  39     my $sad = '[\(\<\[]';
  40     my $happy = '[\)\>\]D]';
  41     my %smiley = ($eyes.$noses.$happy         =>  10,
  42 		  $sad.$noses.$eyes           =>  10,
  43 		  $eyes.$noses.$sad           => -10,
  44 		  $happy.$noses.$eyes         => -10,
  45 		  $eyes.'\.+'.$noses.$sad     => -20,
  46 		  $happy.$noses.'\.+'.$eyes   => -20,
  47 		 );
  48     foreach (keys(%smiley)) {
  49 	return($smiley{$_}) if ($msg =~ m/.*($_).*/);
  50     }
  51     return 0;
  52 }
  53 
  54 sub event_event_privmsg {
  55     my ($server, $data, $nick, $address) = @_;
  56     my ($target, $msg) = split(/ :/, $data,2);
  57     change_mood($target, find_smiley($msg));
  58 }
  59 
  60 sub event_message_own_public {
  61     my ($server, $msg, $target) = @_;
  62     change_mood($target, find_smiley($msg));
  63 }
  64 
  65 sub event_message_kick {
  66     my ($server, $channel, $nick, $kicker, $address, $reason) = @_;
  67     change_mood($channel, -20);
  68 }
  69 
  70 sub event_ban_new {
  71     my ($channel, $ban) = @_;
  72     my $name = $channel->{name};
  73     change_mood($name, -20);
  74 }
  75 
  76 sub event_ban_remove {
  77     my ($channel, $ban) = @_;
  78     my $name = $channel->{name};
  79     change_mood($name, 20);
  80 }
  81 
  82 sub event_netsplit_new {
  83     my ($netsplit) = @_;
  84     #FIXME Not Idea :)
  85     #Irssi::print $netsplit->{nick};
  86 }
  87 
  88 sub event_window_hilight {
  89     my ($window) = @_;
  90     open_mouth();
  91 }
  92 
  93 sub change_mood {
  94     my ($name, $points) = @_;
  95     if (not exists $channels{$name}) {
  96 	$channels{lc $name} = 0;
  97     }
  98     $channels{lc $name} += $points;
  99     mood_refresh();
 100 }
 101 
 102 sub draw_smiley {
 103     my ($points) = @_;
 104     
 105     my $mouth = $bored_mouth;
 106     my $nose = Irssi::settings_get_str('mood_nose');
 107     
 108     if    ($points > 20) { $mouth = 'D'; }
 109     elsif ($points >  0) { $mouth = ')'; }
 110     elsif ($points <-20) { $mouth = '<'; }
 111     elsif ($points <  0) { $mouth = '('; }
 112     if ($shouting) { $mouth = 'O' };
 113     return $eye.$nose.$mouth;
 114 }
 115 
 116 sub mood_show {
 117     my ($item, $get_size_only) = @_;
 118     my $win = !Irssi::active_win() ? undef : Irssi::active_win()->{active};
 119     
 120     if (ref $win && ($win->{type}) and $win->{type} eq "CHANNEL") {
 121 	my $target = lc $win->{name};
 122 	my $face = draw_smiley($channels{$target});
 123 	my $format = "{sb ".$face."}";
 124 	$item->{min_size} = $item->{max_size} = length($face);
 125 	$item->default_handler($get_size_only, $format, 0, 1);
 126     } else {
 127 	$item->{min_size} = $item->{max_size} = 0;
 128     }
 129 }
 130 
 131 sub mood_decay {
 132     foreach (keys %channels) {
 133 	if    ($channels{$_} < 0) {
 134 	    $channels{$_}++;
 135 	    mood_refresh() if (! draw_smiley($channels{$_}) eq draw_smiley($channels{$_}-1));
 136 	} elsif ($channels{$_} > 0) {
 137 	    $channels{$_}--;
 138 	    mood_refresh() if (! draw_smiley($channels{$_}) eq draw_smiley($channels{$_}+1));
 139 	}
 140     }
 141 }
 142 
 143 sub close_eyes {
 144     ($refresh) && Irssi::timeout_remove($refresh);
 145     $eye = '|';
 146     mood_refresh();
 147     $refresh=Irssi::timeout_add(200, 'open_eyes' , undef);
 148 }
 149 
 150 sub open_eyes {
 151     ($refresh) && Irssi::timeout_remove($refresh);
 152     $eye = ':';
 153     mood_refresh();
 154     my $min_delay = Irssi::settings_get_int('mood_blink');
 155     my $next_close = int( rand()*6000 + $min_delay );
 156     $refresh=Irssi::timeout_add($next_close, 'close_eyes', undef);
 157 }
 158 
 159 sub open_mouth {
 160     $shouting = 1;
 161     mood_refresh();
 162     Irssi::timeout_add(2000, 'close_mouth', undef);
 163 }
 164 
 165 sub close_mouth {
 166     Irssi::timeout_remove('close_mouth');
 167     $shouting = 0;
 168     mood_refresh();
 169 }
 170 
 171 sub mood_refresh {
 172     Irssi::statusbar_items_redraw('moodbar');
 173 }
 174 
 175 sub change_bored_mouth {
 176     $bored_mouth = ('\\\\\\\\', '|', '/')[int( rand(3) )];
 177 }
 178 
 179 #Irssi::signal_add('window item hilight', 'event_window_hilight');
 180 Irssi::signal_add('event privmsg', 'event_event_privmsg');
 181 Irssi::signal_add('message own_public', 'event_message_own_public');
 182 Irssi::signal_add('message kick','event_message_kick');
 183 Irssi::signal_add('ban new','event_ban_new');
 184 Irssi::signal_add('ban remove','event_ban_remove');
 185 Irssi::signal_add('netsplit new','event_netsplit_new');
 186 
 187 Irssi::settings_add_int('misc', 'mood_blink', 6000);
 188 Irssi::settings_add_str('misc', 'mood_nose', '-');
 189 
 190 Irssi::statusbar_item_register('moodbar', 0, 'mood_show');
 191 
 192 Irssi::timeout_add(5000, 'mood_decay', undef);
 193 Irssi::timeout_add(10000, 'change_bored_mouth', undef);
 194 
 195 close_mouth;
 196 change_bored_mouth();
 197 open_eyes();