「IT勉強会カレンダー」から、1日単位でエントリを切り出す
「IT勉強会カレンダー」プログラミング・情報科学関連の勉強会情報を集約する場としては最も網羅性の高いものだと思いますが、情報量が多すぎて、自分の求める情報を探すのが難しいというのも事実です。
# というか、調べるのが面倒で放置しているうちに、「こんな勉強会があったのか!」と後悔することもしばしば
そこで、Google CalendarのAPIを使って日付単位で勉強会情報のエントリを切り出し、後でRubyスクリプトでフィルタリングをかけることを試みてみます。Google Calendar API単体でもキーワードでフィルタリングをかけられますが、スクリプト化した方が融通が効きそうなので。
まずは、手始めにGoogle Calendar APIによる切り出しと、取得したAtomフィードをRubyから読み出す処理を作成してみました。
情報源
Google Calendar APIの情報を探すのにちょっと手間取ったのですが、Google Data共通API+Google Calendar固有APIの2段構成になっているようです。
- IT 勉強会カレンダーのFeed紹介しておきます - 家庭内インフラ管理者の独り言(はなずきんの日記っぽいの): 「IT勉強会カレンダー」AtomフィードURLの情報
- http://code.google.com/intl/ja/apis/calendar/docs/2.0/reference.html: Google Calendar 特有のクエリオプション (start-min/max, orderby, etc.) など
- http://code.google.com/intl/ja/apis/gdata/docs/2.0/reference.html: Google Data 共通のクエリオプション (q, etc.) など
- RSS Parser - COZMIXNG: Ruby標準添付ライブラリrssのリファレンス
クエリ
今回は以下の範囲指定+順序指定クエリを使います。これらは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 APIやRubyのrssライブラリの仕様をよく理解していないので、とりあえずは放っておくことにします。
サンプルプログラム
では、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  JST<br /> <br />場所: 式会社オウケイウェイヴ本社「ありがとうルーム」 <br />予定のステータス: 確定 <br />予定の説明: http://www.okwave.co.jp/news/press_log/2009/0529.html ...
各エントリの詳細がXHTMLになっているのがちょっと厄介ですが、ここまで来ればRuby側でフィルタリングするのも難しくなさそうです。