2006/10/15 (日)
■ Publish::iCal とタイムゾーン

Publish::iCal のスケジュールは全部 localtime で出していたので、修正中。403 Forbidden に iCal の日付仕様があり、Olson の名前 ("Asia/Tokyo" とか)を TZID= でつければいいっぽいので、こういうパッチを書いたんだけど、
=== lib/Plagger/Plugin/Publish/iCal.pm
==================================================================
--- lib/Plagger/Plugin/Publish/iCal.pm (revision 5590)
+++ lib/Plagger/Plugin/Publish/iCal.pm (local)
@@ -40,12 +40,16 @@
my $event = Data::ICal::Entry::Event->new;
my($dtstart, $dtend);
+ my %param;
+ if (!$date->time_zone->is_floating && $date->time_zone->name ne 'UTC') {
+ $param{TZID} = $date->time_zone->name;
+ }
if ($date->hms eq '00:00:00') {
- $dtstart = [ $date->strftime('%Y%m%d'), { VALUE => 'DATE' } ];
- $dtend = [ $date->strftime('%Y%m%d'), { VALUE => 'DATE' } ];
+ $dtstart = [ $date->strftime('%Y%m%d'), { %param, VALUE => 'DATE' } ];
+ $dtend = [ $date->strftime('%Y%m%d'), { %param, VALUE => 'DATE' } ];
} else {
- $dtstart = $date->strftime('%Y%m%dT%H%M%S');
- $dtend = $date->strftime('%Y%m%dT%H%M%S');
+ $dtstart = [ iso8691_full($date), \%param ];
+ $dtend = [ iso8691_full($date), \%param ];
}
$event->add_properties(
@@ -70,6 +74,12 @@
$context->log(info => "Wrote iCalendar file to $path");
}
+sub iso8691_full {
+ my $date = shift;
+ my $iso = $date->strftime('%Y%m%dT%H%M%S');
+ $iso .= $date->time_zone->name eq 'UTC' ? 'Z' : '';
+ $iso;
+}
1;
__END__
うまく TZID=Asia/Tokyo にはならなくて、TZID=+0900 になってしまう。CustomFeed::Script で日付をやりとりするときに W3CDTF 形式をつかっているので、現在の時差 (+0900) しかやりとりできないのだ。 JST みたいな名前で渡せればいいんだけど、Date::Parse::strptime() する段階 (Plagger::Date->parse_dwim) でタイムゾーン情報は落ちてしまう。悩ましい。。
いっそ CustomFeed::Script の段階では floating のままでやりとりしておいて、Filter::GuessTimeZoneByDomain とか Filter::FloatingDateTime で Asia/Tokyo にしてしまう、という手もある。そのほうがシンプルかなあ。
http://plagger.org/trac/changeset/1761
というわけで、そのようにした。新しく Filter::ForceTimeZone というプラグインを追加。TZ があるなし、UTC かどうかにかかわらず、すべての日付をシステムで設定した timezone にセットする。Filter::FloatingDateTime は floating のものだけをするのに対し、こちらはすべて。
これで、
- module: Filter::ForceTimeZone
config:
timezone: Asia/Tokyo
を追加して (timezone は global: の下でもよいし、なければ local の tzinfo を見る)、iCal に
DTSTART;TZID=Asia/Tokyo:20061015T180000
が追加された。
と、思ったんだけど +0900 みたいに時差しかないときは、UTC に変換して Z つければいいんだな。Google Calendar の場合、floating だと PST と仮定、UTC ならちゃんとハンドルしてくれるはず。この辺の処理は DateTime::Format::ICal がこれやってくれるっぽい。もちろん UTC がやなら Filter::ForceTimeZone とかで。
■ [Plagger] TV 番組表を iCal で
![はてなブックマーク - [Plagger] TV 番組表を iCal で - Bulknews::Subtech はてなブックマーク - [Plagger] TV 番組表を iCal で - Bulknews::Subtech](http://b.hatena.ne.jp/entry/image/http://subtech.g.hatena.ne.jp/miyagawa/20061015/1160897367)
WOWOW の HV/5.1ch 番組表、リーガエスパニョーラ, JSPORTS の海外サッカー を Plagger で iCal にしてみた。
スクリプトはとりあえず svn の assets/plugins/CustomFeed-Script 以下にいれてある。
plugins:
- module: Subscription::Config
config:
feed:
- script:assets/plugins/CustomFeed-Script/wowow-hv-51ch.pl
- script:assets/plugins/CustomFeed-Script/wowow-liga-espanola.pl
- script:assets/plugins/CustomFeed-Script/jsports-football.pl
- module: CustomFeed::Script
- module: Filter::TagsToTitle
config:
add_to: right
- module: Publish::iCal
config:
dir: /home/miyagawa/public_html/ical
filename: %t.ics
出来上がった ics ファイルは http://plagger.org/ical/ においてある。URL は変わるかもだけど、Google Calendar にも入れてあります。
- WOWOW HV / 5.1ch programs
- WOWOW �������������������������������&
- JSPORTS �������������������������������
いくつかメモ。
- Publish::iCal の現在の仕様上、終了時間がいれられないので Day View とかで見にくい。body に microformats の hCalendar でいれるようにしたい。00:00開始の番組が終日イベント扱いになっているのも同様の制約。
- %t.ics ではいているが、生成されるファイル名が UTF-8 になっている。UNIX でつくって Apache でサーブする分には問題ないみたいだけど、あまりよくはなさそう。filename_for の \w が utf-8 のマルチバイトにもマッチするのが問題か。
- チャンネルや "HV", "5.1ch", リーグ名などは tags に入れるようにして、Filter::TagsToTitle でタイトルに追加するようにした。こうすれば Rule を書いて「チャンピオンズリーグだけのカレンダー」とかつくることができる、はず。
- 2ch のスレでも EFT/CustomFeed::Config の管理が話題になっているけど、こういう野良っぽいスクレイプツールをどうやって管理するかは今後の課題。
- JSPORTS フィードのタグが化けているがこれは修正済み。Google Calendar に強制的にリフェッチさせるのはどうしたらいいんだろ。
