root/trunk/plagger/lib/Plagger/Plugin/Publish/CHTML.pm

Revision 943 (checked in by miyagawa, 14 years ago)

defaults to cp932 would be better

Line 
1 package Plagger::Plugin::Publish::CHTML;
2 use strict;
3 use base qw( Plagger::Plugin );
4
5 use Encode;
6 use Digest::MD5 qw(md5_hex);
7 use File::Path;
8
9 sub register {
10     my($self, $context) = @_;
11     $context->register_hook(
12         $self,
13         'publish.feed' => \&feed,
14         'publish.finalize' => \&finalize,
15     );
16     $self->chtml_init($context);
17 }
18
19 sub chtml_init {
20     my ($self, $context) = @_;
21     $self->{context} = $context;
22     $self->conf->{encoding} ||= 'cp932';
23     $self->{id} = time;
24     @{$self->{feeds}} = ();
25     unless ($self->conf->{work}) {
26         $context->error("Can't parse value in work");
27     }
28     $self->conf->{title} ||= __PACKAGE__;
29     $self->conf->{mobile_gw} = undef unless $self->conf->{mobile_gw} =~ m{^https?://.*?/}i;
30 }
31
32 sub id { shift->{id} }
33 sub context { shift->{context} }
34 sub work { shift->conf->{work} }
35
36 sub add {
37     my($self, $feed) = @_;
38     push @{ $self->{feeds} }, $feed;
39 }
40
41 sub feeds {
42     my $self = shift;
43     wantarray ? @{ $self->{feeds} } : $self->{feeds};
44 }
45
46 sub feed {
47     my($self, $context, $args) = @_;
48
49     my $feed = $args->{feed} or return;
50     my $feed_path = $self->work . '/feeds/' . $feed->id;
51     my $publish_path = "$feed_path/" . $self->id;
52
53     mkpath($publish_path);
54     foreach my $entry ($feed->entries) {
55         my $entry_id = md5_hex($entry->permalink);
56         $self->write("$publish_path/$entry_id.html",
57                      $self->entry_templatize($feed, $entry));
58         $entry->{feed2entry_link} = $self->id . "/$entry_id.html";
59     }
60
61     $self->write("$publish_path.html",
62                  $self->feed_templatize($feed, $self->earlier($feed_path)),
63                  "$feed_path/index.html");
64
65     $self->add(+{
66         feed_link => './feeds/' . $feed->id . '/' . $self->id . '.html',
67         title  => $feed->title || '(no-title)',
68         lastdate => $feed->entries->[-1]->date,
69         count => scalar(@{$feed->entries}),
70     });
71 }
72
73 sub finalize {
74     my($self, $context) = @_;
75
76     return unless @{$self->feeds};
77     $self->write($self->work . '/' . $self->id . '.html',
78                  $self->index_templatize($self->earlier($self->work)),
79                  $self->work . '/index.html');
80 }
81
82 sub entry_templatize {
83     my($self, $feed, $entry) = @_;
84     $self->templatize('chtml_entry.tt', {
85         conf => $self->conf,
86         feed => $feed,
87         entry => $entry,
88         strip_html => sub {
89             my $html = shift;
90             $html =~ s|\s{2,}||og;
91             $html =~ s|<[bh]r.*?>|\n|ogi;
92             $html =~ s|<.*?>||og;
93             $html;
94         }});
95 }
96
97 sub feed_templatize {
98     my($self, $feed, $earlier) = @_;
99     $self->templatize('chtml_feed.tt', {
100         conf => $self->conf,
101         feed => $feed,
102         earlier => $earlier,
103     });
104 }
105
106 sub index_templatize {
107     my($self, $earlier) = @_;
108     $self->templatize('chtml_index.tt', {
109         conf => $self->conf,
110         feeds => [ $self->feeds ],
111         earlier => $earlier,
112     });
113 }
114
115 sub templatize {
116     my $self = shift;
117     my $tt = $self->context->template();
118     $tt->process(shift, shift, \my $out) or $self->context->error($tt->error);
119     $out;
120 }
121
122 sub write {
123     my ($self, $file, $chtml, $symlink) = @_;
124     open my $out, ">:encoding($self->{conf}->{encoding})", $file or $self->context->error("$file: $!");
125     local $PerlIO::encoding::fallback = Encode::FB_HTMLCREF;
126     print $out $chtml;
127     close $out;
128     $self->symlink($file, $symlink) if $symlink;
129 }
130
131 sub symlink {
132     my ($self, $old, $new) = @_;
133     unlink $new if -e $new;
134     symlink $old, $new;
135 }
136
137 sub earlier {
138     my ($self, $path) = @_;
139     my $earlier;
140     my $file = "$path/earlier";
141     if (open my $in, $file) {
142         $earlier = <$in>;
143         close $in;
144     }
145     open my $out, ">$file" or $self->context->error("$file: $!");
146     print $out $self->id;
147     close $out;
148     $earlier;
149 }
150 1;
Note: See TracBrowser for help on using the browser.