Pages

2011年6月5日日曜日

iCalendarでgoogleカレンダーへの登録を自動化

会社で使っているグループウエアのスケジュール情報をGoogleカレンダーに写すことを考えてみた。グループウエアにicalファイルを発行する機能があらば良いのだが、あいにくそのような機能はない。
用意するプログラムの概要は
  • 会社のグループウエアのデータベースからsqlでスケジュールファイルを出力
  • スケジュールファイルからicalファイルを作成し、webで公開
  • Googleカレンダーで「その他のカレンダー」を追加。(url指定)

iCalendarは、RFCで定義されている、カレンダー情報の共通規約です。あんまり、普及していないような気もしますが。詳細は定義は、以下が日本語でわかりやすいです。
iCalendar

icalendarを扱うライブラリが、rubygemにありましたので、それをインストールします。
$ sudo gem install icanlendar

sqlで取得したスケジュールファイルはこんな感じ。
ZZZ FW切り替え作業 監視 |       |      | 2011-06-04 00:00:00 | 2011-06-04 00:00:00
月曜ミーティング        |       |      | 2011-06-06 09:00:00 | 2011-06-06 10:00:00

require "rubygems"
require "icalendar"
require "kconv"    # 日本語の文字コードを扱うための標準ライブラリ
require "date"
# OpenStruct (標準ライブラリ)
# javascriptのobjectのようにプロパティの追加を気楽に扱う
# http://memo.yomukaku.net/entries/244
require "ostruct" 

schdule_file = 'schedules.dat'
schedules = []
File.readlines(schedule_file).each do |line|
  v = line.split(/\|/).map{|val| val.strip}
  next unless v.size > 1
  schedule = OpenStruct.new
  schedule.user = v[0]
  schedule.event = v[1]
  schedule.content = v[2]
  schedule.place = v[3]
  schedule.start = DateTime.parse(v[4])
  schedule.end = DateTime.parse(v[5])
  schedules.push schedule
end

cal = Icalendar::Calendar.new
# VEVENT コンポーネント
# ここがスケジュールの本体
schedules.each do |schedule|
  cal.event do
    dtstart schedule.start, {'TZID' => 'Asia/Tokyo'}
    dtend   schedule.end  , {'TZID' => 'Asia/Tokyo'}
    summary schedule.event
    description schedule.content
  end
end

# STANDARD コンポーネント
standard_component = Icalendar::Component.new('STANDARD')
standard_component.custom_property('dtstart', '19700101T000000')
standard_component.custom_property('tzoffsetfrom', '+0900')
standard_component.custom_property('tzoffsetto', '+0900')
standard_component.custom_property('tzname', 'JST')

# VTIMEZONE コンポーネント
vtimezone_component = Icalendar::Component.new('VTIMEZONE')
vtimezone_component.custom_property('tzid', 'Asia/Tokyo')
vtimezone_component.add(standard_component)
cal.add(vtimezone_component)

# iCalファイル
ical_file = 'calendar.ics'
File.open(ical_file, "w+b") { |f|
    f.write(cal.to_ical.toutf8)
}

さらっと、書いたが実はいろいろと苦労した。
  • 最初はタイムゾーンを設定せずに作成したため、時間がずれた
  • Googleカレンダーの更新が遅いため、ファイルを変更してもカレンダーに反映せず

それにしても、Googleカレンダーはどの程度の間隔で外部カレンダー情報を更新しているのだろうか? サイトを調べた限りでは、数時間ということだが、なんかいつまでたっても更新しない。

困ったもんだ。

0 件のコメント:

コメントを投稿