root/trunk/plagger/lib/Plagger/Plugin/Filter/Babelfish.pm

Revision 1741 (checked in by miyagawa, 14 years ago)

merge from hackathon-summary

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
Line 
1 package Plagger::Plugin::Filter::Babelfish;
2 use strict;
3 use base qw( Plagger::Plugin );
4
5 use Plagger::UserAgent;
6 use WWW::Babelfish;
7 use Digest::MD5 qw(md5_hex);
8 use Encode qw(encode_utf8);
9
10 use Locale::Language;
11
12 sub register {
13     my($self, $context) = @_;
14
15     $context->autoload_plugin({ module => 'Filter::GuessLanguage' });
16     $context->register_hook(
17         $self,
18         'plugin.init'        => \&connect_to_babelfish,
19         'update.entry.fixup' => \&update,
20     );
21 }
22
23 sub rule_hook { 'update.entry.fixup' }
24
25 sub connect_to_babelfish {
26     my($self, $context, $args) = @_;
27
28     my $service = $self->conf->{service} || 'Babelfish';
29
30     $context->log(debug => "hello, $service");
31
32     my $ua = Plagger::UserAgent->new;
33     $self->{babelfish}->{translator} = new WWW::Babelfish(
34         service => $service,
35         agent => $ua->agent
36     );
37     unless (defined $self->{babelfish}->{translator}) {
38         $context->log(error => "$service is not available");
39         return;
40     }
41 }
42
43 sub update {
44     my($self, $context, $args) = @_;
45
46     my $translator = $self->{babelfish}->{translator} or return;
47     my $language   = $self->conf->{source} || code2language(
48         $args->{entry}->{language} || $args->{feed}->language
49     ) or do {
50         $context->log(warn => "can't identify language");
51         return;
52     };
53
54     my $title    = $args->{entry}->title;
55     my $title_tr = $self->translate($translator, $title, $language);
56     unless (defined $title_tr) {
57         $context->log(error => "Translation failed: " . $translator->error);
58         return;
59     }
60     $title_tr = $title . "\n\n" . $title_tr if $self->conf->{prepend_original};
61
62     $args->{entry}->title($title_tr);
63
64     sleep 1;
65
66     my $body    = $args->{entry}->body;
67     my $body_tr = $self->translate($translator, $body, $language);
68     unless (defined $body_tr) {
69         $context->log(error => "Translation failed: " . $translator->error);
70         return;
71     }
72     if ($self->conf->{prepend_original}) {
73         $body_tr = $body . "\n\n" . $body_tr;
74         $context->log(debug => "prepended original body");
75     }
76
77     $args->{entry}->body($body_tr);
78 }
79
80 sub translate {
81     my ($self, $translator, $text, $language) = @_;
82
83     my $destination = $self->conf->{destination} or do {
84       Plagger->context->log(error => "set destination language");
85       return;
86     };
87
88     unless ($translator->languagepairs->{$language}->{$destination}) {
89       Plagger->context->log(
90           error => "unsupported combination: $language to $destination"
91       );
92       return;
93     }
94
95     my $key = md5_hex(encode_utf8($text));
96
97     return $self->cache->get_callback(
98         "babelfish-$key-$destination",
99         sub {
100             $translator->translate(
101                 source      => $language,
102                 destination => $destination,
103                 text => $text,
104                 delimiter => "\n\n",
105             );
106         },
107         '3 days'
108     );
109 }
110
111 1;
112
113 __END__
114
115 =head1 NAME
116
117 Plagger::Plugin::Filter::Babelfish - translate via WWW::Babelfish
118
119 =head1 SYNOPSIS
120
121   - module: Filter::Babelfish
122     config:
123       source: English
124       destination: Japanese
125       service: Google
126       prepend_original: 1
127
128 =head1 DESCRIPTION
129
130 This plugin translates each entry body via Babelfish.
131 See L<WWW::Babelfish> for details.
132
133 =head1 CONFIG
134
135 =over 4
136
137 =item service
138
139 Which translator to use ('Babelfish' or 'Google').
140 Defaults to 'Babelfish'.
141
142 =item source (optional)
143
144 Which language the feeds/entries are. Will be guessed if you don't specify.
145
146 =item destination
147
148 Which language the feeds/entries should be translated to.
149
150 =item prepend_original
151
152 When set to 1, prepends original entry body. Defaults to 0.
153
154 =back
155
156 =head1 AUTHOR
157
158 Kenichi Ishigaki
159
160 =head1 SEE ALSO
161
162 L<Plagger>, L<WWW::Babelfish>
163
164 =cut
Note: See TracBrowser for help on using the browser.