-# $Id: RSS.pm 1934 2006-04-22 05:13:55Z btrott $
+# $Id$
package XML::Feed::Format::RSS;
use strict;
use base qw( XML::Feed );
use DateTime::Format::Mail;
use DateTime::Format::W3CDTF;
+use XML::Atom::Util qw(iso2dt);
+use XML::Feed::Enclosure;
our $PREFERRED_PARSER = "XML::RSS";
my $feed = shift;
my($str) = @_;
$feed->init_empty;
+ my $opts = {
+ hashrefs_instead_of_strings => 1,
+ };
+ $opts->{allow_multiple} = [ 'enclosure' ] if $XML::Feed::MULTIPLE_ENCLOSURES;
if ($str) {
- $feed->{rss}->parse($$str, { hashrefs_instead_of_strings => 1 } );
+ $feed->{rss}->parse($$str, $opts );
}
$feed;
}
## The following elements are the same in all versions of RSS.
sub title { shift->{rss}->channel('title', @_) }
-sub link { shift->{rss}->channel('link', @_) }
+sub link {
+ my $link = shift->{rss}->channel('link', @_);
+ $link =~ s/^\s+//;
+ $link =~ s/\s+$//;
+ return $link;
+}
sub description { shift->{rss}->channel('description', @_) }
+sub updated { shift->modified(@_) }
# This doesn't exist in RSS
sub id { }
my $date;
eval {
if (my $ts = $rss->channel('pubDate')) {
+ $ts =~ s/^\s+//;
+ $ts =~ s/\s+$//;
$date = DateTime::Format::Mail->parse_datetime($ts);
} elsif ($ts = $rss->channel->{dc}{date}) {
+ $ts =~ s/^\s+//;
+ $ts =~ s/\s+$//;
$date = DateTime::Format::W3CDTF->parse_datetime($ts);
}
};
## For RSS 2.0 output from XML::RSS. Sigh.
$entry->{entry}{permaLink} = $_[0];
} else {
- $entry->{entry}{link} || $entry->{entry}{guid};
+ my $link = $entry->{entry}{link} ||
+ $entry->{entry}{permaLink} ||
+ $entry->{entry}{guid};
+ if (defined $link) {
+ $link =~ s/^\s+//;
+ $link =~ s/\s+$//;
+ }
+ return $link;
}
}
($item->{content}{encoded} ||
$item->{'http://www.w3.org/1999/xhtml'}{body})) {
$txt = $item->{description};
+ ## Blogspot's 'short' RSS feeds do this in the Atom namespace
+ ## for no obviously good reason.
+ } elsif ($item->{'http://www.w3.org/2005/Atom'}{summary}) {
+ $txt = $item->{'http://www.w3.org/2005/Atom'}{summary};
}
XML::Feed::Content->wrap({ type => 'text/plain', body => $txt });
}
}
sub category {
- my $item = shift->{entry};
+ my $entry = shift;
+ my $item = $entry->{entry};
if (@_) {
- $item->{category} = $item->{dc}{subject} = $_[0];
+ my @tmp = ($entry->category, @_);
+ $item->{category} = [@tmp];
+ $item->{dc}{subject} = [@tmp];
} else {
- $item->{category} || $item->{dc}{subject};
+ my $r = $item->{category} || $item->{dc}{subject};
+ my @r = ref($r) eq 'ARRAY' ? @$r : defined $r? ($r) : ();
+ return wantarray? @r : $r[0];
}
}
if (my $ts = $item->{pubDate}) {
my $parser = DateTime::Format::Mail->new;
$parser->loose;
+ $ts =~ s/^\s+//;
+ $ts =~ s/\s+$//;
$date = $parser->parse_datetime($ts);
- } elsif ($ts = $item->{dc}{date}) {
+ } elsif ($ts = $item->{dc}{date} or $ts = $item->{dcterms}{date}) {
+ $ts =~ s/^\s+//;
+ $ts =~ s/\s+$//;
$date = DateTime::Format::W3CDTF->parse_datetime($ts);
}
};
$item->{dcterms}{modified} =
DateTime::Format::W3CDTF->format_datetime($_[0]);
} else {
- if (my $ts = $item->{dcterms}{modified}) {
- return eval { DateTime::Format::W3CDTF->parse_datetime($ts) };
- }
+ if (my $ts = $item->{dcterms}{modified} ||
+ $item->{'http://www.w3.org/2005/Atom'}{updated}) {
+ $ts =~ s/^\s+//;
+ $ts =~ s/\s+$//;
+ return eval { DateTime::Format::W3CDTF->parse_datetime($ts) } || eval { XML::Atom::Util::iso2dt($ts) };
+ }
}
}
if (@_) {
my $enclosure = shift;
- $entry->{entry}->{enclosure} = {
+ my $val = {
url => $enclosure->{url},
type => $enclosure->{type},
length => $enclosure->{length}
- };
+ };
+ if ($XML::Feed::MULTIPLE_ENCLOSURES) {
+ push @{$entry->{entry}->{enclosure}}, $val;
+ } else {
+ $entry->{entry}->{enclosure} = $val;
+ }
} else {
- return XML::Feed::Enclosure->new($entry->{entry}->{enclosure});
+ my $tmp = $entry->{entry}->{enclosure};
+ if (defined $tmp) {
+ my @encs = map { XML::Feed::Enclosure->new($_) }
+ (ref $tmp eq 'ARRAY')? @$tmp : ($tmp);
+ return ($XML::Feed::MULTIPLE_ENCLOSURES)? @encs : $encs[-1];
+ }
+ return;
}
}