root/trunk/plagger/lib/Plagger/Plugin/Subscription/LivedoorReader.pm

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

diet unused modules

Line 
1 package Plagger::Plugin::Subscription::LivedoorReader;
2 use strict;
3 use base qw( Plagger::Plugin );
4
5 use JSON::Syck;
6 use URI;
7 use WWW::Mechanize;
8 use Plagger::Util;
9
10 sub plugin_id {
11     my $self = shift;
12     $self->class_id . '-' . $self->conf->{username};
13 }
14
15 sub register {
16     my($self, $context) = @_;
17
18     $self->init_reader;
19     $context->register_hook(
20         $self,
21         'subscription.load' => \&notifier,
22     );
23 }
24
25 sub init_reader {
26     my $self = shift;
27     $self->{mech} = WWW::Mechanize->new(cookie_jar => $self->cache->cookie_jar);
28
29     unless (defined($self->conf->{username}) && defined($self->conf->{password})) {
30         Plagger->context->error("username and/or password is missing");
31     }
32 }
33
34 sub notifier {
35     my($self, $context) = @_;
36
37     $self->{mech}->get("http://rpc.reader.livedoor.com/notify?user=" . $self->conf->{username});
38     my $content = $self->{mech}->content;
39
40     # copied from WebService/Bloglines.pm
41
42     # |A|B| where A is the number of unread items
43     $content =~ /\|([\-\d]+)|(.*)|/
44         or $context->error("Bad Response: $content");
45
46     my($unread, $url) = ($1, $2);
47
48     # A is -1 if the user email address is wrong.
49     if ($unread == -1) {
50         $context->error("Bad username: " . $self->conf->{username});
51     }
52
53     return unless $unread;
54
55     $context->log(info => "You have $unread unread item(s) on livedoor Reader.");
56
57     my $feed = Plagger::Feed->new;
58     $feed->aggregator(sub { $self->sync(@_) });
59     $context->subscription->add($feed);
60 }
61
62 sub sync {
63     my($self, $context, $args) = @_;
64
65     my $mark_read = $self->conf->{mark_read};
66        $mark_read = 1 unless defined $mark_read;
67
68     $self->login_reader();
69
70     my $subs = $self->_request("/api/subs", { unread => 1 });
71
72     for my $sub (@$subs) {
73         $context->log(debug => "get unread items of $sub->{subscribe_id}");
74         my $data = $self->_request("/api/unread", { subscribe_id => $sub->{subscribe_id} });
75         $self->_request("/api/touch_all", { subscribe_id => $sub->{subscribe_id} })
76             if $mark_read;
77
78         my $feed = Plagger::Feed->new;
79         $feed->type('livedoorReader');
80         $feed->title( Plagger::Util::strip_html($data->{channel}->{title}) );
81         $feed->link($data->{channel}->{link});
82         $feed->url($data->{channel}->{feedlink});
83         $feed->image({ url => $data->{channel}->{image} || $sub->{icon} });
84         $feed->meta->{livedoor_reader_id} = $sub->{subscribe_id};
85         $feed->meta->{rate} = $sub->{rate};
86         $feed->add_tag($_) for @{$sub->{tags}};
87         $feed->add_tag($sub->{folder}) if $sub->{folder};
88         $feed->updated( Plagger::Date->from_epoch($sub->{modified_on}) ) if $sub->{modified_on};
89         $feed->description($data->{channel}->{description});
90         $feed->meta->{livedoor_reader_subscribers_count} = $data->{channel}->{subscribers_count};
91
92         for my $item ( @{$data->{items}} ) {
93             my $entry = Plagger::Entry->new;
94             $entry->title($item->{title});
95             $entry->author($item->{author}) if $item->{author};
96             $entry->link($item->{link});
97             # TODO support enclosure
98             $entry->tags([ $item->{category} ]) if $item->{category};
99             $entry->date( Plagger::Date->from_epoch($item->{modified_on}) ); # xxx created_on as well
100             $entry->meta->{livedoor_reader_item_id} = $item->{id};
101             $entry->feed_link($feed->link);
102             $entry->body($item->{body});
103
104             $feed->add_entry($entry);
105         }
106
107         $context->update->add($feed);
108     }
109 }
110
111 sub login_reader {
112     my $self = shift;
113
114     local $^W; # input type="search" warning
115     $self->{mech}->get("http://reader.livedoor.com/reader/");
116
117     if ($self->{mech}->content =~ /name="loginForm"/) {
118         Plagger->context->log(debug => "Logging in to Livedoor Reader");
119         $self->{mech}->submit_form(
120             form_name => 'loginForm',
121             fields => {
122                 livedoor_id => $self->conf->{username},
123                 password    => $self->conf->{password},
124             },
125         );
126
127         if ( $self->{mech}->content =~ /class="headcopy"/ ) {
128             Plagger->context->error("Failed to login using username & password");
129         }
130     }
131
132     $self->{mech}->cookie_jar->scan(
133         sub {
134             my($key, $val) = @_[1,2];
135             if ($key =~ /_sid/) {
136                 $self->{apikey} = $val;
137                 return;
138             }
139         },
140     );
141 }
142
143 sub _request {
144     my($self, $method, $param) = @_;
145
146     my $uri = URI->new_abs($method, "http://reader.livedoor.com/");
147     $uri->query_form(%$param, ApiKey => $self->{apikey});
148
149     $self->{mech}->get($uri->as_string);
150
151     return JSON::Syck::Load($self->{mech}->content);
152 }
153
154 1;
155
156 __END__
157
158 =head1 NAME
159
160 Plagger::Plugin::Subscription::LivedoorReader - Synchronize livedoor Reader with JSON API
161
162 =head1 SYNOPSIS
163
164   - module: Subscription::LivedoorReader
165     config:
166       username: your-livedoor-id
167       password: your-password
168       mark_read: 1
169
170 =head1 DESCRIPTION
171
172 This plugin allows you to synchronize your subscription using Livedoor
173 Reader JSON API.
174
175 =head1 CONFIGURATION
176
177 =over 4
178
179 =item username, password
180
181 Your username & password to use with livedoor Reader.
182
183 =item mark_read
184
185 C<mark_read> specifies whether this plugin I<marks as read> the items
186 you synchronize. With this option set to 0, you will get the
187 duplicated updates everytime you run Plagger, until you mark them
188 unread using Livedoor Reader web interface.
189
190 =back
191
192 =head1 AUTHOR
193
194 Tatsuhiko Miyagawa
195
196 =head1 SEE ALSO
197
198 L<Plagger>, L<Plagger::Plugin::Subscription::Bloglines>, L<http://reader.livedoor.com/>
199
200 =cut
201
Note: See TracBrowser for help on using the browser.