Plagger::Plugin::CustomFeed::Delicious

Livedoor Clip に del.icio.us のブックマークを移行するために del.icio.us の全ブックマークを取得するPlaggerプラグインを作ってみた。
いや、このへんのとか使えばいいんだけど、まぁ Plagger でやってみたかったということで。ちなみに本来は Perl な人ではないので、へんなところがあればだれかツッコミよろ。

package Plagger::Plugin::CustomFeed::Delicious;

use strict;
use warnings;

use base qw( Plagger::Plugin );

use Plagger::UserAgent;
use Plagger::Feed;
use Plagger::Entry;
use Plagger::Tag;

use DateTime::Format::W3CDTF;
use XML::Liberal;
use HTTP::Request;

sub plugin_id {
    my $self = shift;
    $self->class_id . '-' . $self->conf->{username};
}

sub register {
    my ($self, $context) = @_;
    $context->register_hook(
        $self,
        'subscription.load' => \&load,
    );
}

sub load {
    my($self, $context) = @_;

    my $feed = Plagger::Feed->new;
    $feed->aggregator( sub { $self->aggregate(@_); });
    $context->subscription->add($feed);
}

sub aggregate {
    my($self, $context, $args) = @_;

    my $username = $self->conf->{username};
    my $password = $self->conf->{password};

    my $url = "https://api.del.icio.us/v1/posts/all";
    my $agent = Plagger::UserAgent->new;
    my $request = HTTP::Request->new(GET => $url);
    $request->authorization_basic($username, $password);
    my $response = $agent->request($request);

    if ($response->is_error) {
        $context->log(error => "GET $url failed: " .
                          $response->http_status . " " .
                          $response->http_response->message);
        return;
    }

    my $parser = XML::Liberal->new('LibXML');
    my $doc = $parser->parse_string($response->content);

    my $updated = DateTime::Format::W3CDTF->parse_datetime(
        $doc->documentElement->getAttribute('update'));

    my $feed = Plagger::Feed->new;
    $feed->updated($updated);

    for my $element ($doc->getElementsByTagName('post')) {
        $feed->add_entry($self->_create_entry($element, $doc));
    }

    $context->update->add($feed);
}

sub _create_entry {
    my($self, $element, $doc) = @_;
    my $author = $doc->documentElement->getAttribute('user');
    my @tags;

    @tags = Plagger::Tag->parse($element->getAttribute('tag'))
        if $element->getAttribute('tag') ne 'system:unfiled';

    my $date = DateTime::Format::W3CDTF->parse_datetime(
        $element->getAttribute('time'));

    my $entry = Plagger::Entry->new;
    $entry->link($element->getAttribute('href'));
    $entry->title($element->getAttribute('description'));
    $entry->body($element->getAttribute('extended'))
        if $element->getAttribute('extended');
    $entry->author($author);
    $entry->tags(\@tags);
    $entry->date($date);

    return $entry;
}

1;

これで、config.yaml

plugins:
  - module: CustomFeed::Delicious
    config:
      username: oda
      password: foo

  - module: Publish::LivedoorClip
    config:
      livedoor_id: odz
      password: bar
      interval: 2
      post_body: 1

とか書いてPlaggerを実行すれば del.icio.us から Livedoor Clip に移行できるはず。