はてブエントリのTwitter自動投稿 (その2)

前回作成した、はてなブックマークRSSフィードを読んで、内容をTwitterに投稿するスクリプトを少し改良して、未投稿エントリのみ投稿するようにしました。

今までのあらすじ

投稿済みエントリの保存には、gdbmライブラリを使っています。キーとしてエントリのURL (RSSのlink要素)、バリューとして '1' (単に集合としてしか使っていないので値は何でも良いですが、適当に) を入れています。

参考: Ruby 1.8.7 リファレンスマニュアル > gdbmライブラリ

機能的には、これでだいたい完成かな。

TODO

ソースコードはこんな感じ。投稿済みエントリのURLを保存する部分以外は、前回と変わりません。

require 'rubygems'
require 'gdbm'
require 'jcode'
require 'rss'
require 'twitter'

HEADER = '[bookmark]'
BODY_LENGTH = 115
POSTED_DB = 'twitter_posted.gdbm'

class String
  def truncate(length)
    return self if self.jlength <= length
    i = 0
    new_string = ''
    self.each_char {|char|
      break if i >= length
      new_string << char
      i += 1
    }
    return new_string  end
end

GDBM.open(POSTED_DB) {|db|
  client = nil
  rss = RSS::Parser.parse('rss.xml')
  rss.items.reverse.each {|item|
    next if db.has_key?(item.link)
    db[item.link] = '1'
    tag_string = item.dc_subjects.map{|subject| "[#{subject.content}]"}.join
    comment = (item.description == '' ? '' : ": #{item.description}")
    message = "#{HEADER}#{tag_string} #{item.title}#{comment}"
    message = message.truncate(BODY_LENGTH) + " #{item.link}"
    puts message
    client = Twitter::Client.new(:login => <ユーザ名>, :password => <パスワード>) if client == nil
    client.status(:post, message)
  }
}

dbm/gdbmライブラリはほとんどハッシュと同じように使えるので、扱いは非常に楽ですね。1回実行した後、試しに以下のようなスクリプトを実行して、gdbmデータベースの中身を確認してみます。

read_db.rb:

require 'gdbm'

POSTED_DB = 'twitter_posted.gdbm'

GDBM.open(POSTED_DB) {|db|
  db.each_pair {|key, value|
    puts "#{key} => #{value}"
  }
}

実行結果:

$ ruby read_db.rb:
http://www.asahi.com/national/update/0516/TKY200905160093.html => 1
http://r25.jp/b/report/a/report_details/id/110000006723 => 1
http://business.nikkeibp.co.jp/article/topics/20090430/193397/ => 1
...