atomutilを使ってrubyではてなダイアリーに投稿する方法

これまでのrubyでのブログの投稿では、mechanizeを使用して実際のWebでの画面をシュミレートして投稿をするようにしていましたが、どこのブログも結構仕様変更が多くて、そのたびに修正をしていました。

XMLやAtomPubでの投稿ができるのは知ってはいたのですが、AB型の変なこだわりでmechanizeでの方法を貫いていました(笑)。

とはいっても、どう考えてもスマートな方法ではないので、はてなのAtomPubの方法も少し変わったみたい(はてなブログAtomPub - Hatena Developer Center)ですので、これを機会にAtomPubでの投稿に切り替えたいと思います。

そこで、atomutil(atomutil - RubyでAtomPubを操作するパッケージをリリースしました - Codin’ In The Free World)なるものを発見しましたので、それではてなダイアリーrubyから投稿を行ってみました。

# -*- coding: utf-8 -*-

# @see : http://d.hatena.ne.jp/lyokato/20071211/1197353609
# gem install atomutil
require 'atomutil'

# Livedoorブログやアメブロ対策のためオーバーライドし、戻り値としてLocationではなくステータスコードを返却するようにする
class Atompub::Client
  def create_entry(post_uri, entry, slug=nil)
    unless entry.kind_of?(Atom::Entry)
      entry = Atom::Entry.new :stream => entry
    end
    service = @service_info.get(post_uri)
    # Livedoorブログの場合、serviceが取得できなくてservice.allows_category?でエラーになるので、if serviceでくくる
    if service
      unless entry.categories.all?{ |c| service.allows_category?(c) }
        raise RequestError, "Forbidden Category"
      end
    end
    create_resource(post_uri, entry.to_s, Atom::MediaType::ENTRY.to_s, slug)
    return @res.code
  rescue Atompub::ResponseError #=> rs
    # アメブロでは正常に投稿できても@res['Location']が空になってResponseErrorになるので捕獲する
    return @res.code
  end
end

def entry(id, password, title, content, category=nil)
  auth = Atompub::Auth::Wsse.new :username => id, :password => password
  client = Atompub::Client.new :auth => auth    

  new_entry = Atom::Entry.new
  # 下の方法でカテゴリの設定をすることができないみたいなので、はてな記法でカテゴリを設定する
  if category
    title = "*[#{category}]#{title}"
  end
  new_entry.title = title.encode("BINARY", "BINARY")
  new_entry.content = content.encode("BINARY", "BINARY")
  #if category
  #  new_category = Atom::Category.new
  #  new_category.term = category
  #  new_entry.category = new_category
  #end
  return client.create_entry("http://d.hatena.ne.jp/#{id}/atom/blog", new_entry)  
end

title = "タイトル"
content =<<EOM
ここは本文です。
<b>太字ですか?</b>
改行されていますか?
EOM
category = 'ツール'

puts entry('<はてなのID>', '<パスワードもしくはAPIキー(※1)>', title, content, category)

※1)現在はパスワードでもいいみたいですが、そのうちAPIキーでなくてはいけなくなります。(はてなダイアリーAtomPubのWSSE認証の認証方法を変更します(開発者向け) - はてなダイアリー日記

以下のサイトを参考にしました。ありがとうございました。