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 するように修正しました。