split up files to individual packages
[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
106
0d5e38d1 107sub generator {
973e1f9e 108 my $feed = shift;
109 if (@_) {
110 $feed->{rss}->channel('generator', $_[0]);
111 $feed->{rss}->channel->{'http://webns.net/mvcb/'}{generatorAgent} =
112 $_[0];
113 } else {
114 $feed->{rss}->channel('generator') ||
115 $feed->{rss}->channel->{'http://webns.net/mvcb/'}{generatorAgent};
116 }
0d5e38d1 117}
118
119sub author {
973e1f9e 120 my $feed = shift;
121 if (@_) {
122 $feed->{rss}->channel('webMaster', $_[0]);
123 $feed->{rss}->channel->{dc}{creator} = $_[0];
124 } else {
125 $feed->{rss}->channel('webMaster') ||
126 $feed->{rss}->channel->{dc}{creator};
127 }
0d5e38d1 128}
129
130sub modified {
973e1f9e 131 my $rss = shift->{rss};
132 if (@_) {
133 $rss->channel('pubDate',
134 DateTime::Format::Mail->format_datetime($_[0]));
135 ## XML::RSS is so weird... if I set this, it will try to use
136 ## the value for the lastBuildDate, which I don't want--because
137 ## this date is formatted for an RSS 1.0 feed. So it's commented out.
138 #$rss->channel->{dc}{date} =
139 # DateTime::Format::W3CDTF->format_datetime($_[0]);
fe3b3201 140 } else {
141 my $date;
142 eval {
143 if (my $ts = $rss->channel('pubDate')) {
710ed823 144 $ts =~ s/^\s+//;
145 $ts =~ s/\s+$//;
fe3b3201 146 $date = DateTime::Format::Mail->parse_datetime($ts);
147 } elsif ($ts = $rss->channel->{dc}{date}) {
710ed823 148 $ts =~ s/^\s+//;
149 $ts =~ s/\s+$//;
fe3b3201 150 $date = DateTime::Format::W3CDTF->parse_datetime($ts);
151 }
152 };
153 return $date;
0d5e38d1 154 }
155}
156
157sub entries {
158 my $rss = $_[0]->{rss};
159 my @entries;
160 for my $item (@{ $rss->{items} }) {
729cd7a8 161 push @entries, XML::Feed::Entry::Format::RSS->wrap($item);
3bdbab6f 162 $entries[-1]->{_version} = $rss->{'version'};
0d5e38d1 163 }
164 @entries;
165}
166
973e1f9e 167sub add_entry {
33d4cb3f 168 my $feed = shift;
169 my $entry = shift || return;
170 $entry = $feed->_convert_entry($entry);
973e1f9e 171 $feed->{rss}->add_item(%{ $entry->unwrap });
172}
173
174sub as_xml { $_[0]->{rss}->as_string }
175
0d5e38d1 1761;
8c43fc54 177