/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 ' ');
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