2006-03
04
22:02:00
はてブのブックマークを自動的にBlogへ投稿するスクリプト


しばらくテストで使ってみたんですが、意外に使えそうなので公開してみます。
はてブは基本的にストックじゃなくフローの印象が強くて、僕なんかはオンライン・ブックマークというよりはクリップとコメント書きのために使っています。
但しそのままでは放置ではもったいないので、RSSリーダーに登録することでXML-RPCを使って自分のはてブのブックマークをBlogに投稿するPerlスクリプトを作ってみました。
はてブの内容を自動的にかつ定期的に(場合によっては非定期?)自分のBlogへ転載できます。


①以下のスクリプトをサーバーにアップして、動作可能なように権限などを設定して下さい。
XML::RSS、XMLRPC::Liteなどのライブラリが必要です。
postHatebuComments.cgi

#!/usr/bin/perl
use lib qw(../lib);#←ライブラリは適当に変更して下さい。
use LWP::Simple;
use LWP::UserAgent;
use HTTP::Request::Common;
use HTTP::Date;
use XML::RSS;
use XMLRPC::Lite;
use CGI;
use Jcode;
my $hatena_id = "XXXX"; #←はてなのIDです。
my $RPCURL = "XML-RPCエンドポイントURL"; #←使用しているBlog製品や事業者でのXML-RPCエンドポイントURLを指定して下さい。
my $blogid = "xxxx"; #←Blogを示すBlogIDです。通常管理画面のURLなどから判別可能です。
my $username = "xxxxx"; #←ログインIDです。
my $password = "xxxxx"; #←パスワードです。
my $store_dir = "./hb_stats"; #←キャッシュディレクトリです。あらかじめ作成しておいて下さい。
@target_days = (&getToday(), &computeDate(1));
print "Content-Type: text/xml\r\n\r\n";
my $hbUrl = "http://b.hatena.ne.jp/".$hatena_id."/rss?date=";
my $html = "";
my $hbcnt;
my $outRSS = new XML::RSS (version => '1.0');
$outRSS->add_module(prefix=>'admin', uri=>'http://webns.net/mvcb/');
$outRSS->channel(
title        => "Posing Status of ".$hatena_id."'s Bookmarks.",
link         => "http://b.hatena.ne.jp/".$hatena_id."/",
description  => "Posing Status of ".$hatena_id."'s Hatena-Bookmarks.",
dc => {
language   => 'ja',
},
admin => {
generatorAgent   => 'http://www.rocaz.net/',
}
);
foreach my $dt ( @target_days ) {
$html = &getHatebuComments($dt);
if($html ne "") {
$html = "<dl>".$html."</dl><br /><p style=\"text-align: right;\"> : <a href=\"http://b.hatena.ne.jp/ro-ca/\">my Hatena-Bookmarks</a> (^_^)</p>";
if(!open(LOG,"$store_dir/$dt")) {
my $ret = &doNewPost($dt, $html);
open(LOG2, ">$store_dir/$dt");
print LOG2 "$ret:$hbcnt";
close(LOG2);
$ret = &doPublishPost($ret);
$outRSS->add_item(
title       => $dt,
description => $hbcnt.Jcode->new("個のブックマークをポストしました。", "sjis")->utf8,
dc => {
date => &time2Format(time, "%04d-%02d-%02dT%02d:%02d:%02d+09:00"),
creator  => $hatena_id,
}
);
} else {
my @indata = split(":", <LOG>);
if(@indata[1] ne $hbcnt) {
my $ret = &doEditPost($dt, $html, @indata[0]);
open(LOG2, ">$store_dir/$dt");
print LOG2 "@indata[0]:$hbcnt";
close(LOG2);
$ret = &doPublishPost(@indata[0]);
$outRSS->add_item(
title       => $dt,
description => $hbcnt.Jcode->new("個のブックマークを更新しました。", "sjis")->utf8,
dc => {
date => &time2Format(time, "%04d-%02d-%02dT%02d:%02d:%02d+09:00"),
creator  => $hatena_id,
}
);
}
}
close(LOG);
}
}
print $outRSS->as_string;
&cleanLog;
sub doNewPost {
my $dt = shift;
my $desc = shift;
my $result = XMLRPC::Lite
-> proxy($RPCURL)
-> call('metaWeblog.newPost', $blogid, $username, $password,
{
'title'             => Jcode->new(&time2Format(str2time($dt), "%04d年%02d月%02d日")."のブックマーク","sjis")->utf8,
'description'       => Jcode::convert($desc, "utf8", "utf8"),
'dateCreated'       => &time2Format(str2time($dt), "%04d-%02d-%02dT%02d:%02d:%02d+09:00"),
'mt_allow_comments' => 1,
'mt_allow_pings'    => 1
},
1
) -> result;
return $result;
}
sub doEditPost {
my $dt = shift;
my $desc = shift;
my $postid = shift;
my $result = XMLRPC::Lite
-> proxy($RPCURL)
-> call('metaWeblog.editPost', $postid, $username, $password,
{
'title'             => Jcode::convert(&time2Format(str2time($dt), "%04d年%02d月%02d日")."のブックマーク", "utf8", "sjis"),
'description'       => Jcode::convert($desc, "utf8", "utf8"),
'mt_allow_comments' => 1,
'mt_allow_pings'    => 1
},
1
) -> result;
return $result;
}
sub doPublishPost {
my $postid = shift;
my $result = XMLRPC::Lite
-> proxy($RPCURL)
-> call('mt.publishPost', $postid, $username, $password	) -> result;
return $result;
}
sub getHatebuComments {
my $ret = "";
my $rss_data = get($hbUrl.&time2Format(str2time($_[0]),"%04d%02d%02d"));
my $rss = new XML::RSS;
$rss->parse($rss_data);
$hbcnt = 0;
foreach my $item ( @{$rss->{'items'}} ) {
$title = $item->{'title'};
$link = $item->{'link'};
$desc = $item->{'description'};
$ret = $ret."<dt class='phb_HBTitle'><a href='$link'>$title</a></dt><dd class='phb_HBComment'>$desc</dd>";
$hbcnt++;
}
return $ret;
}
sub getToday {
my @ts=localtime(time);
$year = $ts[5]=$ts[5]+1900;
$mon = sprintf("%02.d", $ts[4] + 1);
$mday = sprintf("%02.d", $ts[3]);
$ret = $year."-".$mon."-".$mday;
return $ret;
}
sub computeDate {
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time - $_[0]*24*60*60);
$year += 1900;
$mon = sprintf("%02.d", $mon + 1);
$mday = sprintf("%02.d", $mday);
$ret = $year."-".$mon."-".$mday;
return $ret;
}
sub time2Format {
my $time = shift;
my $format_str = shift;
($sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst) = localtime($time);
return sprintf($format_str, $year+1900, $mon+1, $mday, $hour, $min, $sec);
}
sub cleanLog {
opendir DR, $store_dir;
while (my $file = readdir DR) {
next if( $file =~ /^\./);
my $flg = 0;
foreach my $targetdt ( @target_days ) {
if($targetdt eq $file) {
$flg = 1;
}
}
if($flg eq 0) {
unlink $store_dir."/".$file;
}
}
close DR;
}

②$store_dirに指定したディレクトリを作成して、書き込み可能な権限を付け加えておきます。
# Plagger使えばもっと楽、とか言わないように(^^;
文言とかHTMLなんかは適当に変更して下さい。
うちのサーバーのPerlは5.6系列なのでJcodeを使用していますが、5.8以降であればEncodeに変更してもいいでしょう。
ポイントとして、このスクリプトはRSSを吐くようになっています。そこでこのスクリプトのURLをBloglinesなどで購読することで、定期的かつ自動的にBlog投稿が行われるようになっています。cronが使えないような環境では便利かも。
要はRSSリーダーで購読してしまえば定期チェックされたタイミングで投稿を行うようになるので、ローカルPCのRSSリーダーから購読していても構わないのですが、当然PCがシャットダウンなどされている間は自動投稿されませんので、注意して下さい。
・投稿の範囲は当日と前日の二日間です。
・日別のはてブのブックマーク数を調べ、前回と比較して異なるようであればBlogへ投稿します。
・ローカルのキャッシュディレクトリに日別に投稿結果を保存するファイルを作成します。前日以前のファイルは自動的に削除します。
XML-RPCで投稿しますので、XML-RPCに対応したBlogで無いと使えません。
こちらとかを参考にしてみて下さい。
またはBlogPetが使用できるBlogでも大体使えそうです(XML-RPCではなくAtom APIにのみ対応したlivedoorなどでは使えません)。こちらとかこちらも設定の参考にどうぞ。
ちょっとしたニュースサイト的に使ってみるのも面白いかと。但しコメントは100文字制限ですけど。
ブックマークついでにBlog書きもしたいずぼらな人には最適かとも思います。良ければ使ってみて下さい。
Let’s Enjoy to Try!

One thought on “はてブのブックマークを自動的にBlogへ投稿するスクリプト

コメントを残す

メールアドレスが公開されることはありません。

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください