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

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

Bloglines: refactored the code

  • Property svn:keywords set to Id Revision
Line 
1 package Plagger::Plugin::Subscription::Bloglines;
2 use strict;
3 use base qw( Plagger::Plugin );
4
5 our $VERSION = '0.10';
6 use WebService::Bloglines;
7
8 sub register {
9     my($self, $context) = @_;
10
11     $self->init_bloglines();
12
13     if ($self->conf->{no_sync_api}) {
14         $context->register_hook(
15             $self,
16             'subscription.load' => \&getsubs,
17         );
18     } else {
19         $context->register_hook(
20             $self,
21             'subscription.load' => \&notifier,
22             'aggregator.aggregate.bloglines' => \&sync,
23         );
24     }
25 }
26
27 sub getsubs {
28     my($self, $context) = @_;
29     my $subscription = $self->{bloglines}->listsubs();
30
31     for my $folder ($subscription->folders, 0) {
32         my $subid = $folder ? $folder->{BloglinesSubId} : 0;
33         my $title = $folder ? $folder->{title} : undef;
34         $self->add_subscription($subscription, $subid, $title);
35     }
36 }
37
38 sub add_subscription {
39     my($self, $subscription, $subid, $title) = @_;
40
41     my @feeds = $subscription->feeds_in_folder($subid);
42     for my $source (@feeds) {
43         my $feed = Plagger::Feed->new;
44         $feed->title($source->{title});
45         $feed->link($source->{htmlUrl});
46         $feed->url($source->{xmlUrl} );
47         $feed->tags([ $title ]) if $title;
48         Plagger->context->subscription->add($feed);
49     }
50 }
51
52 sub init_bloglines {
53     my $self = shift;
54     $self->{bloglines} = WebService::Bloglines->new(
55         username => $self->conf->{username},
56         password => $self->conf->{password},
57     );
58 }
59
60 sub notifier {
61     my($self, $context) = @_;
62
63     my $count = $self->{bloglines}->notify();
64     $context->log(info => "You have $count unread item(s) on Bloglines.");
65     if ($count) {
66         my $feed = Plagger::Feed->new;
67         $feed->type('bloglines');
68         $context->subscription->add($feed);
69
70         if ($self->conf->{fetch_meta}) {
71             $self->{bloglines_meta} = $self->cache->get_callback(
72                 'listsubs_meta',
73                 sub { $self->fetch_meta($context) },
74                 '1 day',
75             );
76         }
77     }
78 }
79
80 sub fetch_meta {
81     my($self, $context) = @_;
82
83     $self->{folders} = {};
84     $context->log(info => "call Bloglines listsubs API to get folder structure");
85
86     my $subscription = $self->{bloglines}->listsubs();
87
88     my $meta;
89     for my $folder ($subscription->folders, 0) {
90         my $subid = ref $folder ? $folder->{BloglinesSubId} : 0;
91         my @feeds = $subscription->feeds_in_folder($subid);
92         for my $feed (@feeds) {
93             # BloglinesSubId is different from bloglines:siteid. Don't use it
94             $meta->{$feed->{htmlUrl}} = {
95                 folder => $folder ? $folder->{title} : undef,
96                 xmlUrl => $feed->{xmlUrl},
97             };
98         }
99     }
100
101     $meta;
102 }
103
104 sub sync {
105     my($self, $context, $args) = @_;
106
107     my $mark_read = $self->conf->{mark_read};
108        $mark_read = 1 unless defined $mark_read;
109
110     my @updates = $self->{bloglines}->getitems(0, $mark_read);
111     $context->log(info => scalar(@updates) . " feed(s) updated.");
112
113     for my $update (@updates) {
114         my $source = $update->feed;
115
116         my $feed = Plagger::Feed->new;
117         $feed->type('bloglines');
118         $feed->title($source->{title});
119         $feed->link($source->{link});
120         $feed->image($source->{image});
121         $feed->description($source->{description});
122         $feed->language($source->{language});
123         $feed->author($source->{webmaster});
124         $feed->meta->{bloglines_id} = $source->{bloglines}->{siteid};
125
126         # under fetch_pfolders option, set folder as tags to feeds
127         if (my $meta = $self->{bloglines_meta}->{$feed->link}) {
128             $feed->tags([ $meta->{folder} ]) if $meta->{folder};
129             $feed->url($meta->{xmlUrl});
130         }
131
132         $feed->source_xml($update->{_xml});
133
134         for my $item ( $update->items ) {
135             my $entry = Plagger::Entry->new;
136
137             $entry->title($item->{title});
138             $entry->author($item->{dc}->{creator});
139             $entry->tags([ $item->{dc}->{subject} ])
140                 if $item->{dc}->{subject};
141             $entry->date( Plagger::Date->parse('Mail', $item->{pubDate}) );
142             $entry->link($item->{link});
143             $entry->id($item->{guid});
144
145             $entry->body($item->{description});
146
147             $feed->add_entry($entry);
148         }
149
150         $context->update->add($feed);
151     }
152 }
153
154 1;
155
156 __END__
157
158 =head1 NAME
159
160 Plagger::Plugin::Subscription::Bloglines - Bloglines Subscription
161
162 =head1 SYNOPSIS
163
164   - module: Subscription::Bloglines
165     config:
166       username: your-email@account
167       password: your-password
168       mark_read: 1
169
170 =head1 DESCRIPTION
171
172 This plugin allows you to synchronize your subscription using
173 Bloglines Web Services sync API.
174
175 =head1 CONFIGURATION
176
177 =over 4
178
179 =item username, password
180
181 Your username & password to use with Bloglines API.
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 Bloglines browser interface. Defaults to 1.
189
190 For people who uses Bloglines browser interface regularly, and use
191 Plagger as a tool to synchronize feed updates to mobile devices (like
192 PSP or iPod), I'd recommend set this option to 0.
193
194 Otherwise, especially for Publish::Gmail plugin users, I recommend set
195 to 1, the default.
196
197 =item fetch_meta
198
199 C<fetch_meta> specifies whether this plugin fetches I<folder>
200 strucuture using listsubs API. With this option on, all feeds under
201 I<Plagger> folder will have I<Plagger> as its tag.
202
203 You can use this tags information using Rules in later phase.
204
205 =back
206
207 =head1 AUTHOR
208
209 Tatsuhiko Miyagawa
210
211 =head1 SEE ALSO
212
213 L<Plagger>, L<WebService::Bloglines>, L<http://www.bloglines.com/>
214
215 =cut
216
Note: See TracBrowser for help on using the browser.