File Coverage

blib/lib/CGI/RSS.pm
Criterion Covered Total %
statement 104 118 88.1
branch 19 28 67.8
condition 3 8 37.5
subroutine 21 26 80.7
pod 0 8 0.0
total 147 188 78.1


line stmt bran cond sub pod time code
1              
2             package CGI::RSS;
3              
4 8     8   24393 use strict;
  8         14  
  8         275  
5 8     8   3731 use Date::Manip;
  8         908497  
  8         881  
6 8     8   4272 use AutoLoader;
  8         8356  
  8         33  
7 8     8   20072 use CGI;
  8         94071  
  8         56  
8 8     8   452 use Carp;
  8         12  
  8         566  
9 8     8   40 use Scalar::Util qw(blessed);
  8         11  
  8         568  
10 8     8   38 use base 'Exporter';
  8         9  
  8         665  
11 8     8   31 use vars qw'@TAGS @EXPORT_OK %EXPORT_TAGS';
  8         13  
  8         414  
12              
13 8     8   33 no warnings;
  8         10  
  8         1588  
14              
15             our $VERSION = '0.9659';
16             our $pubDate_format = '%a, %d %b %Y %H:%M:%S %z';
17              
18             # Make sure we have a TZ
19             unless( eval {Date_TimeZone(); 1} ) {
20             $ENV{TZ} = "UTC" if $@ =~ m/unable to determine Time Zone/i;
21             }
22              
23             sub pubDate_format {
24 1     1 0 710 my $class_or_instance = shift;
25 1         2 my $proposed = shift;
26              
27 1         1 $pubDate_format = $proposed;
28 1         2 $pubDate_format
29             }
30              
31             sub grok_args {
32 41 100   41 0 125 my $this = blessed($_[0]) ? shift : __PACKAGE__->new;
33 41 100       71 my $attrs = ref($_[0]) eq "HASH" ? shift : undef;
34              
35 41 100       71 if( ref($_[0]) eq "ARRAY" ) {
36 4         9 return ($this,$attrs,undef,$_[0]);
37             }
38              
39 37         88 return ($this,$attrs,join(" ", @_),undef);
40             }
41              
42             sub setup_tag {
43 264     264 0 213 my $tag = shift;
44              
45             # try to mimick CGI.pm (which is very unfriendly about new tags now)
46              
47 8     8   41 no strict 'refs';
  8         10  
  8         4430  
48              
49 264         464 my @these_tags = ($tag, "start_$tag", "end_$tag");
50              
51 264         309 push @EXPORT_OK, @these_tags;
52 264         145 push @{ $EXPORT_TAGS{all} }, @these_tags;
  264         342  
53 264         200 push @{ $EXPORT_TAGS{tags} }, $tag;
  264         257  
54              
55 264         778 *{ __PACKAGE__ . "::$tag" } = sub {
56 39     39   39998 my ($this, $attrs, $contents, $subs) = grok_args(@_);
57 39         32 my $res;
58              
59 39 100       54 if( $subs ) {
60 4 100       6 $res = join("", map { $this->$tag( ($attrs ? $attrs : ()), $_ ) } @$subs );
  16         34  
61              
62             } else {
63 35         39 $res = "<$tag";
64              
65 35 100       57 if( $attrs ) {
66 10         19 for(values %$attrs) {
67             # XXX: this is a terrible way to do this, better than nothing for now
68 10         19 s/(?
69             }
70              
71 10         18 $res .= " " . join(" ", map {"$_=\"$attrs->{$_}\""} keys %$attrs);
  10         28  
72             }
73              
74 35         55 $res .= ">$contents";
75             }
76              
77 39         136 return $res;
78 264         713 };
79              
80 264         667 *{ __PACKAGE__ . "::start_$tag" } = sub {
81 2     2   5 my ($this, $attrs) = grok_args(@_);
82 2         5 my $res = "<$tag";
83              
84 2 100       3 if( $attrs ) {
85 1         2 for(values %$attrs) {
86             # XXX: this is a terrible way to do this, better than nothing for now
87 1         3 s/(?
88             }
89              
90 1         3 $res .= " " . join(" ", map {"$_=\"$attrs->{$_}\""} keys %$attrs);
  1         4  
91             }
92              
93 2         5 return $res . ">";
94 264         581 };
95              
96 264     0   379 *{ __PACKAGE__ . "::end_$tag" } = sub { "" };
  264         1008  
  0         0  
97             }
98              
99             sub AUTOLOAD {
100 0     0   0 my $this = shift;
101 0         0 our $AUTOLOAD;
102              
103 0 0       0 if( my ($fname) = $AUTOLOAD =~ m/::([^:]+)$/ ) {
104 0 0       0 if( CGI->can($fname) ) {
105 0         0 *{ __PACKAGE__ . "::$fname" } = sub {
106 0     0   0 my $this = shift;
107 0         0 return CGI->$fname(@_);
108             }
109 0         0 }
110              
111             else {
112 0         0 croak "can't figure out what to do with $fname() call";
113             }
114             }
115             }
116              
117             sub new {
118 12     12 0 9520 my $class = shift;
119 12         66 my $this = bless {}, $class;
120              
121 12         29 return $this;
122             }
123              
124             sub date {
125 2     2 0 3 my $this = shift;
126              
127 2 50       4 if( my $pd = ParseDate($_[-1]) ) {
128 2         769 my $date = UnixDate($pd, $pubDate_format);
129 2         728 return $this->pubDate($date);
130             }
131              
132 0         0 $this->pubDate(@_);
133             }
134              
135             sub header {
136 1     1 0 23 my $this = shift;
137              
138 1         2 my $charset = "UTF-8";
139 1         2 my $mime = "application/xml";
140              
141 1         2 eval {
142 8     8   34 no warnings;
  8         8  
  8         1851  
143 1     0   12 local $SIG{WARN} = sub{};
  0         0  
144 1         2 my %opts = @_;
145 1   33     11 $charset = $opts{'-charset'} || $opts{charset} || $charset;
146 1   33     12 $mime = $opts{'-type'} || $opts{type} || (@_==1 && $_[0]) || $mime;
147             };
148              
149 1         6 return CGI::header(-type=>$mime, -charset=>$charset) . "\n\n";
150             }
151              
152             sub begin_rss {
153 1     1 0 970 my $this = shift;
154 1         2 my $opts = $_[0];
155 1 50       4 $opts = {@_} unless ref $opts;
156              
157             # NOTE: This isn't nearly as smart as CGI.pm's argument parsing...
158             # I assume I could call it, but but I'm only mortal.
159              
160 1   50     5 my $ver = $opts->{version} || "2.0";
161 1         5 my $ret = $this->start_rss({version=>$ver});
162 1         5 $ret .= $this->start_channel;
163 1 50       4 $ret .= $this->link($opts->{link}) if exists $opts->{link};
164 1 50       4 $ret .= $this->title($opts->{title}) if exists $opts->{title};
165 1 50       4 $ret .= $this->description($opts->{desc}) if exists $opts->{desc};
166              
167 1         5 return $ret;
168             }
169              
170             sub finish_rss {
171 0     0 0   my $this = shift;
172              
173 0           return $this->end_channel . $this->end_rss;
174             }
175              
176             BEGIN {
177 8     8   35 @TAGS = qw(
178             rss channel item
179              
180             title link description
181              
182             language copyright managingEditor webMaster pubDate lastBuildDate category generator docs
183             cloud ttl image rating textInput skipHours skipDays
184              
185             link description author category comments enclosure guid pubDate source
186              
187             pubDate url
188             );
189              
190 8         23 setup_tag($_) for @TAGS;
191             }
192              
193             1;
194              
195             __END__