TitaniumMobile勉強記

Web系エンジニア向けのキャリアアドバイザーやってましたが現在はフリーランスで開発含めて色々やってます。技術ネタとしてはRuby/RailsとJavaScript関連(Node.js、Titanium)あたり

エキブロから過去のブログを移行するツール出来た!

エキサイトブログからのデータ移行ツールを現在開発中 - インターネット時代のキャリアプランとは?というエントリを以前書いて放置していたツールですが、なんとか完成しました。

はてなへデータを取り込む時にはMT形式にするんだけど、ブログ投稿日付のフォーマットが

エキブロの場合:yyyy-mm-dd hh::mm
MT形式:mm/dd/yyyy hh:mm:ss (PM/AM)

という感じでそれぞれ異なるために、この処理をどうすればいいのかちょっと悩んだけど、Nokogiriで取得した日付の情報が文字列として内部的に保持されているようなので

_date = ParseDate::parsedate(doc.search('span[@class="TIME"]/a').text)

とすると、配列_dateには、先頭から順番にyyyy,mm,dd,hh,mm の値が格納されているのでそれをTime.local()の引数にこんな感じで与えてから、strftime()を下記のように指定して意図した通りにMT形式に変換できました。(これについては2009-05-15 - 篳篥日記がとても参考になった!)

@post_date = Time.local(_date[0],_date[1],_date[2],_date[3],_date[4],0,0,0).strftime("%m/%d/%Y %I:%M:%S %p")

後の処理は基本的にそれほど戸惑わなかったんだけど、一気に全件取得しようとすると

/opt/local/lib/ruby/1.8/tempfile.rb:61:in `initialize': Too many open files - /var/folders/Gn/GnpE+3RxF8OkkSkIlYpQok+++TI/-Tmp-/open-uri20100212-6841-oyu4w5-0 (Errno::EMFILE)

と怒られてしまい、Bug #2067: bodyが大きいエラーページをopen-uriで取得するとfdがリークしている - Ruby 1.8 - Ruby Issue Tracking Systemなんかの情報を見た感じでは、とりあえず全件まとめてではなく、小分けに処理した方が良さそうなので、最初に読み込むページと、終了ページを指定した上で処理を行う形に切り替えました。

出来たツールはこんな感じ

require 'rubygems'
require 'nokogiri'
require 'open-uri'
require 'erb'
require 'parsedate'
class Exblog2MT
  def initialize(start_url, last_url, file_name)
    @start_url = start_url
    @last_url = last_url
    @file_name = file_name
  end
  attr_accessor :post_date, :html_body, :result, :title
  
  def start_parse
    self.move_to(@start_url)
  end

  def get_contens(url)
    begin
      doc = Nokogiri::HTML(open(url))
    rescue OpenURI::HTTPError => e
      e.io.close
    end
    
    _date = ParseDate::parsedate(doc.search('span[@class="TIME"]/a').text)
    @post_date = Time.local(_date[0],_date[1],_date[2],_date[3],_date[4],0,0,0).strftime("%m/%d/%Y %I:%M:%S %p")
    @title = doc.search('//div[@class="POST_TTL"]').text
    @html_body = doc.search('//div[@class="POST_BODY"]').inner_html
    temp = File.open("exblog2MT.tmpl") { |f| f.read }
    @result = ERB.new(temp, nil, '-')
    begin
      f = File.open(@file_name,"a")
      f.puts @result.result(binding)
      f.close
    rescue OpenURI::HTTPError => e
      e.io.close
    end
  end
  
  def move_to(url)
    doc = Nokogiri::HTML(open(url))
    loop do
      _nextlink=""
      self.get_contens(url)
      doc.search('td[align="RIGHT"][width="48%"]').map {
        |link| _nextlink=link.search('@href').text
      }
      if _nextlink == @last_url then
        exit 
      else
        move_to(_nextlink)
      end
    end
  end
end
start_url = "http://dmyoh.exblog.jp/4048814/"
last_url = "http://dmyoh.exblog.jp/4927299/"
file_name = "exblog-xxxx.txt"
exblog = Exblog2MT.new(start_url, last_url, file_name)
exblog.start_parse

ERB.newで指定したテンプレートはこんな感じのものを準備しておきました


AUTHOR: h5y1m141
TITLE: <%= @title %>
STATUS: Publish
ALLOW COMMENTS: 1
CONVERT BREAKS: 1
ALLOW PINGS: 1
DATE: <%= @post_date %>

        • -

BODY:<%= @html_body %>

        • -

EXTENDED BODY:

        • -

EXCERPT:

        • -

KEYWORDS:

        • -
              • -