package Plagger::Plugin::Subscription::Fastladder; use strict; use base qw( Plagger::Plugin ); use JSON::Syck; use URI; use Plagger::Mechanize; use Plagger::Util; sub plugin_id { my $self = shift; $self->class_id . '-' . $self->conf->{username}; } sub register { my($self, $context) = @_; $self->init_reader; $context->register_hook( $self, 'subscription.load' => \¬ifier, ); } sub init_reader { my $self = shift; $self->{mech} = Plagger::Mechanize->new(cookie_jar => $self->cookie_jar); unless (defined($self->conf->{url})) { Plagger->context->error("url is missing"); } unless (defined($self->conf->{username}) && defined($self->conf->{password})) { Plagger->context->error("username and/or password is missing"); } } sub notifier { my($self, $context) = @_; my $content; my $feed = Plagger::Feed->new; $feed->aggregator(sub { $self->sync(@_) }); $context->subscription->add($feed); } sub sync { my($self, $context, $args) = @_; my $mark_read = $self->conf->{mark_read}; $mark_read = 1 unless defined $mark_read; $self->login_reader(); my $subs = $self->_request("/api/subs", { unread => 1 }) || []; for my $sub (@$subs) { $context->log(debug => "get unread items of $sub->{subscribe_id}"); my $data = $self->_request("/api/unread", { subscribe_id => $sub->{subscribe_id} }) or next; my $feed = Plagger::Feed->new; $feed->type('livedoorReader'); $feed->title($data->{channel}->{title}); $feed->link($data->{channel}->{link}); $feed->url($data->{channel}->{feedlink}); $feed->image({ url => $data->{channel}->{image} || $sub->{icon} }); $feed->meta->{livedoor_reader_id} = $sub->{subscribe_id}; $feed->meta->{rate} = $sub->{rate}; $feed->add_tag($_) for @{$sub->{tags}}; $feed->add_tag($sub->{folder}) if $sub->{folder}; $feed->updated( Plagger::Date->from_epoch($sub->{modified_on}) ) if $sub->{modified_on}; $feed->description($data->{channel}->{description}); $feed->meta->{livedoor_reader_subscribers_count} = $data->{channel}->{subscribers_count}; for my $item ( @{$data->{items}} ) { my $entry = Plagger::Entry->new; $entry->title($item->{title}); $entry->author($item->{author}) if $item->{author}; $entry->link($item->{link}); # TODO support enclosure $entry->tags([ $item->{category} ]) if $item->{category}; $entry->date( Plagger::Date->from_epoch($item->{modified_on}) ) if $item->{modified_on}; $entry->meta->{livedoor_reader_item_id} = $item->{id}; $entry->feed_link($feed->link); $entry->body($item->{body}); $feed->add_entry($entry); } $self->_request("/api/touch_all", { subscribe_id => $sub->{subscribe_id} }) if $mark_read; $context->update->add($feed); } } sub login_reader { my $self = shift; local $^W; # input type="search" warning my $uri = URI->new_abs("/reader/", $self->conf->{url}); $self->{mech}->get($uri); if ($self->{mech}->content =~ m!

Sign in

!) { Plagger->context->log(debug => "Logging in to Livedoor Reader"); $self->{mech}->submit_form( fields => { username => $self->conf->{username}, password => $self->conf->{password}, }, ); if ( $self->{mech}->content =~ /Cannot sign in/ ) { Plagger->context->error("Failed to login using username & password"); } } $self->{mech}->cookie_jar->scan( sub { my($key, $val) = @_[1,2]; if ($key =~ /_fastladder_session/) { $self->{apikey} = $val; return; } }, ); } sub _request { my($self, $method, $param) = @_; my $uri = URI->new_abs($method, $self->conf->{url}); $self->{mech}->post($uri, { %$param, ApiKey => $self->{apikey} }); if ($self->{mech}->status == 200) { return JSON::Syck::Load($self->{mech}->content); } return; } 1; __END__ =head1 NAME Plagger::Plugin::Subscription::LivedoorReader - Synchronize livedoor Reader with JSON API =head1 SYNOPSIS - module: Subscription::LivedoorReader config: username: your-livedoor-id password: your-password mark_read: 1 =head1 DESCRIPTION This plugin allows you to synchronize your subscription using Livedoor Reader JSON API. =head1 CONFIGURATION =over 4 =item username, password Your username & password to use with livedoor Reader. Note that you don't have to supply username and password if you set global cookie_jar in your configuration file and the cookie_jar contains a valid login session there, such as: global: user_agent: cookies: /path/to/cookies.txt See L for details. =item mark_read C specifies whether this plugin I the items you synchronize. With this option set to 0, you will get the duplicated updates every time you run Plagger, until you mark them unread using Livedoor Reader web interface. =back =head1 AUTHOR Tatsuhiko Miyagawa =head1 SEE ALSO L, L, L =cut