Ticket #171: iCal.pm.txt

Line 
1 package Plagger::Plugin::Publish::iCal;
2 use strict;
3 use base qw(Plagger::Plugin);
4 use File::Spec;
5 use Date::ICal;
6 use Data::ICal;
7 use Data::ICal::Entry::Event;
8
9 sub register {
10     my($self, $context) = @_;
11     $context->register_hook(
12         $self,
13         'publish.feed' => \&publish_feed,
14     );
15     $self->init_feed($context);
16 }
17
18 sub init_feed {
19     my($self, $context) = @_;
20
21     my $dir = $self->conf->{dir};
22     unless (-e $dir && -d _) {
23         mkdir $dir, 0755 or $context->error("Failed to mkdir $dir: $!");
24     }
25 }
26
27 sub publish_feed {
28     my($self, $context, $args) = @_;
29     my $feed = $args->{feed};
30     my $ical = Data::ICal->new;
31     $ical->add_properties(
32         'X-WR-CALNAME'  => $feed->title,
33     );
34
35     for my $entry ($feed->entries) {
36         my $date = $entry->date;
37         my $event = Data::ICal::Entry::Event->new;
38         $event->add_properties(
39             summary     => $entry->title,
40             description => $entry->summary || $entry->body,
41             dtstart     => join('', split('-', $date->ymd)),
42             dtend       => join('', split('-', Plagger::Date->from_epoch(epoch => $date->epoch + 60*60*24)->ymd)),
43         );
44         $ical->add_entry($event);
45     }
46
47     my $filepath = File::Spec->catfile($self->conf->{dir}, $self->gen_filename($feed));
48     my $data = $ical->as_string;
49     utf8::decode($data) unless utf8::is_utf8($data);
50
51     open my $output, ">:utf8", $filepath or $context->error("$filepath: $!");
52     print $output $data;
53     close $output;
54
55     $context->log(info => "Wrote iCalendar file to $filepath");
56 }
57
58 my %formats = (
59     'u' => sub { my $s = $_[0]->url;  $s =~ s!^https?://!!; $s },
60     'l' => sub { my $s = $_[0]->link; $s =~ s!^https?://!!; $s },
61     't' => sub { $_[0]->title },
62     'i' => sub { $_[0]->id },
63 );
64
65 my $format_re = qr/%(u|l|t|i)/;
66
67 sub gen_filename {
68     my($self, $feed) = @_;
69
70     my $file = $self->conf->{filename} || '%i.ics';
71     $file =~ s{$format_re}{
72         $self->safe_filename($formats{$1}->($feed))
73     }egx;
74     $file;
75 }
76
77 sub safe_filename {
78     my($self, $path) = @_;
79     $path =~ s![^\w\s]+!_!g;
80     $path =~ s!\s+!_!g;
81     $path;
82 }
83
84 1;
85