雑記

2000|01|
2003|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|
2007|01|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|09|11|
2009|02|03|05|06|07|08|10|11|12|
2010|01|03|04|05|06|07|08|09|10|
2011|05|06|09|10|
2012|03|07|09|12|
2013|01|02|04|05|07|08|10|11|
2014|04|05|08|10|12|
2015|01|05|
2016|09|

2013-11-03 [長年日記]

iOS7とDAViCal

手元の機器をiOS7にアップグレードしたところ、DAViCalで管理していたカレンダーの予定が消えてしまいました。iCloudやgoogleのカレンダーはiOS側の設定のリセットで直るという情報があるのですが、再起動やアカウントの削除→再登録をしても既存のカレンダーが見えずに新しいカレンダーを作ってしまいます。調べてみると、iOS7でカレンダーとして認識させるには特殊なプロパティを設定する必要があるようでした。以下、リンク先に記述されている内容をもとにカレンダーを見えるようにするための手順を説明します。

既存のカレンダーの修正

既存のカレンダーを見えるようにするためにはDBを直接操作する必要があります。例として"foo"アカウントの”calendar”カレンダー(/foo/calendar/)を見えるようにするための手順を記述します。

DAViCalのデータベースに接続します

# psql davical davical_app

以下のSQLを実行して"foo"のユーザIDを調べます。

davical=> SELECT user_no,username FROM usr;
 user_no | username 
---------+----------
       1 | admin
    1001 | foo
    1002 | bar
(3 行)

プロパティを登録します。

davical=> INSERT INTO property (dav_name, property_name, property_value, changed_by)
    VALUES ('/foo/calendar/',
            'urn:ietf:params:xml:ns:caldav:supported-calendar-component-set',
            '<comp name="VEVENT" xmlns="urn:ietf:params:xml:ns:caldav"/>',
            1001);

`flat` ;dav_name

カレンダーのパスを入れます。末尾の'/'まで必要です。

;property_name

'urn
ietf:params:xml:ns:caldav:supported-calendar-component-set'と入れます。

;property_value

リマインダーの場合は"VEVENT"の部分を"VTODO"にします。iOSではカレンダーとリマインダーを1つのパスに纏める事はできないようです。

;changed_by

上で調べた"foo"のユーザID(user_no)を入れます。

もう一つ登録します。こちらは不要かも。

davical=> INSERT INTO property (dav_name, property_name, property_value, changed_by)
    VALUES ('/foo/calendar/',
            'urn:ietf:params:xml:ns:caldav:schedule-calendar-transp',
            '<transparent xmlns="urn:ietf:params:xml:ns:caldav"/>',
            1001);

必要なカレンダーについて、上記プロパティの登録を繰り返します。

デフォルトカレンダーの設定

ついでに、ユーザを作成した時のデフォルトカレンダーに上記プロパティを設定するようにしてしまいます。

まず、http://www.inf-it.com/davical/ からパッチをダウンロードして適用します。tar ballをダウンロードして全て置き換えても良いのですが、ここでは最低限必要な、caldav_functions-fix2.sqlauth-functions.php-new.diff だけを適用する方法を説明します。コマンド等はFreeBSDのものですので、Linuxの場合は適宜読み替えて下さい。

caldav_functions-fix2.sqlを使ってデータベースを更新します。
# cd /tmp
# fetch http://www.inf-it.com/fixes/caldav_functions-fix2.sql
# psql davical davical_dba < /tmp/caldav_functions-fix2.sql
DROP TRIGGER
CREATE FUNCTION
CREATE TRIGGER
# rm /tmp/caldav_functions-fix2.sql

このSQLによる修正で、カレンダー(collection)の名前を変えたり削除した時にプロパティも追従するようになります。

次に、auth-functions.php-new.diffパッチをあてます。

# cd /tmp
# fetch http://www.inf-it.com/fixes/auth-functions.php-new.diff
# cd /usr/local/www/davical/inc
# patch < /tmp/auth-functions.php-new.diff
Hmm...  Looks like a unified diff to me...
The text leading up to this was:
--------------------------
|--- auth-functions.php-prev	2013-04-01 13:05:41.555171005 +0200
|+++ auth-functions.php	2013-04-01 16:00:58.215171001 +0200
--------------------------
Patching file auth-functions.php using Plan A...
Hunk #1 succeeded at 118.
done
# rm /tmp/auth-functions.php-new.diff

これでデフォルトのカレンダーに 'urn:ietf:params:xml:ns:caldav:supported-calendar-component-set'プロパティが付くようになります。

最後に、iOSではカレンダーやリマインダーが存在しないと'7365D312-0692-48CD-96A1-422D16B33305'のようなランダム(?)な名前でカレンダーを作成してしまうので、デフォルトでカレンダー(/foo/calendar/)とリマインダー(/foo/todo/)を作るように、/usr/local/www/davical/config/config.php の末尾に以下の内容を追加します。

$c->default_collections=array(
array(
'type'=>'calendar',
'name'=>'calendar',
'displayname'=>'%fn Calendar',
'calendar_components'=>array('VEVENT'),
'default_properties'=>array('urn:ietf:params:xml:ns:caldav:schedule-calendar-transp' => '<transparent xmlns="urn:ietf:params:xml:ns:caldav"/>'),
'privileges'=>null
),
array(
'type'=>'calendar',
'name'=>'todo',
'displayname'=>'%fn ToDo',
'calendar_components'=>array('VTODO'),
'default_properties'=>array('urn:ietf:params:xml:ns:caldav:schedule-calendar-transp' => '<transparent xmlns="urn:ietf:params:xml:ns:caldav"/>'),
'privileges'=>null
),
array(
'type'=>'addressbook',
'name'=>'addresses',
'displayname'=>'%fn addressbook',
'default_properties'=>null,
'privileges'=>null
)
);

上の例ではDAViCalのデフォルトに習ってアドレス帳も作成していますが、手元の環境ではCardDAVサーバとしてはうまくアクセスできませんでした。

[おまけ] IMAP認証を使ってユーザを自動登録する

config.phpに以下の記述を追加すると認証にIMAPを使い、ユーザを自動登録するようになります。

$c->authenticate_hook['call'] = 'RIMAP_check';
$c->authenticate_hook['config'] =  array(
  'imap_url' => '{localhost:993/imap/ssl/novalidate-cert/readonly}',
  'email_base' => 'example.com'
);

include('drivers_rimap.php');

$c->authenticate_hook['optional'] = true;

`flat` ;imap_url

[[imap_open()|http
//php.net/manual/ja/function.imap-open.php]]関数に渡すメールボックス名を入れます

;email_base

メールアドレスのドメインを入れます

最後の行はIMAP認証に失敗したらDAViCalのローカルユーザ認証にフォールバックするための設定です。