diff options
Diffstat (limited to 'scripts/babelirc.pl')
| -rw-r--r-- | scripts/babelirc.pl | 284 | 
1 files changed, 284 insertions, 0 deletions
| diff --git a/scripts/babelirc.pl b/scripts/babelirc.pl new file mode 100644 index 0000000..3472c6d --- /dev/null +++ b/scripts/babelirc.pl @@ -0,0 +1,284 @@ +# +# by Stefan "tommie" Tomanek <stefan@pico.ruhr.de> + +use strict; + +use vars qw($VERSION %IRSSI); +$VERSION = '2003020801'; +%IRSSI = ( +    authors     => 'Stefan \'tommie\' Tomanek', +    contact     => 'stefan@pico.ruhr.de', +    name        => 'babelirc', +    description => 'translates your messages via Babelfish', +    license     => 'GPLv2', +    url         => 'http://irssi.org/scripts/',                                     changed     => $VERSION, +    modules     => 'WWW::Babelfish Unicode::String Data::Dumper', +    sbitems     => 'babelirc_sb', +    commands	=> 'babelirc' +);   + +use WWW::Babelfish; +use Unicode::String; +use Data::Dumper; +use Irssi 20020324; +use Irssi::TextUI; +use POSIX; + + +use vars qw(%channels); + +sub show_help() { +    my $help = "babelirc $VERSION +/babelirc add <channel> <from> <to> +    Add a new translation entry for <channel> +/babelirc del <channel> +    Removes the translation for <channel> +/babelirc toggle <channel> +    Toggle selected entry +/babelirc list +    List all translation entries +"; +    my $text=''; +    foreach (split(/\n/, $help)) { +        $_ =~ s/^\/(.*)$/%9\/$1%9/; +        $text .= $_."\n"; +    } +    print CLIENTCRAP &draw_box("BabelIRC", $text, "help", 1); +} + + +sub draw_box ($$$$) { +    my ($title, $text, $footer, $colour) = @_; +    my $box = ''; +    my $exp_flags = Irssi::EXPAND_FLAG_IGNORE_EMPTY | Irssi::EXPAND_FLAG_IGNORE_REPLACES; +    $box .= '%R,--[%n%9%U'.$title.'%U%9%R]%n'."\n"; +    foreach (split(/\n/, $text)) {                                                      $box .= '%R|%n '.$_."\n"; +    }                                                                               $box .= '%R`--<%n'.$footer.'%R>->%n'; +    $box =~ s/%.//g unless $colour; +    return $box; +} + + +sub translate ($$$) { +    my ($text,$from,$to) = @_; +    Unicode::String->stringify_as('latin1'); +    my $s = new Unicode::String($text); +    my $obj = new WWW::Babelfish('agent' => 'Mozilla/8.0'); +    return undef unless $obj; +    my $data = $obj->translate('source' => $from, +                               'destination' => $to, +			       'text' => $s->utf8()); +    Unicode::String->stringify_as('utf8'); +    my $s2 = new Unicode::String($data); +    return($s2->latin1()); +} + +sub bg_trans ($$$$$$) { +    my ($text, $server, $target, $from, $to, $dir) = @_; +    my ($rh, $wh); +    pipe($rh, $wh); +    my $pid = fork(); +    if ($pid > 0) { +	close $wh; +	Irssi::pidwait_add($pid); +	my $pipetag; +	my @args = ($rh, \$pipetag); +	$pipetag = Irssi::input_add(fileno($rh), INPUT_READ, \&pipe_input, \@args); +    } else { +	eval { +	    my %trans = ( text=>$text, trans=>translate($text, $from, $to) ); +	    $trans{server} = $server->{tag}; +	    $trans{target} = $target->{name} if $target; +	    $trans{dir} = $dir; +	    my $dumper = Data::Dumper->new([\%trans]); +	    $dumper->Purity(1)->Deepcopy(1); +	    my $data = $dumper->Dump; +	    print($wh $data); +	    close($wh); +	}; +	POSIX::_exit(1); +    } +} + +sub pipe_input ($) { +    no strict; +    my ($rh, $pipetag) = @{$_[0]}; +    my $text; +    $text .= $_ foreach (<$rh>); +    close($rh); +    Irssi::input_remove($$pipetag); +    my %result = %{ eval "$text" }; +    unless (defined $result{target}) { +	print CLIENTCRAP $result{text}; +	print CLIENTCRAP $result{trans}; +    } else { +	my $server = Irssi::server_find_tag($result{server}); +	my $channel = $server->window_item_find($result{target}); +	my $stamp = Irssi::settings_get_str('babelirc_stamp'); +	my $text = $result{trans}; +	unless (defined $text) { +	    $channel->print("%R>>%n Translation failed", MSGLEVEL_CLIENTCRAP); +	    return; +	} +	$text = $result{text} if ($result{trans} eq ' '); +	if ($result{dir} eq 'out') { +	    $server->command('MSG '.$channel->{name}.' '.$text.' '.$stamp); +	} else { +	    $channel->print("%b`->%n ".$text.' '.$stamp, MSGLEVEL_CLIENTCRAP); +	} +	if ($channels{$channel->{name}}->{status} >= 2) { +	    $channels{$channel->{name}}->{status}--; +	} +	Irssi::statusbar_items_redraw('babelirc_sb'); +    } +} + + + +sub cmd_babelirc ($$$) { +    my ($args, $server, $witem) = @_; +    my @arg = split(/ +/, $args); +    if ($arg[0] eq 'add' && defined $arg[1] && defined $arg[2] && defined $arg[3]) { +	my $local = Irssi::settings_get_str('babelirc_my_language'); +	add_channel($arg[1],$arg[2],$arg[3]); +    } elsif ($arg[0] eq 'add' && defined $arg[1] && $witem) { +	my $local = Irssi::settings_get_str('babelirc_my_language'); +	add_channel($witem->{name},$local,$arg[1]); +    } elsif ($arg[0] eq 'del' && defined $arg[1]) { +	delete $channels{$arg[1]} if defined $channels{$arg[1]}; +	Irssi::statusbar_items_redraw('babelirc_sb'); +    } elsif ($arg[0] eq 'list') { +	list_trans(); +    } elsif ($arg[0] eq 'toggle' && defined $arg[1]) { +	toggle_trans($arg[1]); +    } elsif ($arg[0] eq 'toggle') { +	toggle_trans($witem->{name}) if $witem; +    } elsif ($arg[0] eq 'help' || $arg[0] eq '-h') { +	show_help() +    } elsif ($arg[0] eq 'save') { +	save_channels(); +    } elsif ($arg[0] eq 'load') { +	load_channels(); +    } +} + +sub toggle_trans ($) { +    my ($channel) = @_; +    return unless defined $channels{$channel}; +    $channels{$channel}{status} = not $channels{$channel}{status}; +    Irssi::statusbar_items_redraw('babelirc_sb'); +} + +sub list_trans () { +    my $text; +    foreach (sort keys %channels) { +	if ($channels{$_}{status} == 0) { +	    $text .= "%9<Q«%9"; +	} else { +	    $text .= "%g%9<Q«%9%n"; +	} +	$text .= ' %9'.$_."%9\n"; +	$text .= '    From: '.$channels{$_}{from}."\n"; +	$text .= '    To  : '.$channels{$_}{to}."\n"; +    } +    print CLIENTCRAP draw_box("BabelIRC", $text, "list", 1); +} + +sub add_channel ($$$) { +    my ($target, $from, $to) = @_; +    my %channel = (from=>$from, to=>$to, status => 0); +    $channels{$target} = \%channel; +    Irssi::statusbar_items_redraw('babelirc_sb'); +} + +sub save_channels { +    my $filename = Irssi::settings_get_str('babelirc_filename'); +    local *F; +    open F, '>'.$filename; +    my $data = Dumper(\%channels); +    print F $data; +    close F; +    print CLIENTCRAP "%R>>%n BabelIRC channels saved"; +} + +sub load_channels { +    my $filename = Irssi::settings_get_str('babelirc_filename'); +    return unless (-e $filename); +    local *F; +    open F, '<'.$filename; +    my $text; +    $text .= $_ foreach <F>; +    no strict "vars"; +    %channels = %{ eval "$text" }; +} + +sub babelirc_show ($$) { +    my ($item, $get_size_only) = @_; +    my $win = !Irssi::active_win() ? undef : Irssi::active_win()->{active}; +    if (ref $win && ($win->{type} eq "CHANNEL" || $win->{type} eq "QUERY") && defined $channels{$win->{name}}) { +	my $fish = "<Q«"; +	my @bubbles = ('°', 'o', '*', '·', ' '); +	$fish = $bubbles[rand(@bubbles)].$fish; +	$item->{min_size} = $item->{max_size} = length($fish); +	if ($channels{$win->{name}}->{status} == 1) { +	    $fish = '%U%g'.$fish.'%U%n'; +	} elsif ($channels{$win->{name}}->{status} >= 2) { +	    $fish = '%9%F'.$fish.'%F%9'; +	} +	my $format = "{sb ".$fish."}"; +	$item->default_handler($get_size_only, $format, 0, 1); +    } else { +	$item->{min_size} = $item->{max_size} = 0; +    } +} + +sub event_send_text ($$$) { +    my ($line, $server, $witem) = @_; +    return unless ref $witem; +    if (defined $channels{$witem->{name}}) { +	return if $channels{$witem->{name}}->{status} == 0; +	my $stamp = Irssi::settings_get_str('babelirc_stamp'); +	my $regexp = quotemeta($stamp); +	return if $line =~ / $regexp$/; +	Irssi::signal_stop(); +	$channels{$witem->{name}}->{status}++; +	Irssi::statusbar_items_redraw('babelirc_sb'); +	bg_trans($line, $server, $witem, $channels{$witem->{name}}->{from}, $channels{$witem->{name}}->{to}, "out"); +    } +} + +sub event_message_public ($$$$) { +    my ($server, $text, $nick, $address, $target) = @_;  +    return unless defined $channels{$target}; +    return unless $channels{$target}{status} > 0; +    my $regexp = '^'.Irssi::settings_get_str("babelirc_retranslate").'$'; +    return unless $text =~ /$regexp/; +    my $witem = Irssi::window_item_find($target); +    bg_trans($text, $server, $witem, $channels{$witem->{name}}->{to}, $channels{$witem->{name}}->{from}, "in"); +} + +Irssi::command_bind('babelirc', \&cmd_babelirc); +foreach my $cmd ('add', 'del', 'list', 'toggle', 'help', 'save', 'load') { +    Irssi::command_bind('babelirc '.$cmd => sub { +		    cmd_babelirc($cmd." ".$_[0], $_[1], $_[2]); }); +} + +Irssi::timeout_add(5000, sub { Irssi::statusbar_items_redraw('babelirc_sb');}, undef); + +Irssi::statusbar_item_register('babelirc_sb', 0, "babelirc_show"); + +Irssi::signal_add_first('send text', "event_send_text"); +Irssi::signal_add('message public', "event_message_public"); +Irssi::signal_add('window changed', sub {Irssi::statusbar_items_redraw('babelirc_sb');}); +Irssi::signal_add('setup saved', 'save_channels'); + +Irssi::settings_add_str($IRSSI{name}, 'babelirc_stamp', '[BabelIRC]'); +Irssi::settings_add_str($IRSSI{name}, 'babelirc_my_language', 'German'); +Irssi::settings_add_str($IRSSI{name}, 'babelirc_retranslate', ''); + +Irssi::settings_add_str($IRSSI{name}, 'babelirc_filename', Irssi::get_irssi_dir()."/babelirc_channels"); + +load_channels(); + +print CLIENTCRAP '%B>>%n '.$IRSSI{name}.' '.$VERSION.' loaded: /babelirc help for help'; + | 
