MobileCal.appの使うデータベースを探検してみた
iPod touchのカレンダー(MobileCal.app)のデータをGoogleCalendarと同期させたいなと思ったので、中身を探ってみた。*1ソフトを組める段階にはならなかったが、いろいろわかったので、メモ。
ぐぐってみるとメモ帳やカレンダーはsqlite3を使っているらしく、sqlite3コマンドを使えばデータベースの中身を見られるらしい。というわけでsqlite3を入れて、探検してみた。
参考 > http://eternalbeta.openprocess.jp/archives/88
# sqlite3 /private/var/mobile/Library/Calendar/Calendar.sqlitedb SQLite version 3.4.1 Enter ".help" for instructions sqlite> .tables Alarm OccurrenceCache AlarmChanges OccurrenceCacheDays Calendar Recurrence CalendarChanges RecurrenceChanges Event Task EventChanges TaskChanges EventExceptionDate _SqliteDatabaseProperties
予定が作成されるEventテーブルの中身はこんなかんじ。
sqlite> select * from Event where description like "%Google%"; ROWID|summary|location|description|start_date|start_tz|end_date|all_day|calendar_id|orig_event_id|orig_start_date 2|てすてす|todai|GoogleCalendar|227397600|Asia/Tokyo|227401200|0|1|0|0
ここでstart_date, end_dateが変な数字として登録されている。数字の羅列だからunixtimeかと思ったけどそうでもなさそう。
で、とある日時から3600や86400をかけたり引いたりして調べたら2001年1月1日0時0分0秒を基準にしている秒数だった。しかもJST(日本標準時)だとさらに9時間ずれるので、9*3600を引いているのだった。
こんなのをいちいち手で計算するのが面倒なのでdateコマンドをPerlから呼び出して計算するスクリプトを書いた。Perlを選んだのはシェルスクリプトは数字の計算に向かなそうだったので。
#!/usr/bin/perl -w # Calculate seconds of MobileCal.app if (!$ARGV[0]) { exit; } $str = 'date --date="2008'. $ARGV[0]. '" +"%s"'; $target = `$str`; $offset = `date --date='20010101 00:00' +"%s"`; # For MobileCal.app seconds must be subbed by 3600*9 (Tokyo/Japan) print $target - $offset - 3600*9; print "\n";
シェルの出力を取り出すバッククォートを使ってみました。きっとPerlのdate関数でもいけるんだろうな。
使い方はこんなの。2008年の時間しかだせません。
/home/tsuzuki% perl date.pl "0404 10:00" 228963600
はい、どうでもいいですね。
今日はこんなスクリプトを使ってsqliteからMobileCal.appの予定を追加することに成功しました、という話です。
ちなみにMobileCal.appのデータベースに予定を追加したときは、追加したことを表すテーブル(EventChanges)や、予定のサマリーを入れているテーブル(OccurrenceCache, OccurrenceCacheDays)も更新しないといけないようです。Eventテーブルだけを更新すると、MobileCal.appの「月」タブでは表示されている予定が「リスト」タブでは表示されない、などといったことが起こります。逆に言えばsqliteを使ってデータベース内の必要なテーブルを変更してしまえば、カレンダーのデータをいじくることができます。
*1:SyncML2iPhone.comというそれっぽいソフトがあったのだが、うまく動かないので自分で作ってみようかなと思ったり。