<< >>

2007-11-06 [長年日記]

[Rails] GoogleCalendar を使う 〜 データ登録編 〜

データの更新や private なカレンダーへアクセスするには Google へのログインおよびセッション維持が必要になるが、gcalapi では GoogleCalendar::Service がセッション周りの面倒を全て見てくれる。

Serviceオブジェクトの作成

Serviceオブジェクトは、カレンダー用の Gmail のアカウント情報から簡単に作成できる。

srv = GoogleCalendar::Service.new('xxxxxx@gmail.com', 'password')  # (※ メアドとパス)

Calendarオブジェクトの作成(その1)

カレンダーへのアクセスには、Calendarオブジェクトを利用する。これは、先ほどのServiceオブジェクトと参照先するカレンダーのFEED情報(カレンダーのID = URL)から作成することができる。

url = 'http://www.google.com/calendar/feeds/t69rg69mfq7jfh8ivh4b91fhug%40group.calendar.google.com/private/full'
cal = GoogleCalendar::Calendar.new(srv, url)

Calendarオブジェクトの作成(その2) FEED情報の取得

Serviceオブジェクトから接続したアカウントで利用可能なFEED情報の一覧を取得することもできるので、「FEED情報を覚えるなんて無理!」という場合には便利である。実際、インタラクティブなUIの場合など、こちらの利用法がメインになるだろう。具体的には、calendar クラスメソッドによって、利用可能な「FEED情報」と「Calendarオブジェクト」からなるHashを得る。

>> cals = GoogleCalendar::Calendar.calendars(srv)
>> cals.keys
=>  ["http://www.google.com/calendar/feeds/t69rg69mfq7jfh8ivh4b91fhug%40group.calendar.google.com/private/full", ...]

>> cal = cals.values.first
=> #<GoogleCalendar::Calendar:0xf6e18948
     @feed="http://www.google.com/calendar/feeds/t69rg69mfq7jfh8ivh4b91fhug%40group.calendar.google.com/private/full",
     @source=nil,
     @srv=...

イベントデータの操作

Eventオブジェクトの取得

Calendarオブジェクトに events メソッドを投げると、登録されているイベント情報の配列が返される。

>> events = cal.events
>> events.size
=> 25

>> events.each{|event| puts "%s %s" % [event.en, event.title] }
Fri Nov 23 11:30:00 UTC 20072007ハロー!プロジェクト新人公演11月〜品川で会いましょう〜 」
Sun Nov 25 10:50:00 UTC 2007 Buono!デビュー記念イベント
...

Eventオブジェクトの更新

ここで得られる Event オブジェクトには ServiceおよびFEED情報が関連付けられているので、値を修正した後に save! メソッドによって自動的に変更内容が Google へと反映される。もちろん、Event.new で作ったオブジェクトに srv と feed 値を自分で設定しても同じ結果になる(※1)。この辺りは、ActiveRecord (と関連)の挙動に似ているので扱い易い。

(※1 未検証。new_record?周りの処理は必要かもしれない)

更新例) 1件目のイベントを翌日に延期する

>> event = events.first
>> event.st += 86400
>> event.save!
GoogleCalendar::EventUpdateFailed: [Line 1, Column 1783, element gd:when] g:when/@startTime must be less than or equal to g:when/@endTime.

なるほど。開始と終了時間の整合性もちゃんとチェックされている。素晴らしい。

更新例) 1件目のイベントを翌日に延期する(終了時刻も考慮)

>> event.en += 86400
>> event.save!
=> #<GoogleCalendar::Event:0xf6e50654  @feed="http://www.google.com/calendar/feeds/t69rg69mfq7jfh8ivh4b91fhug%40gro...

Eventオブジェクトの属性

名前説明
title件名String
desc詳細String
where場所String
st開始日時Time
en終了日時Time
allday終日フラグtrue/false

Eventオブジェクトの追加

Calendarオブジェクトに create_event メソッドを投げると、新しい Event オブジェクトが返る。この時点では、Rubyオブジェクトの生成のみであり、同オブジェクトに save! を投げた時点で Google へと保存される。

event = cal.create_event
event.title = "石村舞波の誕生日"
event.st    = Time.mktime(2007, 11, 20)
event.en    = Time.mktime(2007, 11, 20, 1)
event.save!

この辺も AR に近いので使い勝手がよい。逆に AR 感覚で使う場合の注意点として、create_event は new_event という認識でいる必要がある。というか、手元の操作がちゃんと Google に反映されているのが楽し過ぎる。

create_event.jpg

Eventオブジェクトの削除

こちらも AR ぽく destroy! メソッドでOK。

>> event.destroy!
=> :deleted

イベントデータの検索

Calendar#events メソッドの引数に、イベントデータの検索条件を指定することができる。

パラメータ説明補足
q検索文字列全文検索
orderbyソート対象SQLのorder by
start-index開始位置SQLのoffset (値は1から)
max-results取得件数SQLのlimit (デフォルトは25)
start-min最小開始日時
start-max最大開始日時

これらは、Google の API に直接渡されるため、パラメータの指定対象となるフィールド名は Event オブジェクトのものではなく、Google の API のものになるので注意。(詳細は参考2,3)。

Buono情報だけ取得

>> events = cal.events(:q=>"Buono", :orderby=>"starttime")
>> events.size
=> 6

>> events.each{|event| puts "%s %s" % [event.en, event.title] }
Sun Nov 25 10:50:00 UTC 2007 Buono!デビュー記念イベント
Sun Nov 25 08:30:00 UTC 2007 Buono!デビュー記念イベント
Thu Nov 22 00:00:00 +0900 2007 「ホントのじぶん」Buono!(DVD)発売
Sat Nov 17 10:50:00 UTC 2007 Buono!デビュー記念イベント
Sat Nov 17 08:40:00 UTC 2007 Buono!デビュー記念イベント
Mon Nov 05 15:00:00 UTC 2007 Buono!イベ申し込み締切

疑問

  • orderby で DESC 指定はできない?
  • 時として UTC だったり JST だったり

参考

  1. gcalapi http://rubyforge.org/projects/gcalapi/
  2. 検索パラメータ http://code.google.com/apis/gdata/reference.html#Queries
  3. Google Calendar APIの基礎 http://www.rcdtokyo.com/ucb/contents/i000815.php