たまには Hack。はてなブックマークの自分のブックマークのページは、丁寧にコメントをつけていたりすると、それはそれである種のコンテンツのようなものです。Blog界の出来事みたいに、リンクとコメントで一日のコンテンツが作られているサイトに近い感じですね。
せっかくなので、ブックマークで集めた情報を Movable Type でコンテンツとして publish するなんてことをやってみます。と、言ってもそんなに難しいことはなく、RSSフィードを取得して、本日分のブックマークを XML-RPC で post してやります。
#!/usr/local/bin/perl
use strict;
use warnings;
NDO::HatenaBM2MT->new(
template => './template.html',
rsd => 'http://naoya.dyndns.org/~naoya/mt/rsd.xml',
feedurl => 'http://b.hatena.ne.jp/naoya/rss',
mt_user => 'foo',
mt_passwd => 'bar',
mt_blogid => 3,
)->do;
package NDO::HatenaBM2MT;
use Encode;
use HTML::Template;
use LWP::Simple;
use Net::MovableType;
use Time::Piece;
use XML::RSS;
sub new {
my $class = shift;
bless {@_}, $class;
}
sub do {
my $self = shift;
$self->init;
$self->getfeed;
$self->makelist;
$self->format;
$self->associate;
$self->post;
}
sub init {
my $self = shift;
$self->{tmpl} = HTML::Template->new(
type => 'filename',
source => $self->{template},
die_on_bad_params => 0
);
$self->{mt} = Net::MovableType->new($self->{rsd});
$self->{mt}->username($self->{mt_user});
$self->{mt}->password($self->{mt_passwd});
$self->{mt}->blogId($self->{mt_blogid});
$self->{rss} = XML::RSS->new;
}
sub getfeed {
my $self = shift;
$self->{document} = LWP::Simple::get($self->{feedurl})
or die "cannnot get feed from $self->{feedurl}: $!";
1;
}
sub makelist {
my $self = shift;
$self->{rss}->parse($self->{document});
$self->{list} = [];
my $today = localtime->ymd;
@{$self->{list}} = map {
+{
title => $_->{title} || '',
link => $_->{link} || '',
comment => $_->{description} || '',
subject => $_->{dc}->{subject} || '',
};
} grep $_->{dc}->{date} =~ /^$today/, @{$self->{rss}->{items}};
}
sub format {
my $self = shift;
$self->{list} or return;
for my $item (@{$self->{list}}) {
Encode::_utf8_off($item->{$_})
for qw(title comment subject);
}
}
sub associate {
my $self = shift;
$self->{list} or return;
$self->{tmpl}->param(
bookmarklist => $self->{list},
);
}
sub post {
my $self = shift;
$self->{list} or return;
my $title = $self->{title} || $self->{rss}->{channel}->{title} || '';
Encode::_utf8_off($title);
my $id = $self->{mt}->newPost({
title => $title,
description => $self->{tmpl}->output,
});
$self->{mt}->publishPost($id) if $id;
}
1;
XML-RPC による post は Net::MovableType を使ってます。途中 HTML::Template で Post する内容を整形していて、
<TMPL_IF NAME=BOOKMARKLIST> <dl> <TMPL_LOOP NAME=BOOKMARKLIST> <dt><a href="http://b.hatena.ne.jp/entry/<TMPL_VAR NAME=LINK>"> <img src="http://b.hatena.ne.jp/images/entry.gif" border="0"></a> <a href="<TMPL_VAR NAME=LINK>"><TMPL_VAR NAME=TITLE></a> <dt> <dd><TMPL_VAR NAME=COMMENT><dd> </TMPL_LOOP> </dl> </TMPL_IF>
こんな感じのテンプレートを用意しました。(途中見た目のため改行してます。)
Hack してて思ったんですが、今日のブックマークかどうかを判定する場所がちょっとダサくて、
grep $_->{dc}->{date} =~ /^$today/, @{$self->{rss}->{items}};
なんてことをやっているわけですが、どちらかというとフィードをループして判定するよりサーバー側で URL パラメータとして ?date=20040419 といったものをサポートしたほうが良いような気がしました。
このスクリプトを cron で一日一回動かすとかすると、自動コンテンツ生成マシーンの完成です。次のエントリに試しに投稿してみます。
はじめまして。
del.icio.us2MTで参考にさせてもらったものです。
いじっていて気付いたことなんですが、
$self->{list} or return;
ですと、配列のリファレンスが入っているのでreturnされずに続行してしまうようです。
$self->makelistの次に$self->{list}->[0] or returnを入れて止まるようにしてみましたが、
どういうのがかっこいいんでしょう。
あと、くだらないつっこみなんですが、テンプレのdt, ddが閉じられてないようなので一応報告です。
[1] Posted by: タロウ at April 29, 2005 01:51 AM [返信]ご指摘どもです。
かっこいい止め方...
@{$self->{list}} or return;
とか
return unless @{$self->{list}};
とかかなあ。
[2] Posted by: naoya at April 29, 2005 08:55 PM [返信]Typepadにはてなブックマークをpostしたいのですが、どこにどうやればアップできるんでしょうか?
プログラム知識ゼロだとやはりだめでしょうか?
うーん、そうですね、プログラムの知識がないとちょっと難しいかも。
そういう機能をはてなブックマーク側でサポートしちゃうという手もありますな。検討してみます。
[4] Posted by: naoya at May 20, 2005 09:59 AM [返信]なおやさん、ありがとうございます!
ぜひ、はてなブックマークを自分のブログやサイトにペタっとはりつけたく思いますので、よろしくお願いします!