root/trunk/plagger/lib/Plagger/Plugin/Publish/2chdat.pm

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

Fixed syntax error of Publish::2chdat. Escape <>. Thanks to yanagi

Line 
1 package Plagger::Plugin::Publish::2chdat;
2 use strict;
3 use base qw( Plagger::Plugin );
4
5 use Encode;
6 use File::Spec;
7
8 sub register {
9     my($self, $context) = @_;
10     $context->register_hook(
11         $self,
12         'publish.feed' => \&feed,
13         'publish.finalize' => \&finalize,
14     );
15 }
16
17 sub init {
18     my $self = shift;
19     $self->SUPER::init(@_);
20
21     my $dir = $self->conf->{dir};
22     unless (-e $dir && -d _) {
23         mkdir $dir, 0755 or Plagger->context->error("$dir: $!");
24         mkdir File::Spec->catfile($dir, 'dat'), 0755 or Plagger->context->error("$dir/dat: $!");
25     }
26 }
27
28 sub feed {
29     my($self, $context, $args) = @_;
30
31     my $feed = $args->{feed};
32     my $out  = File::Spec->catfile($self->conf->{dir}, 'dat', $feed->id_safe . ".dat");
33     $context->log(info => "Writing dat output to $out");
34
35     my $anonymous = decode("utf-8", $self->conf->{default_anonymous} || "名無しさん");
36
37     open my $fh, ">:encoding(shift_jis)", $out or $context->error("$out: $!");
38     printf $fh "%s<><>%s ID:%s<> %s<>%s\n",
39         ($feed->author || $feed->entries->[0]->author || $anonymous),
40         $self->format_date( Plagger::Date->from_epoch(0) ), # Fix created date to handle bytes-range request
41         substr($feed->id_safe, 0, 8),
42         $self->format_body($feed->description) . "<BR>" . $feed->link,
43         $feed->title;
44
45     for my $entry (reverse $feed->entries) {
46         printf $fh "%s<><>%s ID:%s<> %s\n",
47             ($entry->author || $anonymous),
48             $self->format_date( $entry->date || Plagger::Date->now ),
49             substr($entry->id_safe, 0, 8),
50             $self->format_body($entry->body) . "<P>" . $entry->link . "</P>";
51     }
52
53     close $fh;
54
55     # update mtime of file with the latest entry
56     if (my $mtime = $feed->entries->[0]->date) {
57         utime $mtime->epoch, $mtime->epoch, $out;
58     }
59 }
60
61 sub finalize {
62     my($self, $context, $args) = @_;
63
64     my $out = File::Spec->catfile($self->conf->{dir}, 'subject.txt');
65     open my $fh, ">:encoding(shift_jis)", $out or $context->erorr("$out: $!");
66     for my $feed ($context->update->feeds) {
67         printf $fh "%s.dat<>%s (%d)\n", $feed->id_safe, $feed->title, $feed->count;
68     }
69 }
70
71 sub format_date {
72     my($self, $date) = @_;
73     my $clone = $date->clone;
74     $clone->set_locale("ja_JP");
75     return $clone->strftime("%Y/%m/%d(%a) %H:%M:%S");
76 }
77
78 sub format_body {
79     my($self, $body) = @_;
80
81     # replace images
82     $body =~ s!<img .*?src="(.*?)".*?>!$1!ig;
83
84     # ad-hoc replacement of A links
85     $body =~ s{<a .*?href="(.*?)".*?>(.*?)</a>}
86               {my($url, $label) = ($1, $2);
87                $label =~ m!^https?://! ? $url : "$label ($url)"}ieg;
88
89     # respect newline in <pre> tags
90     $body =~ s{(<pre>)(.*?)(</pre>)}{$1 . nl2br($2) . $3}seig;
91
92     # other than that, nuke newlines
93     $body =~ tr/\r\n//d;
94
95     # <> is a separator
96     $body =~ s/<>/&lt;&gt;/g;
97
98     $body;
99 }
100
101 sub nl2br {
102     my $str = shift;
103     $str =~ s/\r?\n/<BR>/g;
104     $str;
105 }
106
107 1;
108
109 __END__
110
111 =head1
112
113 Plagger::Plugin::Publish::2chdat - Publish 2ch data files for 2ch browsers
114
115 =head1 SYNOPSYS
116
117   - module: Publish::2chdat
118     config:
119       dir: /home/miyagawa/public_html/2chdat
120
121 =head1 DESCRIPTION
122
123 This plugin publishes feed updates as 2ch browser compatible data
124 files e.g. C<subject.txt> and C<*.dat> files.
125
126 Note that this plugin might not work very well with Subscription
127 plugins that manages unread management, e.g. Bloglines and Livedoor
128 Reader.
129
130 =head1 CONFIG
131
132 =head2 dir
133
134 Directory to save data files in.
135
136 =head1 AUTHOR
137
138 Tatsuhiko Miyagawa
139
140 =head1 SEE ALSO
141
142 L<Plagger>, L<http://age.s22.xrea.com/talk2ch/>
143
144 =cut
Note: See TracBrowser for help on using the browser.