File Coverage

blib/lib/Bot/Babelfish.pm
Criterion Covered Total %
statement 4 6 66.6
branch n/a
condition n/a
subroutine 2 2 100.0
pod n/a
total 6 8 75.0


line stmt bran cond sub pod time code
1             package Bot::Babelfish;
2 2     2   46303 use strict;
  2         7  
  2         76  
3 2     2   2119 use Bot::BasicBot;
  0            
  0            
4             use Carp;
5             use Encode;
6             use I18N::LangTags qw(extract_language_tags is_language_tag);
7             use I18N::LangTags::List;
8             use Lingua::Translate;
9             use Text::Unidecode;
10              
11             { no strict;
12             $VERSION = '0.04';
13             @ISA = qw(Bot::BasicBot);
14             }
15              
16             =head1 NAME
17              
18             Bot::Babelfish - Provides Babelfish translation services via an IRC bot
19              
20             =head1 VERSION
21              
22             Version 0.04
23              
24             =head1 SYNOPSIS
25              
26             use Bot::Babelfish;
27              
28             my $bot = Bot::Babel->new(
29             nick => 'babel', name => 'Babelfish bot',
30             server => 'irc.perl.org', channels => [ '#mychannel' ]
31             )->run
32              
33             =head1 DESCRIPTION
34              
35             This module provides the backend for an IRC bot which can be used as an
36             interface for translation services using Babelfish.
37              
38             =head1 METHODS
39              
40             =over 4
41              
42             =item init()
43              
44             Initializes private data.
45              
46             =cut
47              
48             sub init {
49             my $self = shift;
50            
51             $self->{babel} = {
52             cache => {},
53             };
54              
55             return 1
56             }
57              
58             =item said()
59              
60             Main function for interacting with the bot object.
61             It follows the C API and expect an hashref as argument.
62             See L<"COMMANDS"> for more information on recognized commands.
63              
64             =cut
65              
66             sub said {
67             my $self = shift;
68             my $args = shift;
69              
70             # don't do anything unless directly addressed
71             return undef unless $args->{address} eq $self->nick or $args->{channel} eq 'msg';
72             return if $self->ignore_nick($args->{who});
73              
74             # ignore karma
75             return if index($args->{body}, '++') == 0;
76             return if index($args->{body}, '--') == 0;
77              
78             if($args->{body} =~ /^ *version/) {
79             $args->{body} = sprintf "%s IRC bot, using %s", $self->nick,
80             join ', ', map { $_ . ' ' . $_->VERSION } qw(
81             Bot::BasicBot Bot::Babelfish Encode Lingua::Translate
82             POE POE::Component::IRC
83             );
84             $self->say($args);
85             return undef;
86             }
87              
88             #print STDERR $/, $args->{body}, $/;
89             my ($from, $to) = extract_language_tags($args->{body} );
90             $from ||= 'en';
91             $to ||= 'fr';
92             #print STDERR " $from -> $to : ", $args->{body}, $/;
93              
94             unless(is_language_tag($from)) {
95             $args->{body} = "Unrecognized language tag '$from'";
96             $self->say($args);
97             return undef
98             }
99              
100             unless(is_language_tag($to)) {
101             $args->{body} = "Unrecognized language tag '$to'";
102             $self->say($args);
103             return undef
104             }
105              
106             my $from_to = "$from>$to";
107             my($from_lang,$to_lang) = map { I18N::LangTags::List::name($_) } $from, $to;
108              
109             my $translator = new Lingua::Translate src => $from, dest => $to;
110             unless(defined $translator) {
111             $args->{body} = "Can't translate from $from_lang to $to_lang";
112             $self->say($args);
113             return undef
114             }
115              
116             my $text = encode('utf-8', decode('iso-8859-1', $args->{body}));
117             my $result = $self->{babel}{cache}{$from_to}{$text};
118              
119             unless($result) {
120             eval { $result = decode('utf-8', $translator->translate($text)) };
121             $self->{babel}{cache}{$from_to}{$text} = $result unless $@;
122             }
123             #print STDERR " ($@) result = $result\n";
124              
125             $text = non_unicode_version(decode('utf-8', $text));
126             $result = non_unicode_version($result);
127              
128             $args->{body} = defined($result) ? qq|$to_lang for "$text" => "$result"| : "error: $@";
129             $self->say($args);
130            
131             return $args
132             }
133              
134             =item help()
135              
136             Prints usage.
137              
138             =cut
139              
140             sub help {
141             return "usage: babel: from to: text to translate\n".
142             " where 'from' and 'to' are two-letters codes of source and destination languages\n".
143             " see http://babelfish.altavista.com/ for the list of supported languages.\n".
144             " example: babel: fr en: ceci n'est pas une pipe"
145             }
146              
147             =item non_unicode_version()
148              
149             This function returns a printable version of the given string
150             (with a European value of "printable" C<:-)>. More precisely,
151             if the string only contains Latin-1 characters, it is returned
152             decoded from internal Perl format. If the string contains
153             others characters outside Latin-1, it's converted using
154             C.
155              
156             =cut
157              
158             sub non_unicode_version {
159             my $text = shift;
160             my $wide = 0;
161             ord($_) > 255 and $wide++ for split //, $text;
162             return $wide ? unidecode($text) : encode('iso-8859-1', $text)
163             }
164              
165             =back
166              
167              
168             =head1 COMMANDS
169              
170             =over 4
171              
172             =item translation
173              
174             babel from to: some text to translate
175              
176             Where C and C are ISO-639 two-letters codes representing the languages.
177             See L for the list of supported languages.
178              
179             B
180              
181             babel: fr en: ceci n'est pas une pipe
182             English for "ceci n'est pas une pipe" => "this is not a pipe"
183              
184             =item help
185              
186             babel help
187              
188             Shows how to use this bot.
189              
190             =item version
191              
192             babel version
193              
194             Prints the version of this module and its dependencies.
195              
196             =back
197              
198             =head1 DIAGNOSTICS
199              
200             =over 4
201              
202             =item Can't create new %s object
203              
204             B<(F)> Occurs in C. As the message says, we were unable to create
205             a new object of the given class.
206              
207             =back
208              
209             =head1 SEE ALSO
210              
211             L, L
212              
213             =head1 AUTHOR
214              
215             SEbastien Aperghis-Tramoni, Esebastien@aperghis.netE
216              
217             =head1 BUGS
218              
219             Please report any bugs or feature requests to
220             C, or through the web interface at
221             L.
222             I will be notified, and then you'll automatically be notified
223             of progress on your bug as I make changes.
224              
225             =head1 COPYRIGHT & LICENSE
226              
227             Copyright 2005 SEbastien Aperghis-Tramoni, All Rights Reserved.
228              
229             This program is free software; you can redistribute it and/or modify it
230             under the same terms as Perl itself.
231              
232             =cut
233              
234             1; # End of Bot::Babelfish