1#!/usr/local/bin/perl 2# 3# by Stefan "Tommie" Tomanek 4use strict; 5 6use vars qw($VERSION %IRSSI); 7$VERSION = '20040515'; 8%IRSSI = ( 9 authors => 'Stefan \'tommie\' Tomanek', 10 contact => 'stefan@pico.ruhr.de', 11 name => 'leodict', 12 description => 'translates via dict.leo.org', 13 license => 'GPLv2', 14 url => 'http://irssi.org/scripts/', 15 changed => $VERSION, 16 modules => 'LWP::Simple Data::Dumper', 17 commands => "leodict" 18); 19use vars qw($forked); 20use Irssi 20020324; 21use LWP::Simple; 22use POSIX; 23 24 25sub draw_box ($$$$) { 26 my ($title, $text, $footer, $colour) = @_; 27 my $box = ''; 28 $box .= '%R,--[%n%9%U'.$title.'%U%9%R]%n'."\n"; 29 foreach (split(/\n/, $text)) { 30 $box .= '%R|%n '.$_."\n"; 31 } 32 $box .= '%R`--<%n'.$footer.'%R>->%n'; 33 $box =~ s/%.//g unless $colour; 34 return $box; 35} 36 37sub show_help() { 38 my $help = "LeoDict $VERSION 39/leodict <word1> <word2>... 40 searches dict.leo.org for appropiate translations 41/leodict -p <word1>... 42 paste the translations to the current channel or query 43 The number of translations is limited by the setting 44 'leodict_paste_max_translations' 45/leodict -b <word1>... 46 open dict.leo.org in your web browser (uses openurl.pl) 47"; 48 my $text=''; 49 foreach (split(/\n/, $help)) { 50 $_ =~ s/^\/(.*)$/%9\/$1%9/; 51 $text .= $_."\n"; 52 } 53 print CLIENTCRAP draw_box($IRSSI{name}, $text, "help", 1); 54} 55 56 57 58sub get_page ($) { 59 my ($word) = @_; 60 return get('http://dict.leo.org/?search='.$word.'&relink=off'); 61} 62 63sub get_words ($) { 64 my ($word) = @_; 65 my @translations; 66 my $data = get_page($word); 67 foreach (split(/\n/, $data)) { 68 if (/(\d+) search results/) { 69 my $results = $1; 70 foreach (split(/\<\/TR\>/)) { 71 my @trans; 72 foreach (split(/\<\/TD\>/)) { 73 $_ =~ s/\<.*?\>//g; 74 $_ =~ s/^ *//g; 75 $_ =~ s/ *$//g; 76 $_ =~ s/ //g; 77 $_ =~ s/^\t*//g; 78 # Thanks to senneth 79 $_ =~ s/Direct Matches//g; 80 next if (/\d+ search results/); 81 #print $_."\n" if (/\w/); 82 push @trans, $_ if (/\w/); 83 } 84 if (scalar(@trans) == 2) { 85 push @translations, \@trans; 86 } 87 } 88 } 89 } 90 return \@translations; 91} 92 93sub call_openurl ($) { 94 my ($url) = @_; 95 no strict "refs"; 96 # check for a loaded openurl 97 if (defined &{ "Irssi::Script::openurl::launch_url" } ) { 98 &{ "Irssi::Script::openurl::launch_url" }($url); 99 } else { 100 print CLIENTCRAP "%R>>%n Please install openurl.pl"; 101 } 102} 103 104sub translate ($$$) { 105 my ($word,$target,$server) = @_; 106 my ($rh, $wh); 107 pipe($rh, $wh); 108 if ($forked) { 109 print CLIENTCRAP "%R>>%n Please wait until your earlier request has been finished."; 110 return; 111 } 112 my $pid = fork(); 113 $forked = 1; 114 if ($pid > 0) { 115 print CLIENTCRAP "%R>>%n Please wait..." unless $target; 116 close $wh; 117 Irssi::pidwait_add($pid); 118 my $pipetag; 119 my @args = ($rh, \$pipetag, $target, $server); 120 $pipetag = Irssi::input_add(fileno($rh), INPUT_READ, \&pipe_input, \@args); 121 } else { 122 eval { 123 my %result; 124 $result{trans} = get_words($word); 125 $result{word} = $word; 126 my $dumper = Data::Dumper->new([\%result]); 127 $dumper->Purity(1)->Deepcopy(1)->Indent(0); 128 my $data = $dumper->Dump; 129 print($wh $data); 130 }; 131 close($wh); 132 POSIX::_exit(1); 133 } 134} 135 136sub pipe_input ($) { 137 my ($rh, $pipetag, $target, $tag) = @{$_[0]}; 138 $forked = 0; 139 my $text; 140 $text .= $_ foreach <$rh>; 141 close $rh; 142 Irssi::input_remove($$pipetag); 143 unless ($text) { 144 print CLIENTCRAP "%R<<%n Something weird happend"; 145 return(0); 146 } 147 no strict 'vars'; 148 my %incoming = %{ eval("$text") }; 149 if ($target eq '') { 150 show_translations($incoming{trans},$incoming{word}); 151 } else { 152 my $server = Irssi::server_find_tag($tag); 153 my $witem = $server->window_item_find($target); 154 paste_translations($incoming{trans}, $incoming{word}, $witem) if $witem; 155 } 156} 157 158sub show_translations($$) { 159 my @trans = @{$_[0]}; 160 my $word = $_[1]; 161 if (@trans) { 162 my $text; 163 foreach (@trans) { 164 $text .= "%U".$_->[0]."%U \n"; 165 $text .= " `-> ".$_->[1]."\n"; 166 } 167 print CLIENTCRAP draw_box('LeoDict', $text, $word, 1); 168 } else { 169 print CLIENTCRAP "%R>>>%n No translations found (".$word.")."; 170 } 171} 172 173sub paste_translations ($$) { 174 my ($trans, $word, $target) = @_; 175 return unless ($target->{type} eq "CHANNEL" || $target->{type} eq "QUERY"); 176 if (@$trans) { 177 my $text; 178 my $beauty = Irssi::settings_get_bool('leodict_paste_beautify'); 179 my $max = Irssi::settings_get_int('leodict_paste_max_translations'); 180 my $i = 0; 181 foreach (@$trans) { 182 if ($i < $max || $max == 0) { 183 if ($beauty) { 184 $text .= $_->[0]." \n"; 185 $text .= " `-> ".$_->[1]."\n"; 186 } else { 187 $text .= $_->[0].' => '.$_->[1]."\n"; 188 } 189 $i++; 190 } else { 191 $text .= '...'."\n"; 192 last; 193 } 194 } 195 my $msg = $text; 196 $msg = draw_box('LeoDict', $text, $word, 0) if $beauty; 197 $target->command('MSG '.$target->{name}. ' '.$_) foreach (split(/\n/, $msg)); 198 } 199 200} 201 202sub cmd_leodict ($$$) { 203 my ($args, $server, $witem) = @_; 204 my @arg = split(/ /, $args); 205 my $paste = 0; 206 my $browse = 0; 207 if ($arg[0] eq '-p') { 208 $paste = 1; 209 shift(@arg); 210 } elsif ($arg[0] eq '-b') { 211 $browse = 1; 212 shift(@arg); 213 } elsif ($arg[0] eq '-h') { 214 show_help(); 215 return(); 216 } 217 218 foreach (@arg) { 219 if ($paste) { 220 #paste_translations($_, $witem) if $witem; 221 next unless ref $witem; 222 next unless ref $server; 223 translate($_, $witem->{name}, $witem->{server}->{tag}); 224 } elsif ($browse) { 225 call_openurl('http://dict.leo.org/?lang=en&search='.$_); 226 } else { 227 #show_translations($_); 228 translate($_,'', ''); 229 } 230 } 231} 232 233Irssi::command_bind('leodict', 'cmd_leodict'); 234 235Irssi::settings_add_int($IRSSI{'name'}, 'leodict_paste_max_translations', 2); 236Irssi::settings_add_bool($IRSSI{'name'}, 'leodict_paste_beautify', 1); 237 238print CLIENTCRAP "%B>>%n ".$IRSSI{name}." ".$VERSION." loaded: /leodict -h for help"; 239