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/&nbsp;//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