root/trunk/plagger/lib/Plagger/Plugin/CustomFeed/Script.pm

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

handle error code in CustomFeed-Script. Refs #412

Line 
1 package Plagger::Plugin::CustomFeed::Script;
2 use strict;
3 use base qw( Plagger::Plugin );
4
5 use URI;
6 use URI::Escape;
7 use YAML;
8
9 use Plagger::Plugin::Aggregator::Simple;
10 use Plagger::Plugin::CustomFeed::Debug;
11
12 sub register {
13     my($self, $context) = @_;
14     $context->register_hook(
15         $self,
16         'customfeed.handle' => \&handle,
17     );
18 }
19
20 sub handle {
21     my($self, $context, $args) = @_;
22
23     if (URI->new($args->{feed}->url)->scheme eq 'script') {
24         $self->aggregate($context, $args);
25         return 1;
26     }
27
28     return;
29 }
30
31 sub aggregate {
32     my($self, $context, $args) = @_;
33
34     my $script = URI->new($args->{feed}->url)->opaque;
35        $script =~ s!^//!!;
36     $script = URI::Escape::uri_unescape($script); # to support script://python.exe foo.py
37
38     $context->log(debug => "Executing '$script'");
39     my $output = qx($script);
40     if ($?) {
41         $context->log(error => "Error happend while executing '$script': $?");
42         return;
43     }
44
45     # TODO: check BOM?
46     if ($output =~ /^<\?xml/) {
47         $context->log(debug => "Looks like output is RSS/Atom");
48         $self->Plagger::Plugin::Aggregator::Simple::handle_feed($args->{feed}->url, \$output, $args->{feed});
49     } else {
50         eval {
51             my $feed = YAML::Load($output);
52             $context->log(debug => "Looks like output is YAML");
53             local $self->{conf} = $feed;
54             $self->Plagger::Plugin::CustomFeed::Debug::aggregate($context, $args);
55         };
56         if ($@) {
57             $context->log(error => "Failed to parse as YAML. Can't determine output format of $script");
58             return;
59         }
60     }
61
62     return 1;
63 }
64
65 1;
66 __END__
67
68 =head1 NAME
69
70 Plagger::Plugin::CustomFeed::Script - Script support for Plagger
71
72 =head1 SYNOPSIS
73
74   - module: Subscription::Config
75     config:
76       feed:
77         - script:/path/to/script.rb
78         - script:/path/to/scrape.py
79   - module: CustomFeed::Script
80
81 =head1 DESCRIPTION
82
83 This plugin executes arbitrary script specified in subscription with
84 I<script:> URI protocol, then parse the STDOUT from the script to
85 create a feed.
86
87 The output from the script can either be Atom/RSS feed, or YAML format
88 which is compatible to the one used in CustomFeed::Debug. This means
89 you can reuse your I<something2rss> script used for NetNewsWire or
90 similar tools, and you can even write your scraper code in other
91 languages like Python/Ruby.
92
93 This plugin auto-detects if the output is XML or YAML.
94
95 =head1 AUTHOR
96
97 Tatsuhiko Miyagawa
98
99 =head1 SEE ALSO
100
101 L<Plagger>
102
103 =cut
Note: See TracBrowser for help on using the browser.