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

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

use new Cache framework in CustomFeeds? and Subscriptions. Refs #65

  • 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) {
32         $self->add_subscription($subscription, $folder->{BloglinesSubId}, $folder->{title});
33     }
34
35     $self->add_subscription($subscription, 0);
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) {
90         my @feeds = $subscription->feeds_in_folder($folder->{BloglinesSubId});
91         for my $feed (@feeds) {
92             # BloglinesSubId is different from bloglines:siteid. Don't use it
93             $meta->{$feed->{htmlUrl}} = {
94                 folder => $folder->{title},
95                 xmlUrl => $feed->{xmlUrl},
96             };
97         }
98     }
99
100     $meta;
101 }
102
103 sub sync {
104     my($self, $context, $args) = @_;
105
106     my $mark_read = $self->conf->{mark_read};
107        $mark_read = 1 unless defined $mark_read;
108
109     my @updates = $self->{bloglines}->getitems(0, $mark_read);
110     $context->log(info => scalar(@updates) . " feed(s) updated.");
111
112     for my $update (@updates) {
113         my $source = $update->feed;
114
115         my $feed = Plagger::Feed->new;
116         $feed->type('bloglines');
117         $feed->title($source->{title});
118         $feed->link($source->{link});
119         $feed->image($source->{image});
120         $feed->description($source->{description});
121         $feed->language($source->{language});
122         $feed->author($source->{webmaster});
123         $feed->meta->{bloglines_id} = $source->{bloglines}->{siteid};
124
125         # under fetch_pfolders option, set folder as tags to feeds
126         if (my $meta = $self->{bloglines_meta}->{$feed->link}) {
127             $feed->tags([ $meta->{folder} ]);
128             $feed->url($meta->{xmlUrl});
129         }
130
131         $feed->source_xml($update->{_xml});
132
133         for my $item ( $update->items ) {
134             my $entry = Plagger::Entry->new;
135
136             $entry->title($item->{title});
137             $entry->author($item->{dc}->{creator});
138             $entry->tags([ $item->{dc}->{subject} ])
139                 if $item->{dc}->{subject};
140             $entry->date( Plagger::Date->parse('Mail', $item->{pubDate}) );
141             $entry->link($item->{link});
142             $entry->id($item->{guid});
143
144             $entry->body($item->{description});
145
146             $feed->add_entry($entry);
147         }
148
149         $context->update->add($feed);
150     }
151 }
152
153 1;
154
155 __END__
156
157 =head1 NAME
158
159 Plagger::Plugin::Subscription::Bloglines - Bloglines Subscription
160
161 =head1 SYNOPSIS
162
163   - module: Subscription::Bloglines
164     config:
165       username: your-email@account
166       password: your-password
167       mark_read: 1
168
169 =head1 DESCRIPTION
170
171 This plugin allows you to synchronize your subscription using
172 Bloglines Web Services sync API.
173
174 =head1 CONFIGURATION
175
176 =over 4
177
178 =item username, password
179
180 Your username & password to use with Bloglines API.
181
182 =item mark_read
183
184 C<mark_read> specifies whether this plugin I<marks as read> the items
185 you synchronize. With this option set to 0, you will get the
186 duplicated updates everytime you run Plagger, until you mark them
187 unread using Bloglines browser interface. Defaults to 1.
188
189 For people who uses Bloglines browser interface regularly, and use
190 Plagger as a tool to synchronize feed updates to mobile devices (like
191 PSP or iPod), I'd recommend set this option to 0.
192
193 Otherwise, especially for Publish::Gmail plugin users, I recommend set
194 to 1, the default.
195
196 =item fetch_meta
197
198 C<fetch_meta> specifies whether this plugin fetches I<folder>
199 strucuture using listsubs API. With this option on, all feeds under
200 I<Plagger> folder will have I<Plagger> as its tag.
201
202 You can use this tags information using Rules in later phase.
203
204 =back
205
206 =head1 AUTHOR
207
208 Tatsuhiko Miyagawa
209
210 =head1 SEE ALSO
211
212 L<Plagger>, L<WebService::Bloglines>, L<http://www.bloglines.com/>
213
214 =cut
215
Note: See TracBrowser for help on using the browser.