del.icio.usからlivedoor Clipにデータを移行するためのモジュール
うそ、パクりました。にぽたん研究所から。
先に使い方から説明すると、まず「http://api.del.icio.us/v1/posts/all?」ここにアクセスすると、自分が今までにdel.icio.usへポストしたブックマークをすべて取得できるので、それを取得しておきます。ベーシック認証がありますが、それは自分のdel.icio.usのアカウントを入力してください。
次に下記のスクリプトを用意して、先程del.icio.usから取得したブックマークのデータ(all.xmlというファイル名にしておいてください)と同じディレクトリに置いたら、あとはスクリプトを実行するだけです。もちろんあとで紹介するWWW::SyncSBS::D2Lも用意する必要があります。
#!/usr/local/bin/perl
use strict;
use WWW::SyncSBS::D2L;
my $d2l = WWW::SyncSBS::D2L->new;
$d2l->livedoor_id('your_ld_id');
$d2l->livedoor_pw('your_ld_pw');
$d2l->sync;
WWW::SyncSBS::D2Lの本体は↓です。
package WWW::SyncSBS::D2L;
use strict;
use Carp;
use HTML::Entities ();
use WWW::Mechanize;
use URI;
use XML::Simple;
use base qw(Class::Accessor::Fast);
use Encode;
__PACKAGE__->mk_accessors(qw(mech livedoor_id livedoor_pw debug));
sub new {
my($class, $args) = @_;
my $self = bless {
debug => 0,
}, $class;
if ($args && ref($args) eq 'HASH') {
for my $method (keys %$args) {
if ($class->can($method)) {
$class->$method($args->{$method});
}
}
}
return $self->_init;
}
sub sync {
my $self = shift;
$self->login_livedoor_clip unless $self->{_logged_in};
my $posted = $self->parse_delicious_bookmark;
$self->clip_to_livedoor($posted);
}
sub login_livedoor_clip {
my $self = shift;
unless ($self->livedoor_id && $self->livedoor_pw) {
croak('set your livedoor_id and livedoor_pw before login.');
}
unless ($self->_has_clip_account) {
croak('register to livedoor clip before using this module.');
}
my $res = $self->mech->get('http://clip.livedoor.com/register/');
$self->mech->submit_form(
form_name => 'loginForm',
fields => {
livedoor_id => $self->livedoor_id,
password => $self->livedoor_pw,
},
);
# XXX login checking (WWW::Mechanize->uri() doesn't work correct).
$self->mech->get('http://clip.livedoor.com/register/');
$self->{_logged_in} =
$self->mech->uri =~ m{^http://clip\.livedoor\.com/} ? 1 : 0;
unless ($self->{_logged_in}) {
croak("failed to login to livedoor clip.");
}
}
sub _has_clip_account {
my $self = shift;
my $myclip_url =
sprintf('http://clip.livedoor.com/clips/%s', $self->livedoor_id);
my $res = $self->mech->get($myclip_url);
return $res->is_success ? 1 : 0;
}
sub _init {
my $self = shift;
unless ($self->mech) {
my $mech = WWW::Mechanize->new;
$mech->agent_alias('Windows IE 6');
$self->mech($mech);
}
if ($self->livedoor_id && $self->livedoor_pw) {
$self->mech->login_livedoor_clip;
}
return $self;
}
sub parse_delicious_bookmark {
my $self = shift;
my $feed = $self->_get_content();
my @posted = $self->_parse_feed($feed);
return \@posted;
}
# XXX parse using regexp
sub _parse_feed {
my($self, $feed) = @_;
my @posted_data = ();
my $xml = XMLin($feed);
for my $post (@{$xml->{post}}) {
my $title = $post->{description};
my $url = $post->{href};
my $summary = $post->{extended};
my @tags = $post->{tag} eq 'system:unfiled' ? () : split(/ /, encode('utf8', $post->{tag}));
my $data = {
title => encode('utf8', $title) || '',
url => encode('utf8', $url) || '',
summary => encode('utf8', $summary) || '',
tags => \@tags,
};
push @posted_data, $data;
}
return @posted_data;
}
sub get_bookmark_count {
my($self, $feed) = @_;
my $count;
if ($feed =~ m{(\d+)};
unless ($count) {
$count = scalar($feed =~ m{(.+?) }sg);
}
}
return ($count || 0);
}
sub _get_content {
open(FH, "all.xml");
my $f = join('', );
close(FH);
return $f;
}
sub clip_to_livedoor {
my($self, $data) = @_;
for my $posted (@$data) {
my $uri = URI->new('http://clip.livedoor.com/clip/add');
$uri->query_form(
link => $posted->{url},
jump => 'page',
tags => join(' ', @{$posted->{tags}}),
title => $posted->{title},
notes => $posted->{summary},
);
my $add_url = $uri->as_string;
my $res = eval { $self->mech->get($add_url) };
if ($res && $res->is_success) {
eval { $self->mech->submit_form(form_name => 'clip') };
if ($@) {
carp("can't submit: " . $posted->{url});
}
}
else {
carp("fail to clip $add_url HTTP Status: " . $res->code);
}
}
}
1;