User:Aphrael Runestar/colourtextrep.pl

From Wikipedia, the free encyclopedia
#
# link replacement script for irssi.
#
# May end up being downloadable from http://wikipedia.org.
#

use strict;
use Irssi;
use vars qw($VERSION %IRSSI);

$VERSION = 0.1;
%IRSSI = (
  authors     => "Kiyoshi \"Aphrael Runestar\" Aman, Timo Sirainen, Ian Peters",
  contact     => "childgoddess\@gmail.com",
  name        => "colourlinkrep",
  description => "link replacement script for irssi; replaces page with http://en.wikipedia.org/wiki/page, merged with nickcolor.pl",
  license     => "Creative Commons",
  changed     => "20040912"
);

# hm.. i should make it possible to use the existing one..
Irssi::theme_register([
  'pubmsg_hilight', '{pubmsghinick $0 $3 $1}$2'
]);

my %saved_colors;
my %session_colors = {};
my @colors = qw/2 3 4 5 6 7 9 10 11 12 13/;

sub load_colors {
  open COLORS, "$ENV{HOME}/.irssi/saved_colors";

  while (<COLORS>) {
    # I don't know why this is necessary only inside of irssi
    my @lines = split "\n";
    foreach my $line (@lines) {
      my($nick, $color) = split ":", $line;
      $saved_colors{$nick} = $color;
    }
  }

  close COLORS;
}

sub save_colors {
  open COLORS, ">$ENV{HOME}/.irssi/saved_colors";

  foreach my $nick (keys %saved_colors) {
    print COLORS "$nick:$saved_colors{$nick}\n";
  }

  close COLORS;
}

# If someone we've colored (either through the saved colors, or the hash
# function) changes their nick, we'd like to keep the same color associated
# with them (but only in the session_colors, ie a temporary mapping).

sub sig_nick {
  my ($server, $newnick, $nick, $address) = @_;
  my $color;

 $newnick = substr ($newnick, 1) if ($newnick =~ /^:/);

  if ($color = $saved_colors{$nick}) {
    $session_colors{$newnick} = $color;
  } elsif ($color = $session_colors{$nick}) {
    $session_colors{$newnick} = $color;
  }
}

# This gave reasonable distribution values when run across
# /usr/share/dict/words

sub simple_hash {
  my ($string) = @_;
  chomp $string;
  my @chars = split //, $string;
  my $counter;

  foreach my $char (@chars) {
    $counter += ord $char;
  }

  $counter = $colors[$counter % 11];

  return $counter;
}

  sub cmd_color {
  my ($data, $server, $witem) = @_;
  my ($op, $nick, $color) = split " ", $data;

 $op = lc $op; 
  if (!$op) {
    Irssi::print ("No operation given");
  } elsif ($op eq "save") {
    save_colors;
  } elsif ($op eq "set") {
    if (!$nick) {
      Irssi::print ("Nick not given");
    } elsif (!$color) {
      Irssi::print ("Color not given");
    } elsif ($color < 2 || $color > 14) {
      Irssi::print ("Color must be between 2 and 14 inclusive");
    } else {
      $saved_colors{$nick} = $color;
    }
  } elsif ($op eq "clear") {
    if (!$nick) {
      Irssi::print ("Nick not given");
    } else {
      delete ($saved_colors{$nick});
    }
  } elsif ($op eq "list") {
    Irssi::print ("\nSaved Colors:");
    foreach my $nick (keys %saved_colors) {
      Irssi::print (chr (3) . "$saved_colors{$nick}$nick" .
		    chr (3) . "1 ($saved_colors{$nick})");
    }
  } elsif ($op eq "preview") {
    Irssi::print ("\nAvailable colors:");
    foreach my $i (2..14) {
      Irssi::print (chr (3) . "$i" . "Color #$i");
    }
  }
}

load_colors;

Irssi::command_bind('color', 'cmd_color');

Irssi::signal_add('message public', 'sig_public');
Irssi::signal_add('event nick', 'sig_nick');
Irssi::signal_add "event privmsg" => sub {
  my ($server, $data, $nick, $address) = @_;
  my ($target, $text) = split / :/,$data,2;
  my $colour;
 
  return unless ($target eq "#wikipedia");
  my $chanrec = $server->channel_find($target);
  return if not $chanrec;
  my $nickrec = $chanrec->nick_find($nick);
  return if not $nickrec;
  my $nickmode = $nickrec->{op} ? "@" : $nickrec->{voice} ? "+" : "";
  
  $text =~ s/\[\[/http:\/\/en.wikipedia.org\/wiki\//g;
  $text =~ s/\]\]//g;
  if ($saved_colors{$nick}) {
    $colour = $saved_colors{$nick};
  }
  elsif ($session_colors{$nick}) {
    $colour = $session_colors{$nick};
  }
  else {
    $session_colors($nick) = int(rand($#colors));
    $colour = $session_colors($nick);
  }
  $colour = "0".$colour if ($colour < 10);
  $output = "<$nickmode".chr(3).$colour.$nick.chr(3)."> $text";
  $server->print($target,$output,MSGLEVEL_PUBLIC);
  Irssi::signal_stop();
}