Amazon2iCal で、本やCDなんかの発売日に Google Calendar でメール通知してもらおうと思って設定したのだけど、Google Calendar が通知してくれない。
これはもしかして、Publish::iCal で生成した iCalendar データに時刻が入ってないせいかな、と思い時刻も入れようと思ったんだけど、どうせなら Plagger::Event とか作って、イベントハンドリングしやすくしてしまえ、ってことで、Plagger::Enclosure の様な感じで作ってみた。たったこれだけだけど。
package Plagger::Event; use strict; use base qw( Plagger::Thing ); __PACKAGE__->mk_accessors(qw( dtstart dtend summary description location organizer )); 1;
Event だと色んな意味があって曖昧な気がするから Plagger::iCal::Event とかの方がいいかな、と思ったけど、とりあえずの実装なのでまあいいか、と。
でもってこれに合わせて Plagger::Entry も修正。
Index: plagger/trunk/lib/Plagger/Entry.pm =================================================================== --- plagger/trunk/lib/Plagger/Entry.pm (revision 238) +++ plagger/trunk/lib/Plagger/Entry.pm (revision 241) @@ -19,4 +19,5 @@ meta => {}, enclosures => [], + events => [], }, $class; } @@ -102,4 +103,24 @@ } +sub add_event { + my($self, $event) = @_; + push @{ $self->{events} }, $event; +} + +sub event { + my $self = shift; + wantarray ? @{$self->{events}} : $self->{events}->[0]; +} + +sub events { + my $self = shift; + wantarray ? @{$self->{events}} : $self->{events}; +} + +sub has_event { + my $self = shift; + scalar @{$self->{events}} > 0; +} + 1;
更にこれに合わせて、Publish::iCal と CustomFeed::AmazonWebService も修正。
Index: plagger/trunk/lib/Plagger/Plugin/Publish/iCal.pm =================================================================== --- plagger/trunk/lib/Plagger/Plugin/Publish/iCal.pm (revision 233) +++ plagger/trunk/lib/Plagger/Plugin/Publish/iCal.pm (revision 241) @@ -35,17 +35,19 @@ for my $entry ($feed->entries) { - my $address = ( Email::Address->parse($entry->author) )[0]; - my $mail = eval { $address->address } || 'nobody@example.com'; - my $name = eval { $address->name } || $entry->author; + my $ev = $entry->event; + my $organizer = $ev ? $ev->organizer : $entry->author; + my $address = ( Email::Address->parse($organizer) )[0]; + my $mail = $address ? $address->address : 'nobody@example.com'; + my $name = $address ? $address->name : $organizer; + my $dtstart = $ev ? $ev->dtstart : $entry->date; + my $dtend = $ev ? $ev->dtend : $entry->date; - my $date = $entry->date; my $event = Data::ICal::Entry::Event->new; $event->add_properties( - summary => $entry->title . ' - ' . $entry->author, - description => $entry->summary || $entry->body, + summary => $ev ? $ev->summary : $entry->title, + description => $ev ? $ev->description : $entry->summary || $entry->body, organizer => [ "MAILTO:$mail", { cn => $name } ], - url => $entry->link, - dtstart => join('', split('-', $date->ymd)), - dtend => join('', split('-', Plagger::Date->from_epoch(epoch => $date->epoch + 60*60*24)->ymd)), + dtstart => Date::ICal->new( epoch => $dtstart->epoch )->ical, + dtend => Date::ICal->new( epoch => $dtend->epoch )->ical, ); $ical->add_entry($event);
--- plagger/trunk/lib/Plagger/Plugin/CustomFeed/AmazonWebService.pm (revision 232) +++ plagger/trunk/lib/Plagger/Plugin/CustomFeed/AmazonWebService.pm (revision 241) @@ -6,4 +6,5 @@ use Net::Amazon::Request::Keyword; use Encode; +use Plagger::Event; sub register { @@ -59,4 +60,11 @@ $entry->date($date); + my $event = Plagger::Event->new; + $event->dtstart($date); + $event->dtend( $date->clone->add( hours => 1 ) ); + $event->summary($entry->title . ' - ' . $entry->author); + $event->organizer($entry->author); + $entry->add_event($event); + $feed->add_entry($entry); } @@ -91,5 +99,5 @@ *Net::Amazon::Property::Music::author = *Net::Amazon::Property::Music::artist; -*Net::Amazon::Property::DVD::author = sub { return ( $_[0]->starring() )[0] }; +*Net::Amazon::Property::DVD::author = sub { return ( $_[0]->starring() )[0] }; 1;
あと、どうも意図したタイムゾーン通りの時刻にならないと思ったら、Plagger::Date::strptime で使われている DateTime::Format::Strptime は、time_zone を指定しないと、floating になってしまうみたい。なので、config.yaml で指定しているタイムゾーンを使うように修正してみました。
Index: plagger/trunk/lib/Plagger/Date.pm =================================================================== --- plagger/trunk/lib/Plagger/Date.pm (revision 240) +++ plagger/trunk/lib/Plagger/Date.pm (revision 241) @@ -42,5 +42,8 @@ my($class, $pattern, $date) = @_; Encode::_utf8_on($pattern); - my $format = DateTime::Format::Strptime->new(pattern => $pattern); + my $format = DateTime::Format::Strptime->new( + pattern => $pattern, + time_zone => Plagger->context->conf->{timezone} || 'local', + ); $class->parse($format, $date); }
追記
floating になってるのは こういう理由がある ということで、CustomFeed::AmazonWebService の方で global: timezone の値を見て、set_time_zone するように修正しました。