File Coverage

blib/lib/SoggyOnion/Plugin/RSS.pm
Criterion Covered Total %
statement 22 24 91.6
branch n/a
condition n/a
subroutine 8 8 100.0
pod n/a
total 30 32 93.7


line stmt bran cond sub pod time code
1             package SoggyOnion::Plugin::RSS;
2 1     1   5 use warnings;
  1         2  
  1         26  
3 1     1   5 use strict;
  1         1  
  1         33  
4 1     1   6 use base qw( SoggyOnion::Plugin );
  1         2  
  1         109  
5              
6             our $VERSION = '0.04';
7              
8 1     1   5 use Template;
  1         1  
  1         33  
9 1     1   4 use constant TEMPLATE_FILE => 'rss.tt2';
  1         2  
  1         198  
10              
11 1     1   864 use LWP::Simple qw(get head $ua);
  1         151366  
  1         12  
12 1     1   422 use constant MOD_TIME => 2;
  1         3  
  1         88  
13              
14 1     1   803 use XML::RSS;
  0            
  0            
15             use HTML::Strip;
16              
17             our $DEFAULT_MAXLEN;
18              
19             sub init {
20              
21             # set our useragent to be nice
22             $ua->agent( SoggyOnion->useragent );
23              
24             # set default maximum length using global option
25             $DEFAULT_MAXLEN = SoggyOnion->options->{maxlen}
26             if not defined $DEFAULT_MAXLEN
27             && not defined SoggyOnion->options->{maxlen};
28             }
29              
30             # try getting the modification time of the RSS feed from the web server.
31             # if we can't, just return the current time to make sure the feed is
32             # processed.
33             sub mod_time {
34             my $self = shift;
35             my $mtime = [ head( $self->{rss} ) ]->[MOD_TIME];
36             return $mtime || time; # in case no modification time is available
37             }
38              
39             sub content {
40             my $self = shift;
41              
42             # get the feed
43             my ( $rss, $xml );
44             eval {
45             $xml = get( $self->{rss} );
46             $rss = XML::RSS->new;
47             $rss->parse($xml);
48             };
49             die $@ if $@;
50              
51             # honor maxlen
52             my $maxlen =
53             defined $DEFAULT_MAXLEN ? $DEFAULT_MAXLEN
54             : defined $self->{maxlen} ? $self->{maxlen}
55             : 0;
56              
57             # honor limit option
58             @{ $rss->{items} } = splice( @{ $rss->{items} }, 0, $self->{limit} )
59             if $self->{limit};
60              
61             # honor strip-html option (after limiting items)
62             my $allow_html
63             = ( exists $self->{html} && $self->{html} =~ /^(0$|n)/i ) ? 0 : 1;
64              
65             # create stripped html, should do entities conversion so that we don't have
66             # any quotes or brackets in the title
67             my $hs = HTML::Strip->new;
68             map {
69              
70             # create HTML-less version of descriptions
71             $_->{stripped_description} = $hs->parse( $_->{description} );
72              
73             # shorten it if asked to
74             $_->{stripped_description}
75             = substr( $_->{stripped_description}, 0, $maxlen )
76             if $maxlen;
77              
78             } @{ $rss->{items} } unless $allow_html;
79              
80             # honor show-description option
81             my $show_descriptions = ( exists $self->{descriptions}
82             && $self->{descriptions} =~ /^(0$|n)/i ) ? 0 : 1;
83              
84             # trim description if needed
85             map {
86             $_->{description} = substr( $_->{description}, 0, $maxlen );
87              
88             } @{ $rss->{items} } if $maxlen;
89              
90             # honor icon
91             if ( defined $self->{icon} ) {
92             $rss->{image}{url} = $self->{icon};
93             $rss->{image}{link} = $rss->{channel}{link}
94             unless $rss->{image}{link};
95             }
96              
97             # run it through our template
98             my $tt
99             = Template->new( INCLUDE_PATH => SoggyOnion->options->{templatedir} )
100             or die "couldn't create Template object\n";
101             my $output;
102             $tt->process(
103             TEMPLATE_FILE,
104             { %$rss,
105             allow_html => $allow_html,
106             show_descriptions => $show_descriptions,
107             },
108             \$output
109             )
110             or die $tt->error;
111             return $output;
112             }
113              
114             1;
115              
116             __END__