2011年10月24日月曜日

Aipo と Google カレンダー連携

後日追記: 全部 perl で書き換えました→こちら
------
某所で Aipo というグループウェアが使用されていて,他の人はこれで予定を管理している人が多いんだけど,個人的には Android で予定管理したいので Google カレンダーに予定を入れている.で,Aipo に入れた予定を自動的に Google カレンダーに反映したいんだけど,それらしいことを一発でできるソリューションは今のとこ無いみたい.

で,ふと思いついたのは,Aipo に予定を入れると関係する人にメールが飛ぶようになっているので,このメールをトリガに Google カレンダーに予定を追加できるんじゃね? と思って,自作プログラムから Google カレンダーを操作できる API を探してみたら,本家 Google が API・ライブラリ等を公開してた.

だけど今回は,もっと手軽にコマンドラインから Google カレンダーを操作できる gcalcli というプログラムを使ってみた.
iCal というスケジュール内容が記述されたファイルを gcalcil に食わせれば Google カレンダーに予定が追加できる.あとは,メール内容から iCal を生成するスクリプトを作成し,Aipo メールを受信したらメーラからそのスクリプトを kick すればよい.

gcalcil は python スクリプトなので,cygwin 上で動作させることにする.
gcalcil 以外に python モジュールの gdata.calendar.service, dateutil.tz, setuptools もインストールした (ここは適宜怒られたら足りないものをインストールする).

iCal 生成スクリプトはこんな感じ.
#!/usr/bin/perl -w

use jcode;
use Time::Local;

# 必要なら適当に python 用 proxy の設定.
$ENV{ 'http_proxy'  } = 'http://hoge.hoge:8080';
$ENV{ 'https_proxy' } = 'https://hoge.hoge:8080';

# stdin を全部読み込んでいったん EUC に変換
$_ = join( '', <> );
Jcode::convert( \$_, 'euc' );
@_ = split( /\x0D*\x0A/, $_ );

# メールのパース

$Summery =
$Location =
$Description = '';

$DateStart = $DateEnd = ':';

while( $#_ >= 0 ){
    $_ = shift( @_ );
    
    if( $_ eq '[予定]' ){
        $Summery = shift( @_ );
    }elsif( $_ eq '[日時]' ){
        $_ = shift( @_ );
        if( m#(\d+)/(\d+)/(\d+)\s+(\d+):(\d+)~(\d+):(\d+)# ){
            # 時間指定あり
            $DateStart = timelocal(
                0, $5, $4,
                $3, $2 - 1, $1
            );
            ( $Sec, $Min, $Hour, $Day, $Mon, $Year ) =
                localtime( $DateStart - 9 * 3600 );
            $DateStart = sprintf(
                ":%4d%02d%02dT%02d%02d%02dZ",
                $Year + 1900, $Mon + 1, $Day, $Hour, $Min, $Sec
            );
            
            $DateEnd = timelocal(
                0, $7, $6,
                $3, $2 - 1, $1
            );
            ( $Sec, $Min, $Hour, $Day, $Mon, $Year ) =
                localtime( $DateEnd - 9 * 3600 );
            $DateEnd = sprintf(
                ":%4d%02d%02dT%02d%02d%02dZ",
                $Year + 1900, $Mon + 1, $Day, $Hour, $Min, $Sec
            );
        }elsif( m#(\d+)/(\d+)/(\d+)# ){
            # 時間指定なし
            $DateStart = sprintf( ";VALUE=DATE:%04d%02d%02d", $1, $2, $3 );
            
            $DateEnd = timelocal(
                0, 0, 0,
                $3, $2 - 1, $1
            );
            ( undef, undef, undef, $Day, $Mon, $Year ) =
                localtime( $DateEnd + 24 * 3600 );
            $DateEnd = sprintf(
                ";VALUE=DATE:%04d%02d%02d",
                $Year + 1900, $Mon + 1, $Day
            );
        }else{
            # よくわからない時間指定,とりあえず無視
        }
        
    }elsif( $_ eq '[場所]' ){
        $Location = shift( @_ );
    }elsif( $_ eq '[内容]' ){
        while( $#_ >= 0 ){
            $_ = shift( @_ );
            last if( $_ =~ /^\[/ );
            
            $Description .= '\n' if( $Description ne '' );
            $Description .= $_;
        }
    }
}

# iCalender 本文
$_ = << "EOF";
BEGIN:VCALENDAR
VERSION:2.0
BEGIN:VEVENT
DTSTART$DateStart
DTEND$DateEnd
DESCRIPTION:$Description
LOCATION:$Location
SEQUENCE:0
STATUS:CONFIRMED
SUMMARY:$Summery
TRANSP:OPAQUE
END:VEVENT
END:VCALENDAR
EOF

Jcode::convert( \$_, 'utf8' );
s/\x0A/\x0D\x0A/g;

$TmpFile = "/tmp/aipo2gcal$$.ics";
open( fpOut, "> $TmpFile" );
print fpOut $_;
close( fpOut );

system( "/home/hoge/bin/gcalcli import $TmpFile" );
unlink( $TmpFile );
メーラのフィルタリング設定等で,Aipo メールがきたらこのスクリプトを kick するよう設定することで,Aipo スケジュールが Google カレンダーに自動的に追加されるようになった.

…とおもったら,色々と問題が.
Aipo に自分で予定を入れると,自分にはメールが飛ばない仕様なので,人が入れた予定しか自分の Google カレンダーに反映できないw これに関しては,メアドが自分と同じ別のアカウントをもう一人作ってもらい,その人もスケジュールのメンバに加えることで解決.
あと Aipo で予定を修正する毎に Google カレンダーに予定が追加されていくw これはスクリプトを改良すれば何とかなるかもしれない.

0 件のコメント:

コメントを投稿