File Coverage

blib/lib/Lingua/Translate/Google.pm
Criterion Covered Total %
statement 92 98 93.8
branch 31 54 57.4
condition 17 48 35.4
subroutine 13 13 100.0
pod 4 4 100.0
total 157 217 72.3


line stmt bran cond sub pod time code
1             package Lingua::Translate::Google;
2              
3             our $VERSION = '0.22';
4              
5 1     1   768 use strict;
  1         2  
  1         34  
6 1     1   6 use warnings;
  1         2  
  1         30  
7             {
8 1     1   5 use Carp;
  1         9  
  1         65  
9 1     1   6 use Readonly;
  1         2  
  1         41  
10 1     1   6 use WWW::Google::Translate;
  1         2  
  1         102  
11             }
12              
13             my ($DEFAULT_AGENT);
14             {
15             Readonly $DEFAULT_AGENT => __PACKAGE__ . "/v$VERSION";
16             }
17              
18             # hack to allow 'auto' as a valid lang tag
19             BEGIN {
20              
21 1     1   1034 require I18N::LangTags;
22              
23 1         9294 my $is_rc = \&I18N::LangTags::is_language_tag;
24              
25 1     1   5 no warnings 'redefine';
  1         2  
  1         85  
26              
27             *I18N::LangTags::is_language_tag = sub {
28 7     7   11 my ($tag) = @_;
29 7 50       14 return 1
30             if $tag eq 'auto';
31 7         18 return $is_rc->($tag);
32 1         1310 };
33             }
34              
35             {
36             my %self = (
37             src => 'auto',
38             dest => 'en',
39             api_key => 0,
40             agent => $DEFAULT_AGENT,
41             );
42              
43             sub _true_self {
44 5     5   15 my ($param_rh) = @_;
45              
46 5 100       14 if ($param_rh) {
47              
48 1         2 for my $key ( keys %{$param_rh} ) {
  1         4  
49              
50 5         10 $self{$key} = $param_rh->{$key};
51             }
52             }
53              
54 5         9 return \%self;
55             }
56             }
57              
58             sub new {
59 1     1 1 450 my ( $class, %config ) = @_;
60              
61 1         4 my $self = _true_self();
62              
63 1   33     8 my $default_source
64             = $config{src}
65             || $config{default_source}
66             || $self->{src};
67              
68 1   33     5 my $default_target
69             = $config{dest}
70             || $config{default_target}
71             || $self->{dest};
72              
73 1   33     5 my $key
74             = $config{api_key}
75             || $config{key}
76             || $self->{api_key};
77              
78 1   33     11 my $agent = $config{agent}
79             || $self->{agent};
80              
81 1 50       4 croak "key parameter must be your Google API key"
82             if !$key;
83              
84 1         4 my %param = (
85             key => $key,
86             default_target => $default_target,
87             default_source => $default_source,
88             agent => $agent,
89             );
90 1         9 $self = _true_self(
91             { wgt => WWW::Google::Translate->new( \%param ),
92             src => $default_source,
93             dest => $default_target,
94             api_key => $key,
95             agent => $agent,
96             }
97             );
98              
99 1         7 return bless $self, $class;
100             }
101              
102             sub config {
103 1     1 1 447 my ( $self, %param );
104              
105 1 50       4 if ( @_ % 2 == 0 ) {
106              
107 0         0 (%param) = @_;
108              
109 0         0 $self = _true_self();
110             }
111             else {
112              
113 1         4 ( $self, %param ) = @_;
114             }
115              
116 1         3 for my $p ( keys %param ) {
117              
118 2 50       6 if ( exists $self->{$p} ) {
119              
120 2   33     6 $self->{$p} ||= $param{$p};
121             }
122             else {
123              
124 0         0 carp "$p is not a supported parameter";
125             }
126             }
127              
128 1   33     7 my $src = $param{src} || $param{source} || $param{default_source};
129 1   33     7 my $dest = $param{dest} || $param{target} || $param{default_target};
130              
131 1 50       3 if ($src) {
132              
133 1 50       3 croak "$src is not a valid language tag"
134             if !I18N::LangTags::is_language_tag($src);
135              
136 1         11 $self->{src} = $src;
137             }
138              
139 1 50       11 if ($dest) {
140              
141 1 50       5 croak "$dest is not a valid language tag"
142             if !I18N::LangTags::is_language_tag($dest);
143              
144 1         11 $self->{dest} = $dest;
145             }
146              
147 1         3 return;
148             }
149              
150             sub translate {
151 3     3 1 669 my ( $self, $text ) = @_;
152              
153 3 50       13 UNIVERSAL::isa( $self, __PACKAGE__ )
154             or croak __PACKAGE__ . '::translate() called as function';
155              
156 3         7 my $true_self = _true_self();
157              
158 3 50       12 croak "no dest language specified\n"
159             if !defined $self->{dest};
160              
161 3 50       8 croak "$self->{dest} is not available on Google translate"
162             if !$self->available( $self->{dest} );
163              
164 3 100       18 if ( $self->{src} ne 'auto' ) {
165              
166 2 50       5 croak "$self->{src} is not available on Google translate"
167             if !$self->available( $self->{src} );
168             }
169              
170 3 100       11 if ( $self->{src} eq 'auto' ) {
171              
172 1         6 my $r = $self->{wgt}->detect( { q => $text } );
173              
174 1 50 33     22 if ( defined $r->{data}
      33        
175             && defined $r->{data}->{detections}
176             && defined $r->{data}->{detections}->[0] )
177             {
178 1         22 my $detect_rh = $r->{data}->{detections}->[0]->[0];
179              
180 1 50       5 if ( defined $detect_rh->{language} ) {
181              
182 1         2 $self->{src} = $detect_rh->{language};
183             }
184             }
185              
186 1 50       13 croak "failed to detect language"
187             if $self->{src} eq 'auto';
188             }
189              
190 3         13 my %q = (
191             source => $self->{src},
192             target => $self->{dest},
193             q => $text,
194             );
195 3         11 my $r = $self->{wgt}->translate( \%q );
196              
197 3         33 my $result;
198              
199 3 50 33     34 if ( defined $r->{data}
      33        
200             && defined $r->{data}->{translations}
201             && defined $r->{data}->{translations}->[0] )
202             {
203 3         6 my $trans_rh = $r->{data}->{translations}->[0];
204              
205 3         5 $result = $trans_rh->{translatedText};
206             }
207             else {
208              
209 0         0 croak 'translation failed';
210             }
211              
212 3 100       7 if (wantarray) {
213              
214             return (
215 1         11 src => $self->{src},
216             dest => $self->{dest},
217             q => $text,
218             result => $result,
219             );
220             }
221              
222 2         11 return $result;
223             }
224              
225             # Returns the available language translation pairs.
226             sub available {
227 5     5 1 12 my ( $self, $lang_inquiry, $lang_target ) = @_;
228              
229 5 50       15 UNIVERSAL::isa( $self, __PACKAGE__ )
230             or croak __PACKAGE__ . '::available() called as function';
231              
232 5 50       10 if ($lang_inquiry) {
233              
234 5         26 require I18N::LangTags;
235              
236 5 50       11 croak "$lang_inquiry is not a valid language code"
237             if !I18N::LangTags::is_language_tag($lang_inquiry);
238             }
239              
240 5   33     75 $lang_target ||= $self->{dest};
241              
242 5 50 33     26 croak "you must specify the target language as the second argument",
243             "or the default_target in the constructor"
244             if $lang_inquiry && $lang_target eq 'auto';
245              
246 5         22 my $r = $self->{wgt}->languages( { target => $lang_target } );
247              
248 5         51 my @langs;
249              
250 5 50 33     39 if ( defined $r->{data}
      33        
251             && defined $r->{data}->{languages}
252             && defined $r->{data}->{languages}->[0] )
253             {
254              
255 5         6 for my $lang_rh ( @{ $r->{data}->{languages} } ) {
  5         12  
256              
257 9         15 push @langs, $lang_rh->{language};
258              
259 9 100 66     60 return 1
260             if $lang_inquiry && $lang_rh->{language} eq lc $lang_inquiry;
261             }
262             }
263              
264             return @langs
265 0 0         if wantarray;
266              
267 0           return \@langs;
268             }
269              
270             1;