Plagger::Event

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);
 }

trac のチェンジセットはこちら

追記
floating になってるのは こういう理由がある ということで、CustomFeed::AmazonWebService の方で global: timezone の値を見て、set_time_zone するように修正しました