Twitterの発言をhatena用に出力するrubyコード

 Twitterでの発言でblogの記事を稼ぐかな,と思って作ってみた.すでにそういうサービスがあるのは知っているけど,駄々漏れではなくて一部抜粋にしたかったので作ってみた.抜粋とはてなへの投稿は手動です.

 記事への言及,というスタイルが多いようです.それならはてブで良いじゃないか,と思ったりもしますが,Google Readerからはてブにたどり着くのが面倒なので,これで良いかな.それに,記事と関係ない発言ややり取りもあって,一元的に残しておきたいので.

 抜粋する部分をajaxでかっこよく作ってみたかったりもしたんだが,時間対効果が薄いと判断して却下.さらにはてなへの投稿も,はてなダイアリーapiがよく分かっていないので,スルー.

 せっかくなので,出来たコードを晒してみる.

#!/usr/bin/ruby -Ku
require 'net/http'
require 'rexml/document'
require 'kconv'
require 'time'
require 'pp'

Net::HTTP.version_1_2

class String
  def escapeHTML
    self.gsub(/&/n, '&amp;').gsub(/\"/n, '&quot;').gsub(/>/n, '&gt;').gsub(/</n, '&lt;')
  end
end

path_id = '/home/kei/public_html/since_id2'
li_format = '-<span style="font-style:italic;">[http://twitter.com/kkei/status/%s:title=%s]</span> %s'

since_id = *File.open(path_id, 'r') {|f| f.read.strip.to_i}

xml = nil
if ARGV.length == 0
  Net::HTTP::Proxy('www-proxy.waseda.jp', 8080).start('twitter.com', 80) {|http|
    req = Net::HTTP::Get.new("/statuses/user_timeline.xml?since_id=#{since_id}&count=200")
    req.basic_auth('kkei','password')
    xml = http.request(req)
  }
end

if xml
  doc = REXML::Document.new xml.body
else
  exit if ARGV.length == 0
  doc = File.open(ARGV[0], "r") {|f| REXML::Document.new f}
end

since_id = doc.elements['statuses/status/id'].text.to_i
File.open(path_id, 'w') {|f| f.print since_id }
if xml
  File.open("user_timeline.xml", 'w') {|f| f.write xml.body}
end

tweets = []
doc.elements['statuses'].each_element do |e|
  id = e.elements['id'].text
  time = Time.parse(e.elements['created_at'].text)
  text = e.elements['text'].text.to_s.toutf8
  text.gsub!(/@([[:alnum:]_]+)/, '@[http://twitter.com/\1/:title=\1]')
  tweet = format(li_format, id, time.strftime("%H:%M"), text)
  tweets << tweet
end
tweets << "*[twitter]今日のTwitter(抜粋)"

printf "Content-Type: text/html;\n\n"
printf "%s", <<EOS
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Today's tweet.</title></head>
<body><pre>#{tweets.reverse.join("\n").escapeHTML}</pre></body>
</html>
EOS

 since_id2というファイルに,取得開始の発言idを保存しておきます.エラー処理はゼロなので,このファイルがなかったりすると落ちます.本当は1日たったらsince_idを更新したかったのですが,うまくロジックを組めなかったので断念.意外と面倒なんですよ…….なんどもapiを呼んでTwitterに負荷をかけるのも申し訳ないですし.

 大学のサーバに設置したので,プロキシ経由です.あと,idとpasswordはベタ書きです.まぁ,自分用なので良いことにしています.デバッグ用に,引数があるときは,そのxmlファイルを読みに行っています.

 私がはまったポイントをいくつか.日本語を含めていたため,スクリプトが実行できずに困り果てました.てっきりutf-8にしておけば良いのかと思ったら,デフォルトの文字コードはnoneということでした.ruby -Kuと文字コードの指定が必要なようです.さらに,escapeHTMLが必要になったので,CGIからコピって来ました.素直にrequireしても良かったのですが,なんとなく.開発サーバと公開サーバでrubyのバージョンが違ったために,gsubにハッシュを渡せなくてしばらく悩みました.それから,formatの第一引数として発言を全て渡していたところ,%が含まれていてエラーとなりました.これのうまい解決方法は分からなかったので,"%s"に放り込むことにしました.

 折角自前で実装しているので,@で会話しているところは相手の発言も引っ張ってきたかったのですが(自分のtimelineのログは保存してあるのでデータはある),明らかに著作権的にアウトなので自重しました.リンクを張るだけにしておけばよいのかもしれませんが,それだと会話の一覧性が損なわれるので,スルー.