id:otn:20140829 の続き。
どういうときに、ExchangeのイベントとGoogle Calendarのイベントを等しいと判断するか。
考慮が必要なのは3点。
- 文字列の内容
タイトル、内容、場所など文字列の文字コードがCP932か、utf-8かの違い。これはutf-8に揃えることにする。
また、内容がないときはExchangeは空文字列で、Google Calendarではnilで、これは空文字列に揃える。
- 全日イベント
Exchangeだと0時から翌日0時の予定で、全日フラグ(AllDayEvent)がtrueになっている。
Google Calendarだと、日付だけが文字列でセットされている。これはExchange式に揃える。
- リマインダー
Exchangeは、リマインダー有無のフラグ(ReminderSet)と、分数がセットされている。また、リマインダー時刻が過ぎると、分数はそのままでフラグがfalseになる。
Google Calendarは、複数のリマインダーがセットできるようで配列になっている。また、リマインダーのデフォルト値があり、デフォルトかどうかのフラグ(use_default)がある。リマインダーがないときは、デフォルトフラグがfalseで配列が空。リマインダー時刻が過ぎても値は変化しない。
class Event def ==(other) @start == other.instance_variable_get(:@start) and @end == other.instance_variable_get(:@end) and @allday == other.instance_variable_get(:@allday) and reminder_eql?(@start, @reminder, other.instance_variable_get(:@reminder)) and @title == other.instance_variable_get(:@title) and @body == other.instance_variable_get(:@body) and @location == other.instance_variable_get(:@location) end private def reminder_eql?(start, x, y) @@now ||= Time.now ( x == y ) or ( x and not y and start - x < @@now ) or # リマインダー時刻を過ぎている場合はリマインダーの有無を無視 ( y and not x and start - y < @@now ) end end class Gcal < Event def initialize(event) if event.start.date # 全日イベント @start = Time.parse(event.start.date) @end = Time.parse(event.end.date) @allday = true else @start = event.start.date_time @end = event.end.date_time @allday = false end if event.reminders.use_default @reminder = 10 # 正確にはそのユーザーのデフォルト値を取得する必要がある elsif event.reminders.overrides[0] @reminder = event.reminders.overrides[0].minutes else @reminder = nil end @title = event.summary || "" @body = event.description || "" @location = event.location || "" @id = event.id end end class Ecal < Evant def initialize(event) @start = event.Start @end = event.End @allday = event.AllDayEvent @reminder = event.ReminderSet ? event.ReminderMinutesBeforeStart : nil @title = event.Subject.encode(Encoding::UTF_8) @body = event.Body.encode(Encoding::UTF_8) @location = event.Location.encode(Encoding::UTF_8) end end