理系学生日記

おまえはいつまで学生気分なのか

忍者TOOLS

IT 勉強会カレンダーを iCal でちょっと使い易くする

IT 勉強会カレンダーにはぼくもお世話になっています。ぼくはこのカレンダーを iCal に登録している。ところが、iCal だとちょっと困ったことが起こってしまいます。

勉強会カレンダーには、その勉強会に関する URL まで配信してくれていますが、iCal ではこの URL にリンクを張ってくれません。

これはなぜかというと、URL の情報が、Description プロパティで配信されてしまってるからです。iCal だと、Description プロパティはメモ欄になるみたいで、これじゃイチイチ URL をコピペしてブラウザに貼り付けないといけない。。
iCalendar を定義している RFC2445 では、Description プロパティの目的を以下のように示しています。(勝手に訳した)

目的:
このプロパティは "SUMMARY" プロパティよりも完全なカレンダーコンポーネントの説明を提供します

本来、この URL が提供されるべきは URL プロパティだと思うのですよ。

目的:
このプロパティは、iCalendar オブジェクトに関連した URL を定義する

というわけで、Description プロパティの値を URL プロパティに設定してあげれば良い。

hakobe さんが一年前に IT 勉強会用のスクリプトを作られてた(IT勉強会カレンダーをフィルター - はこべブログ ♨)ので、それを基に(ていうか上記の処理を加えただけ)こんなのを作ります。

use strict;
use warnings;
use URI::Fetch;
use Data::ICal;
use utf8;
use Encode;

my $CAL_URL = 'http://www.google.com/calendar/ical/fvijvohm91uifvd9hratehf65k%40group.calendar.google.com/public/basic.ics';

my $res = URI::Fetch->fetch( $CAL_URL ) or die URI::Fetch->errstr;
my $ical = Data::ICal->new( data => decode_utf8( $res->content ) );
die $ical->error_message if ref( $ical ) eq 'Class::ReturnValue';

my $entries = $ical->entries;
$ical->{entries} = [];
for my $entry (@$entries) {

    if ( $entry->property( 'description' ) ) {
        $entry->add_property( url => [
            $entry->property( 'description' )->[0]->value,
            { value => 'URI' }
        ]);
        $entry->add_property( description => undef );
    }

    my $summaries = $entry->property('summary');
    unless ($summaries) {
        $ical->add_entry( $entry );
    }
    else {
        my $summary = $summaries->[0];
        $ical->add_entry( $entry ) if $summary->value =~ /(?:東京|筑波|オンライン|千葉)/;
    }
}
my $output = $ical->as_string;
print encode( 'utf-8', $output );

これで生成された iCalendar のデータを iCal に読み込ませるとこんな感じ。

ちゃんと URL 欄にリンクが張られてることがわかります。やったね!