Ruby で del.icio.us からはてなブックマークへデータを移行する感じのスクリプト

100に満たない数のブックマークでは一応動いてる感じだったけど、ちゃんと動くかは保証できない。

参考にしたところ

CPAN の使いかたがわからなかった…。なので Ruby
my $cache = file('delicious.xml'); の部分がよくわからなかったので、いったんファイルに書きだしてみた。

rubygems, atomutil なので、sudo gem install atomutil とかやって atomutil を導入しておく必要があります。atomutil については Atompub を。
あとよくわからないけど、Bad Content Type: application/x.atom+xml; charset=utf-8 とか言われるけど、スルーした。

#!/usr/bin/env ruby

require 'open-uri'
require 'rexml/document'
require 'rubygems'
require 'atomutil'

hatena_user = '<hatena username>'
hatena_pass = '<hatena password>'
del_user = '<del.icio.us username>'
del_pass = '<del.icio.us password>'

del_api    = 'https://api.del.icio.us/v1/posts/all'
hatena_api = 'http://b.hatena.ne.jp/atom/post'

file = 'delicious.xml'

unless File.exist?(file)
  open(del_api, :http_basic_authentication => [del_user, del_pass]) do |io|
    open(file, 'w'){|f| f.write(io.read) }
  end
end

content = open(file){|f| f.read }
doc = REXML::Document.new(content)
posts = doc.elements.to_a('posts/post')

auth = Atompub::Auth::Wsse.new(:username => hatena_user, :password => hatena_pass)
hatena = Atompub::Client.new(:auth => auth)

posts.reverse.each do |post|
  href     = post.attributes['href']
  tag      = "[" + post.attributes['tag'].split(' ').join('][') + ']' unless post.attributes['tag'].empty?
  extended = post.attributes['extended']
  summary  = tag.to_s + extended

  link = Atom::Link.new(
    :rel  => 'related',
    :type => 'text/html',
    :href => href
  )

  entry = Atom::Entry.new(
    :title   => 'dummy',
    :link    => link,
    :summary => summary
  )
  hatena.create_entry(hatena_api, entry)
  print "posted: #{href}\n"
end

もしも、なんかブックマークの登録のときミスって再実行しようとしたとき、また delicious にとりにいかないように、delicious.xml というファイル作ってるんだけど、つまりこのファイルがあると最新の delicious のデータじゃなくてローカルにあるデータを使う。なので最新のデータとってきて使いたい場合は delicious.xml を消す必要がある。あとインポート終わったら delicious.xml はいらないので消して。