Merge pull request #5 from nichtich/master
[catagits/XML-Feed.git] / lib / XML / Feed / Format / RSS.pm
CommitLineData
3353d70c 1# $Id$
0d5e38d1 2
729cd7a8 3package XML::Feed::Format::RSS;
0d5e38d1 4use strict;
5
6use base qw( XML::Feed );
0d5e38d1 7use DateTime::Format::Mail;
8use DateTime::Format::W3CDTF;
723eaa15 9use XML::Atom::Util qw(iso2dt);
7b5fccb1 10use XML::Feed::Enclosure;
8c43fc54 11use XML::Feed::Entry::Format::RSS;
0d5e38d1 12
973e1f9e 13our $PREFERRED_PARSER = "XML::RSS";
14
9b6bc912 15
16sub identify {
17 my $class = shift;
18 my $xml = shift;
19 my $tag = $class->_get_first_tag($xml);
20 return ($tag eq 'rss' || $tag eq 'RDF');
21}
22
973e1f9e 23sub init_empty {
4e9c4625 24 my ($feed, %args) = @_;
25 $args{'version'} ||= '2.0';
973e1f9e 26 eval "use $PREFERRED_PARSER"; die $@ if $@;
4e9c4625 27 $feed->{rss} = $PREFERRED_PARSER->new(%args);
fe3b3201 28 $feed->{rss}->add_module(prefix => "content", uri => 'http://purl.org/rss/1.0/modules/content/');
813f78d8 29 $feed->{rss}->add_module(prefix => "dcterms", uri => 'http://purl.org/dc/terms/');
9a36f82c 30 $feed->{rss}->add_module(prefix => "atom", uri => 'http://www.w3.org/2005/Atom');
31 $feed->{rss}->add_module(prefix => "geo", uri => 'http://www.w3.org/2003/01/geo/wgs84_pos#');
973e1f9e 32 $feed;
33}
34
0d5e38d1 35sub init_string {
36 my $feed = shift;
37 my($str) = @_;
973e1f9e 38 $feed->init_empty;
b1aa7a62 39 my $opts = {
40 hashrefs_instead_of_strings => 1,
41 };
42 $opts->{allow_multiple} = [ 'enclosure' ] if $XML::Feed::MULTIPLE_ENCLOSURES;
0d5e38d1 43 if ($str) {
b1aa7a62 44 $feed->{rss}->parse($$str, $opts );
0d5e38d1 45 }
46 $feed;
47}
48
49sub format { 'RSS ' . $_[0]->{rss}->{'version'} }
50
51## The following elements are the same in all versions of RSS.
973e1f9e 52sub title { shift->{rss}->channel('title', @_) }
710ed823 53sub link {
54 my $link = shift->{rss}->channel('link', @_);
55 $link =~ s/^\s+//;
56 $link =~ s/\s+$//;
57 return $link;
58}
973e1f9e 59sub description { shift->{rss}->channel('description', @_) }
e23387f1 60sub updated { shift->modified(@_) }
0d5e38d1 61
813f78d8 62# This doesn't exist in RSS
63sub id { }
64
0d5e38d1 65## This is RSS 2.0 only--what's the equivalent in RSS 1.0?
973e1f9e 66sub copyright { shift->{rss}->channel('copyright', @_) }
0d5e38d1 67
5383a560 68sub base {
69 my $feed = shift;
70 if (@_) {
71 $feed->{rss}->{'xml:base'} = $_[0];
72 } else {
73 $feed->{rss}->{'xml:base'};
74 }
75}
76
0d5e38d1 77## The following all work transparently in any RSS version.
78sub language {
973e1f9e 79 my $feed = shift;
80 if (@_) {
81 $feed->{rss}->channel('language', $_[0]);
82 $feed->{rss}->channel->{dc}{language} = $_[0];
83 } else {
84 $feed->{rss}->channel('language') ||
85 $feed->{rss}->channel->{dc}{language};
86 }
0d5e38d1 87}
88
9a36f82c 89sub self_link {
90 my $feed = shift;
91
92 if (@_) {
93 my $uri = shift;
94
95 $feed->{rss}->channel->{'atom'}{'link'} =
96 {
97 rel => "self",
98 href => $uri,
99 type => "application/rss+xml",
100 };
101 }
102
103 return $feed->{rss}->channel->{'atom'}{'link'};
104}
105
02de1790 106# This doesn't exist in RSS
107sub first_link { };
108sub last_link { };
109sub previous_link { };
110sub next_link { };
111sub current_link { };
112sub prev_archive_link { };
113sub next_archive_link { };
9a36f82c 114
0d5e38d1 115sub generator {
973e1f9e 116 my $feed = shift;
117 if (@_) {
118 $feed->{rss}->channel('generator', $_[0]);
119 $feed->{rss}->channel->{'http://webns.net/mvcb/'}{generatorAgent} =
120 $_[0];
121 } else {
122 $feed->{rss}->channel('generator') ||
123 $feed->{rss}->channel->{'http://webns.net/mvcb/'}{generatorAgent};
124 }
0d5e38d1 125}
126
127sub author {
973e1f9e 128 my $feed = shift;
129 if (@_) {
130 $feed->{rss}->channel('webMaster', $_[0]);
131 $feed->{rss}->channel->{dc}{creator} = $_[0];
132 } else {
133 $feed->{rss}->channel('webMaster') ||
134 $feed->{rss}->channel->{dc}{creator};
135 }
0d5e38d1 136}
137
138sub modified {
973e1f9e 139 my $rss = shift->{rss};
140 if (@_) {
141 $rss->channel('pubDate',
142 DateTime::Format::Mail->format_datetime($_[0]));
143 ## XML::RSS is so weird... if I set this, it will try to use
144 ## the value for the lastBuildDate, which I don't want--because
145 ## this date is formatted for an RSS 1.0 feed. So it's commented out.
146 #$rss->channel->{dc}{date} =
147 # DateTime::Format::W3CDTF->format_datetime($_[0]);
fe3b3201 148 } else {
149 my $date;
150 eval {
151 if (my $ts = $rss->channel('pubDate')) {
710ed823 152 $ts =~ s/^\s+//;
153 $ts =~ s/\s+$//;
fe3b3201 154 $date = DateTime::Format::Mail->parse_datetime($ts);
155 } elsif ($ts = $rss->channel->{dc}{date}) {
710ed823 156 $ts =~ s/^\s+//;
157 $ts =~ s/\s+$//;
fe3b3201 158 $date = DateTime::Format::W3CDTF->parse_datetime($ts);
159 }
160 };
161 return $date;
0d5e38d1 162 }
163}
164
165sub entries {
166 my $rss = $_[0]->{rss};
167 my @entries;
168 for my $item (@{ $rss->{items} }) {
729cd7a8 169 push @entries, XML::Feed::Entry::Format::RSS->wrap($item);
3bdbab6f 170 $entries[-1]->{_version} = $rss->{'version'};
0d5e38d1 171 }
172 @entries;
173}
174
973e1f9e 175sub add_entry {
33d4cb3f 176 my $feed = shift;
177 my $entry = shift || return;
178 $entry = $feed->_convert_entry($entry);
973e1f9e 179 $feed->{rss}->add_item(%{ $entry->unwrap });
180}
181
182sub as_xml { $_[0]->{rss}->as_string }
183
0d5e38d1 1841;
8c43fc54 185