Load XML-Feed-0.02 into trunk.
[catagits/XML-Feed.git] / lib / XML / Feed / RSS.pm
CommitLineData
a749d9b9 1# $Id: RSS.pm,v 1.5 2004/07/29 16:42:29 btrott Exp $
0d5e38d1 2
3package XML::Feed::RSS;
4use strict;
5
6use base qw( XML::Feed );
7use XML::RSS;
8use DateTime::Format::Mail;
9use DateTime::Format::W3CDTF;
10
11sub init_string {
12 my $feed = shift;
13 my($str) = @_;
14 my $rss = $feed->{rss} = XML::RSS->new;
15 if ($str) {
16 $rss->parse($str);
17 }
18 $feed;
19}
20
21sub format { 'RSS ' . $_[0]->{rss}->{'version'} }
22
23## The following elements are the same in all versions of RSS.
24sub title { $_[0]->{rss}->channel('title') }
25sub link { $_[0]->{rss}->channel('link') }
26sub description { $_[0]->{rss}->channel('description') }
27
28## This is RSS 2.0 only--what's the equivalent in RSS 1.0?
29sub copyright { $_[0]->{rss}->channel('copyright') }
30
31## The following all work transparently in any RSS version.
32sub language {
33 $_[0]->{rss}->channel('language') ||
34 $_[0]->{rss}->channel->{dc}{language}
35}
36
37sub generator {
38 $_[0]->{rss}->channel('generator') ||
39 $_[0]->{rss}->channel->{'http://webns.net/mvcb/'}{generatorAgent};
40}
41
42sub author {
43 $_[0]->{rss}->channel('webMaster') ||
44 $_[0]->{rss}->channel->{dc}{creator};
45}
46
47sub modified {
48 my $rss = $_[0]->{rss};
49 if (my $ts = $rss->channel('pubDate')) {
50 return DateTime::Format::Mail->parse_datetime($ts);
51 } elsif ($ts = $rss->channel->{dc}{date}) {
52 return DateTime::Format::W3CDTF->parse_datetime($ts);
53 }
54}
55
56sub entries {
57 my $rss = $_[0]->{rss};
58 my @entries;
59 for my $item (@{ $rss->{items} }) {
60 push @entries, XML::Feed::RSS::Entry->wrap($item);
61 }
62 @entries;
63}
64
65package XML::Feed::RSS::Entry;
66use strict;
67
a749d9b9 68use XML::Feed::Content;
69
0d5e38d1 70use base qw( XML::Feed::Entry );
71
72sub title { $_[0]->{entry}{title} }
73sub link { $_[0]->{entry}{link} }
a749d9b9 74
75sub summary {
76 my $item = $_[0]->{entry};
77 ## Some RSS feeds use <description> for a summary, and some use it
78 ## for the full content. Pretty gross. We don't want to return the
79 ## full content if the caller expects a summary, so the heuristic is:
80 ## if the <entry> contains both a <description> and one of the elements
81 ## typically used for the full content, use <description> as the summary.
82 my $txt;
83 if ($item->{description} &&
84 ($item->{'http://purl.org/rss/1.0/modules/content/'}{encoded} ||
85 $item->{'http://www.w3.org/1999/xhtml'}{body})) {
86 $txt = $item->{description};
87 }
88 XML::Feed::Content->wrap({ type => 'text/plain', body => $txt });
89}
0d5e38d1 90
91sub content {
92 my $item = $_[0]->{entry};
a749d9b9 93 my $body =
94 $_[0]->{entry}{'http://purl.org/rss/1.0/modules/content/'}{encoded} ||
95 $_[0]->{entry}{'http://www.w3.org/1999/xhtml'}{body} ||
96 $_[0]->{entry}{description};
97 XML::Feed::Content->wrap({ type => 'text/html', body => $body });
0d5e38d1 98}
99
100sub category {
101 $_[0]->{entry}{category} || $_[0]->{entry}{dc}{subject};
102}
103
104sub author {
105 $_[0]->{entry}{author} || $_[0]->{entry}{dc}{creator};
106}
107
108## XML::RSS doesn't give us access to the rdf:about for the <item>,
109## so we have to fall back to the <link> element in RSS 1.0 feeds.
110sub id {
111 $_[0]->{entry}{guid} || $_[0]->{entry}{link};
112}
113
114sub issued {
115 if (my $ts = $_[0]->{entry}{pubDate}) {
116 return DateTime::Format::Mail->parse_datetime($ts);
117 } elsif ($ts = $_[0]->{entry}{dc}{date}) {
118 return DateTime::Format::W3CDTF->parse_datetime($ts);
119 }
120}
121
122sub modified {
123 if (my $ts = $_[0]->{entry}{'http://purl.org/rss/1.0/modules/dcterms/'}{modified}) {
124 return DateTime::Format::W3CDTF->parse_datetime($ts);
125 }
126}
127
1281;