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

Revision 304 (checked in by naoya, 15 years ago)

add Publish::CSV and Filter::Hatena

Line 
1 package Plagger::Plugin::Publish::CSV;
2 use strict;
3 use warnings;
4 use base qw ( Plagger::Plugin );
5
6 our $VERSION = 0.02;
7
8 use Encode;
9 use File::Spec;
10 use Text::CSV_PP;
11 use IO::File;
12
13 sub register {
14     my ($self, $context) = @_;
15     $context->register_hook(
16         $self,
17         'publish.feed' => \&feed,
18     );
19 }
20
21 sub feed {
22     my ($self, $context, $args) = @_;
23     my $csv = Text::CSV_PP->new({ binary => 1 });
24     my $append = ($self->conf->{mode} && $self->conf->{mode} eq 'append');
25     my $dir = $self->conf->{dir};
26     unless (-e $dir && -d _) {
27         mkdir $dir, 0755 or $context->error("mkdir $dir: $!");
28     }
29
30     my $file = $self->gen_filename($args->{feed}) || $args->{feed}->id . ".csv";
31     my $path = File::Spec->catfile($dir, $file);
32     my $io = IO::File->new($append  ? ">> $path" : "> $path");
33
34     my $columns = $self->conf->{column} || [qw(title permalink)];
35     for my $entry ($args->{feed}->entries) {
36         my $st = $csv->combine(map { $entry->$_ } @$columns);
37         $context->log(error => $self->convert($csv->error_input)) unless $st;
38         $io->printf("%s\n", $self->convert($csv->string)) if $st;
39     }
40
41     $context->log(
42         info => sprintf(
43             "%s to %s: %d entries",
44             $append ? 'Append' : 'Write',
45             $path,
46             $args->{feed}->count
47         )
48     );
49 }
50
51 sub convert {
52     my ($self, $str) = @_;
53     utf8::decode($str) unless utf8::is_utf8($str);
54     return encode($self->conf->{encoding} || 'utf8', $str);
55 }
56
57 my %formats = (
58     'u' => sub { my $s = $_[0]->url;  $s =~ s!^https?://!!; $s },
59     'l' => sub { my $s = $_[0]->link; $s =~ s!^https?://!!; $s },
60     't' => sub { $_[0]->title },
61     'i' => sub { $_[0]->id },
62 );
63
64 my $format_re = qr/%(u|l|t|i)/;
65
66 sub gen_filename {
67     my($self, $feed) = @_;
68
69     my $file = $self->conf->{filename} || '';
70     $file =~ s{$format_re}{
71         $self->safe_filename($formats{$1}->($feed))
72     }egx;
73
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
86 __END__
87
88 =head1
89
90 Plagger::Plugin::Publish::CSV - Publish feeds as CSV
91
92 =head1 SYNOPSYS
93
94   - module: Publish::CSV
95     config:
96       dir: /var/web/csv
97       encoding: euc-jp
98       filename: my_%t.csv
99       mode: append
100       column:
101        - title
102        - permalink
103
104 =head1 CONFIG
105
106 =head2 dir
107
108 Directory to save csv files in.
109
110 =head2 filename
111
112 Filename to be used to create csv files. It defaults to C<%i.csv>. It
113 supports the following format like printf():
114
115 =over 4
116
117 =item * %u url
118
119 =item * %l link
120
121 =item * %t title
122
123 =item * %i id
124
125 =back
126
127 =head2 mode
128
129 Specify 'append' if you want to append entries to an existing file
130 rather than creating a new file.
131
132 =head2 column
133
134 Chose the columns of entry which you want to write to the csv. It
135 defaults to title and permalink.
136
137 =head1 AUTHOR
138
139 Naoya Ito E<lt>naoya@bloghackers.netE<gt>
140
141 =head1 SEE ALSO
142
143 L<Plagger>, L<Text::CSV_PP>
144
145 =cut
Note: See TracBrowser for help on using the browser.