GMarksへエクスポート

livedoorクリップのデータをGoogle Bookmarkへ移行させるためのスクリプトを書いた。自分のデータで1回使っただけなので、バグはあると思う*1。特に、sleep(1)は適当なので回線が細いともっと待たなければいけないかもしれない。
ラベルの日本語対応が上手くいかなくて、を参考にさせてもらった。
使い方は、livedoorクリップからエクスポートして保存したデータをコマンドの引数に渡すだけ。まだ、一部で文字化けする。

(2008/06/25)文字化けを直した。エクスポートしたlivedoorクリップがUTF8で保存されているのに、SJIS変換で誤認識していることが原因だった。

kconv(Kconv::SJIS,Kconv::UTF8)

を使う修正版。

#! /usr/bin/env ruby

require 'rubygems'
require 'mechanize'
require 'rss/2.0'
require 'kconv'

class Gmark
  def initialize(id,pass)
    @id = id
    @pass = pass
    @agent = WWW::Mechanize.new
  end

  def login
    login_page = @agent.get('http://www.google.com/bookmarks/?hl=ja')
    login_form = login_page.forms.first
    login_form['Email'] = @id
    login_form['Passwd']= @pass
    page = @agent.submit(login_form)
  end
  def post_clips(feed)
    feed.items.each { |item|
      tags = []
      unless item.categories.empty?
        item.categories.each { |cat|
          tags.push cat.content
        }
      end
      inport(item.title, item.link, tags, item.description)
      # 待つ
      sleep(1)
    }
  end

  private
  # bookmarkを取り込む
  def inport(title,url,labels=[],anno="")
    page = @agent.get('http://www.google.com/bookmarks/mark?op=add&hl=ja')
    add_form = page.forms.name("add_bkmk_form").first

    add_form['title'] = title.kconv(Kconv::SJIS,Kconv::UTF8)
    add_form['bkmk'] = url.kconv(Kconv::SJIS, Kconv::UTF8)
    unless labels.empty?
      add_form['labels'] = labels.join(",").kconv(Kconv::SJIS, Kconv::UTF8)
    end
    add_form['annotation'] = anno.kconv(Kconv::SJIS, Kconv::UTF8)
    @agent.submit(add_form)
  end
end

ARGV.each { |fname|
  feed = nil
  begin
    text = File.read(fname)
    # Dublin Coreが動作しないので無理矢理変換する
    text.gsub!(/<dc:subject>/,"<category>")
    text.gsub!(/<\/dc:subject>/,"</category>")
    feed = RSS::Parser.parse(text)
  rescue RSS::Error
  end

  if feed.nil?
    puts "#{fname}はRSS 0.9x/1.0/2.0, Atom 1.0のいずれでもありません。"
  else
    gmark = Gmark.new('Google ID','Google Password')
    gmark.login
    gmark.post_clips(feed)
  end
}

*1:一部で文字化けしている。