/var/www/www.irssi.org-old/scripts/html/babelirc.pl


   1 #
   2 # by Stefan "tommie" Tomanek <stefan@pico.ruhr.de>
   3 
   4 use strict;
   5 
   6 use vars qw($VERSION %IRSSI);
   7 $VERSION = '2003020801';
   8 %IRSSI = (
   9     authors     => 'Stefan \'tommie\' Tomanek',
  10     contact     => 'stefan@pico.ruhr.de',
  11     name        => 'babelirc',
  12     description => 'translates your messages via Babelfish',
  13     license     => 'GPLv2',
  14     url         => 'http://irssi.org/scripts/',                                     changed     => $VERSION,
  15     modules     => 'WWW::Babelfish Unicode::String Data::Dumper',
  16     sbitems     => 'babelirc_sb',
  17     commands	=> 'babelirc'
  18 );  
  19 
  20 use WWW::Babelfish;
  21 use Unicode::String;
  22 use Data::Dumper;
  23 use Irssi 20020324;
  24 use Irssi::TextUI;
  25 use POSIX;
  26 
  27 
  28 use vars qw(%channels);
  29 
  30 sub show_help() {
  31     my $help = "babelirc $VERSION
  32 /babelirc add <channel> <from> <to>
  33         Add a new translation entry for <channel>
  34 /babelirc del <channel>
  35         Removes the translation for <channel>
  36 /babelirc toggle <channel>
  37         Toggle selected entry
  38 /babelirc list
  39         List all translation entries
  40 ";
  41     my $text='';
  42     foreach (split(/\n/, $help)) {
  43         $_ =~ s/^\/(.*)$/%9\/$1%9/;
  44         $text .= $_."\n";
  45     }
  46     print CLIENTCRAP &draw_box("BabelIRC", $text, "help", 1);
  47 }
  48 
  49 
  50 sub draw_box ($$$$) {
  51     my ($title, $text, $footer, $colour) = @_;
  52     my $box = '';
  53     my $exp_flags = Irssi::EXPAND_FLAG_IGNORE_EMPTY | Irssi::EXPAND_FLAG_IGNORE_REPLACES;
  54     $box .= '%R,--[%n%9%U'.$title.'%U%9%R]%n'."\n";
  55     foreach (split(/\n/, $text)) {                                                      $box .= '%R|%n '.$_."\n";
  56     }                                                                               $box .= '%R`--<%n'.$footer.'%R>->%n';
  57     $box =~ s/%.//g unless $colour;
  58     return $box;
  59 }
  60 
  61 
  62 sub translate ($$$) {
  63     my ($text,$from,$to) = @_;
  64     Unicode::String->stringify_as('latin1');
  65     my $s = new Unicode::String($text);
  66     my $obj = new WWW::Babelfish('agent' => 'Mozilla/8.0');
  67     return undef unless $obj;
  68     my $data = $obj->translate('source' => $from,
  69                                'destination' => $to,
  70 			       'text' => $s->utf8());
  71     Unicode::String->stringify_as('utf8');
  72     my $s2 = new Unicode::String($data);
  73     return($s2->latin1());
  74 }
  75 
  76 sub bg_trans ($$$$$$) {
  77     my ($text, $server, $target, $from, $to, $dir) = @_;
  78     my ($rh, $wh);
  79     pipe($rh, $wh);
  80     my $pid = fork();
  81     if ($pid > 0) {
  82 	close $wh;
  83 	Irssi::pidwait_add($pid);
  84 	my $pipetag;
  85 	my @args = ($rh, \$pipetag);
  86 	$pipetag = Irssi::input_add(fileno($rh), INPUT_READ, \&pipe_input, \@args);
  87     } else {
  88 	eval {
  89 	    my %trans = ( text=>$text, trans=>translate($text, $from, $to) );
  90 	    $trans{server} = $server->{tag};
  91 	    $trans{target} = $target->{name} if $target;
  92 	    $trans{dir} = $dir;
  93 	    my $dumper = Data::Dumper->new([\%trans]);
  94 	    $dumper->Purity(1)->Deepcopy(1);
  95 	    my $data = $dumper->Dump;
  96 	    print($wh $data);
  97 	    close($wh);
  98 	};
  99 	POSIX::_exit(1);
 100     }
 101 }
 102 
 103 sub pipe_input ($) {
 104     no strict;
 105     my ($rh, $pipetag) = @{$_[0]};
 106     my $text;
 107     $text .= $_ foreach (<$rh>);
 108     close($rh);
 109     Irssi::input_remove($$pipetag);
 110     my %result = %{ eval "$text" };
 111     unless (defined $result{target}) {
 112 	print CLIENTCRAP $result{text};
 113 	print CLIENTCRAP $result{trans};
 114     } else {
 115 	my $server = Irssi::server_find_tag($result{server});
 116 	my $channel = $server->window_item_find($result{target});
 117 	my $stamp = Irssi::settings_get_str('babelirc_stamp');
 118 	my $text = $result{trans};
 119 	unless (defined $text) {
 120 	    $channel->print("%R>>%n Translation failed", MSGLEVEL_CLIENTCRAP);
 121 	    return;
 122 	}
 123 	$text = $result{text} if ($result{trans} eq '&nbsp;');
 124 	if ($result{dir} eq 'out') {
 125 	    $server->command('MSG '.$channel->{name}.' '.$text.' '.$stamp);
 126 	} else {
 127 	    $channel->print("%b`->%n ".$text.' '.$stamp, MSGLEVEL_CLIENTCRAP);
 128 	}
 129 	if ($channels{$channel->{name}}->{status} >= 2) {
 130 	    $channels{$channel->{name}}->{status}--;
 131 	}
 132 	Irssi::statusbar_items_redraw('babelirc_sb');
 133     }
 134 }
 135 
 136 
 137 
 138 sub cmd_babelirc ($$$) {
 139     my ($args, $server, $witem) = @_;
 140     my @arg = split(/ +/, $args);
 141     if ($arg[0] eq 'add' && defined $arg[1] && defined $arg[2] && defined $arg[3]) {
 142 	my $local = Irssi::settings_get_str('babelirc_my_language');
 143 	add_channel($arg[1],$arg[2],$arg[3]);
 144     } elsif ($arg[0] eq 'add' && defined $arg[1] && $witem) {
 145 	my $local = Irssi::settings_get_str('babelirc_my_language');
 146 	add_channel($witem->{name},$local,$arg[1]);
 147     } elsif ($arg[0] eq 'del' && defined $arg[1]) {
 148 	delete $channels{$arg[1]} if defined $channels{$arg[1]};
 149 	Irssi::statusbar_items_redraw('babelirc_sb');
 150     } elsif ($arg[0] eq 'list') {
 151 	list_trans();
 152     } elsif ($arg[0] eq 'toggle' && defined $arg[1]) {
 153 	toggle_trans($arg[1]);
 154     } elsif ($arg[0] eq 'toggle') {
 155 	toggle_trans($witem->{name}) if $witem;
 156     } elsif ($arg[0] eq 'help' || $arg[0] eq '-h') {
 157 	show_help()
 158     } elsif ($arg[0] eq 'save') {
 159 	save_channels();
 160     } elsif ($arg[0] eq 'load') {
 161 	load_channels();
 162     }
 163 }
 164 
 165 sub toggle_trans ($) {
 166     my ($channel) = @_;
 167     return unless defined $channels{$channel};
 168     $channels{$channel}{status} = not $channels{$channel}{status};
 169     Irssi::statusbar_items_redraw('babelirc_sb');
 170 }
 171 
 172 sub list_trans () {
 173     my $text;
 174     foreach (sort keys %channels) {
 175 	if ($channels{$_}{status} == 0) {
 176 	    $text .= "%9<Q«%9";
 177 	} else {
 178 	    $text .= "%g%9<Q«%9%n";
 179 	}
 180 	$text .= ' %9'.$_."%9\n";
 181 	$text .= '    From: '.$channels{$_}{from}."\n";
 182 	$text .= '    To  : '.$channels{$_}{to}."\n";
 183     }
 184     print CLIENTCRAP draw_box("BabelIRC", $text, "list", 1);
 185 }
 186 
 187 sub add_channel ($$$) {
 188     my ($target, $from, $to) = @_;
 189     my %channel = (from=>$from, to=>$to, status => 0);
 190     $channels{$target} = \%channel;
 191     Irssi::statusbar_items_redraw('babelirc_sb');
 192 }
 193 
 194 sub save_channels {
 195     my $filename = Irssi::settings_get_str('babelirc_filename');
 196     local *F;
 197     open F, '>'.$filename;
 198     my $data = Dumper(\%channels);
 199     print F $data;
 200     close F;
 201     print CLIENTCRAP "%R>>%n BabelIRC channels saved";
 202 }
 203 
 204 sub load_channels {
 205     my $filename = Irssi::settings_get_str('babelirc_filename');
 206     return unless (-e $filename);
 207     local *F;
 208     open F, '<'.$filename;
 209     my $text;
 210     $text .= $_ foreach <F>;
 211     no strict "vars";
 212     %channels = %{ eval "$text" };
 213 }
 214 
 215 sub babelirc_show ($$) {
 216     my ($item, $get_size_only) = @_;
 217     my $win = !Irssi::active_win() ? undef : Irssi::active_win()->{active};
 218     if (ref $win && ($win->{type} eq "CHANNEL" || $win->{type} eq "QUERY") && defined $channels{$win->{name}}) {
 219 	my $fish = "<Q«";
 220 	my @bubbles = ('°', 'o', '*', '·', ' ');
 221 	$fish = $bubbles[rand(@bubbles)].$fish;
 222 	$item->{min_size} = $item->{max_size} = length($fish);
 223 	if ($channels{$win->{name}}->{status} == 1) {
 224 	    $fish = '%U%g'.$fish.'%U%n';
 225 	} elsif ($channels{$win->{name}}->{status} >= 2) {
 226 	    $fish = '%9%F'.$fish.'%F%9';
 227 	}
 228 	my $format = "{sb ".$fish."}";
 229 	$item->default_handler($get_size_only, $format, 0, 1);
 230     } else {
 231 	$item->{min_size} = $item->{max_size} = 0;
 232     }
 233 }
 234 
 235 sub event_send_text ($$$) {
 236     my ($line, $server, $witem) = @_;
 237     return unless ref $witem;
 238     if (defined $channels{$witem->{name}}) {
 239 	return if $channels{$witem->{name}}->{status} == 0;
 240 	my $stamp = Irssi::settings_get_str('babelirc_stamp');
 241 	my $regexp = quotemeta($stamp);
 242 	return if $line =~ / $regexp$/;
 243 	Irssi::signal_stop();
 244 	$channels{$witem->{name}}->{status}++;
 245 	Irssi::statusbar_items_redraw('babelirc_sb');
 246 	bg_trans($line, $server, $witem, $channels{$witem->{name}}->{from}, $channels{$witem->{name}}->{to}, "out");
 247     }
 248 }
 249 
 250 sub event_message_public ($$$$) {
 251     my ($server, $text, $nick, $address, $target) = @_; 
 252     return unless defined $channels{$target};
 253     return unless $channels{$target}{status} > 0;
 254     my $regexp = '^'.Irssi::settings_get_str("babelirc_retranslate").'$';
 255     return unless $text =~ /$regexp/;
 256     my $witem = Irssi::window_item_find($target);
 257     bg_trans($text, $server, $witem, $channels{$witem->{name}}->{to}, $channels{$witem->{name}}->{from}, "in");
 258 }
 259 
 260 Irssi::command_bind('babelirc', \&cmd_babelirc);
 261 foreach my $cmd ('add', 'del', 'list', 'toggle', 'help', 'save', 'load') {
 262     Irssi::command_bind('babelirc '.$cmd => sub {
 263 		    cmd_babelirc($cmd." ".$_[0], $_[1], $_[2]); });
 264 }
 265 
 266 Irssi::timeout_add(5000, sub { Irssi::statusbar_items_redraw('babelirc_sb');}, undef);
 267 
 268 Irssi::statusbar_item_register('babelirc_sb', 0, "babelirc_show");
 269 
 270 Irssi::signal_add_first('send text', "event_send_text");
 271 Irssi::signal_add('message public', "event_message_public");
 272 Irssi::signal_add('window changed', sub {Irssi::statusbar_items_redraw('babelirc_sb');});
 273 Irssi::signal_add('setup saved', 'save_channels');
 274 
 275 Irssi::settings_add_str($IRSSI{name}, 'babelirc_stamp', '[BabelIRC]');
 276 Irssi::settings_add_str($IRSSI{name}, 'babelirc_my_language', 'German');
 277 Irssi::settings_add_str($IRSSI{name}, 'babelirc_retranslate', '');
 278 
 279 Irssi::settings_add_str($IRSSI{name}, 'babelirc_filename', Irssi::get_irssi_dir()."/babelirc_channels");
 280 
 281 load_channels();
 282 
 283 print CLIENTCRAP '%B>>%n '.$IRSSI{name}.' '.$VERSION.' loaded: /babelirc help for help';
 284