「IT勉強会カレンダー」から、1日単位でエントリを切り出す

IT勉強会カレンダー」プログラミング・情報科学関連の勉強会情報を集約する場としては最も網羅性の高いものだと思いますが、情報量が多すぎて、自分の求める情報を探すのが難しいというのも事実です。
# というか、調べるのが面倒で放置しているうちに、「こんな勉強会があったのか!」と後悔することもしばしば

そこで、Google CalendarAPIを使って日付単位で勉強会情報のエントリを切り出し、後でRubyスクリプトでフィルタリングをかけることを試みてみます。Google Calendar API単体でもキーワードでフィルタリングをかけられますが、スクリプト化した方が融通が効きそうなので。

まずは、手始めにGoogle Calendar APIによる切り出しと、取得したAtomフィードRubyから読み出す処理を作成してみました。

情報源

Google Calendar APIの情報を探すのにちょっと手間取ったのですが、Google Data共通APIGoogle Calendar固有APIの2段構成になっているようです。

クエリ

今回は以下の範囲指定+順序指定クエリを使います。これらはHTTPリクエストへのquery stringとして渡すので、実際にはURLエンコードする必要があります。

  • start-min: イベント開始時刻が指定した時刻以降である場合にヒット
    • 例: start-min=2009-06-28T00:00:00+09:00
  • start-max: イベント開始時刻が指定した時刻よりも早い場合にヒット
    • 例: start-max=2009-06-28T22:00:00+09:00
  • orderby: 取得するエントリの出現順を指定
    • 例: orderby=starttime (デフォルトはlastmodified=最終更新時刻)

RubyからAtomフィードの読み出し

Google Calender APIでは、情報はAtomフィードで出力されるようです。

最初、Ruby標準添付ライブラリの範囲ではAtomフィードのパーズはできないと思っていましたが、どうやらrssライブラリでAtomフィードも読めるようです。

コードとしてはこんな感じ。

require 'rss'

rss_source = IO.read('atomfeed.xml')
rss = RSS::Parser.parse(rss_source, false)

rss.entries.each {|entry|
  puts
  puts entry.title.content
  puts entry.content.content
}

手元で試した範囲では、RSS::Parser.parseの第2引数 (バリデーションの有効化/無効化) をtrueにすると失敗するようです。
この辺は、Google Calendar APIRubyrssライブラリの仕様をよく理解していないので、とりあえずは放っておくことにします。

サンプルプログラム

では、IT勉強会カレンダーのAtomフィードを取得し、その内容を読み出して表示するようなRubyスクリプトを実際に書いてみます。

test.rb:

#!/usr/bin/ruby -Ku

require 'rss'
require 'erb'
require 'open-uri'

FEED_URL = 'http://www.google.com/calendar/feeds/fvijvohm91uifvd9hratehf65k%40group.calendar.google.com/public/basic'

query =  'start-min=' + ERB::Util.u('2009-07-01T00:00:00+09:00') + '&' +
  'start-max=' + ERB::Util.u('2009-07-02T00:00:00+09:00') + '&' +
  'orderby=starttime'

atom_feed = nil
open("#{FEED_URL}?#{query}") {|fin|
  atom_feed = fin.read
}

rss = RSS::Parser.parse(atom_feed, false)

rss.entries.each {|entry|
  puts '--------------------------'
  puts '[title]'
  puts entry.title.content
  puts '[content]'
  puts entry.content.content
}

上のコード中でクエリのURLエンコードを行っている部分、ERB::Util.uの代わりにURI.encodeでは '+' が期待通りにエンコードされないようです。

実行結果:

--------------------------
[title]
[東京]第4回バイナリ勉強会
[content]
期間: 2009/07/01 19:30〜21:00 
JST<br />

<br />場所: JR品川イーストビル ホールB  
<br />予定のステータス: 確定
<br />予定の説明: http://groups.google.co.jp/group/reading-assembly/msg/afb5feeb
298dfc88?hl=ja
--------------------------
[title]
[東京]『OKWaveファンミーティング09』
[content]
期間: 2009/07/01 19:00〜20:00&#160;
JST<br />

<br />場所: 式会社オウケイウェイヴ本社「ありがとうルーム」
<br />予定のステータス: 確定
<br />予定の説明: http://www.okwave.co.jp/news/press_log/2009/0529.html
...

各エントリの詳細がXHTMLになっているのがちょっと厄介ですが、ここまで来ればRuby側でフィルタリングするのも難しくなさそうです。