From: Gabor Szabo Date: Sun, 19 Feb 2012 07:26:03 +0000 (+0200) Subject: split up files to individual packages X-Git-Tag: RELEASE_0.48~5^2~5 X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=catagits%2FXML-Feed.git;a=commitdiff_plain;h=8c43fc54b494ebb1ae8b451d18fd77603fe20372 split up files to individual packages --- diff --git a/lib/XML/Feed/Entry/Format/Atom.pm b/lib/XML/Feed/Entry/Format/Atom.pm new file mode 100644 index 0000000..bf67088 --- /dev/null +++ b/lib/XML/Feed/Entry/Format/Atom.pm @@ -0,0 +1,202 @@ +package XML::Feed::Entry::Format::Atom; +use strict; + +use base qw( XML::Feed::Entry ); +use XML::Atom::Util qw( iso2dt ); +use XML::Feed::Content; +use XML::Atom::Entry; +use List::Util qw( first ); + +sub init_empty { + my $entry = shift; + $entry->{entry} = XML::Atom::Entry->new(Version => 1.0); + 1; +} + +sub format { 'Atom' } + +sub title { shift->{entry}->title(@_) } +sub source { shift->{entry}->source(@_) } +sub updated { shift->{entry}->updated(@_) } +sub base { shift->{entry}->base(@_) } + +sub link { + my $entry = shift; + if (@_) { + $entry->{entry}->add_link({ rel => 'alternate', href => $_[0], + type => 'text/html', }); + } else { + my $l = first { !defined $_->rel || $_->rel eq 'alternate' } $entry->{entry}->link; + $l ? $l->href : undef; + } +} + +sub summary { + my $entry = shift; + if (@_) { + my %param; + if (ref($_[0]) eq 'XML::Feed::Content') { + %param = (Body => $_[0]->body); + } else { + %param = (Body => $_[0]); + } + $entry->{entry}->summary(XML::Atom::Content->new(%param, Version => 1.0)); + } else { + my $s = $entry->{entry}->summary; + # map Atom types to MIME types + my $type = ($s && ref($s) eq 'XML::Feed::Content') ? $s->type : undef; + if ($type) { + $type = 'text/html' if $type eq 'xhtml' || $type eq 'html'; + $type = 'text/plain' if $type eq 'text'; + } + my $body = $s; + if (defined $s && ref($s) eq 'XML::Feed::Content') { + $body = $s->body; + } + XML::Feed::Content->wrap({ type => $type, + body => $body }); + } +} + +my %types = ( + 'text/xhtml' => 'xhtml', + 'text/html' => 'html', + 'text/plain' => 'text', +); + +sub content { + my $entry = shift; + if (@_) { + my %param; + my $base; + my $orig_body; + if (ref($_[0]) eq 'XML::Feed::Content') { + $orig_body = $_[0]->body; + if (defined $_[0]->type && defined $types{$_[0]->type}) { + %param = (Body => $orig_body, Type => $types{$_[0]->type}); + + if ($param{'Type'} eq "html") { + $param{'Body'} = HTML::Entities::encode_entities($param{'Body'}); + } + } else { + } + $base = $_[0]->base if defined $_[0]->base; + } else { + $orig_body = $_[0]; + } + if (!exists($param{Body})) + { + $param{Body} = $orig_body; + } + $entry->{entry}->content(XML::Atom::Content->new(%param, Version => 1.0)); + # Assigning again so the type will be normalized. This seems to be + # an XML-Atom do-what-I-don't-meannery. + $entry->{entry}->content->body($orig_body); + $entry->{entry}->content->base($base) if defined $base; + } else { + my $c = $entry->{entry}->content; + + # map Atom types to MIME types + my $type = $c ? $c->type : undef; + if ($type) { + $type = 'text/html' if $type eq 'xhtml' || $type eq 'html'; + $type = 'text/plain' if $type eq 'text'; + } + + XML::Feed::Content->wrap({ type => $type, + base => $c ? $c->base : undef, + body => $c ? $c->body : undef }); + } +} + +sub category { + my $entry = shift; + my $ns = XML::Atom::Namespace->new(dc => 'http://purl.org/dc/elements/1.1/'); + if (@_) { + $entry->{entry}->add_category({ term => $_ }) for @_; + return 1 + } else { + + + my @category = ($entry->{entry}->can('categories')) ? $entry->{entry}->categories : $entry->{entry}->category; + my @return = @category + ? (map { $_->label || $_->term } @category) + : $entry->{entry}->getlist($ns, 'subject'); + + return wantarray? @return : $return[0]; + } +} + +sub author { + my $entry = shift; + if (@_ && $_[0]) { + my $person = XML::Atom::Person->new(Version => 1.0); + $person->name($_[0]); + $entry->{entry}->author($person); + } else { + $entry->{entry}->author ? $entry->{entry}->author->name : undef; + } +} + +sub id { shift->{entry}->id(@_) } + +sub issued { + my $entry = shift; + if (@_) { + $entry->{entry}->issued(DateTime::Format::W3CDTF->format_datetime($_[0])) if $_[0]; + } else { + $entry->{entry}->issued ? iso2dt($entry->{entry}->issued) : undef; + } +} + +sub modified { + my $entry = shift; + if (@_) { + $entry->{entry}->modified(DateTime::Format::W3CDTF->format_datetime($_[0])) if $_[0]; + } else { + return iso2dt($entry->{entry}->modified) if $entry->{entry}->modified; + return iso2dt($entry->{entry}->updated) if $entry->{entry}->updated; + return undef; + } +} + +sub lat { + my $entry = shift; + if (@_) { + $entry->{entry}->lat($_[0]) if $_[0]; + } else { + $entry->{entry}->lat; + } +} + +sub long { + my $entry = shift; + if (@_) { + $entry->{entry}->long($_[0]) if $_[0]; + } else { + $entry->{entry}->long; + } +} + + +sub enclosure { + my $entry = shift; + + if (@_) { + my $enclosure = shift; + my $method = ($XML::Feed::MULTIPLE_ENCLOSURES)? 'add_link' : 'link'; + $entry->{entry}->$method({ rel => 'enclosure', href => $enclosure->{url}, + length => $enclosure->{length}, + type => $enclosure->{type} }); + return 1; + } else { + my @links = grep { defined $_->rel && $_->rel eq 'enclosure' } $entry->{entry}->link; + return unless @links; + my @encs = map { XML::Feed::Enclosure->new({ url => $_->href, length => $_->length, type => $_->type }) } @links ; + return ($XML::Feed::MULTIPLE_ENCLOSURES)? @encs : $encs[-1]; + } +} + + +1; + diff --git a/lib/XML/Feed/Entry/Format/RSS.pm b/lib/XML/Feed/Entry/Format/RSS.pm new file mode 100644 index 0000000..c720b70 --- /dev/null +++ b/lib/XML/Feed/Entry/Format/RSS.pm @@ -0,0 +1,219 @@ +package XML::Feed::Entry::Format::RSS; +use strict; + +sub format { 'RSS ' . $_[0]->{'_version'} } + +use XML::Feed::Content; + +use base qw( XML::Feed::Entry ); + +sub init_empty { $_[0]->{entry} = { } } + +sub base { + my $entry = shift; + @_ ? $entry->{entry}->{'xml:base'} = $_[0] : $entry->{entry}->{'xml:base'}; +} + +sub title { + my $entry = shift; + @_ ? $entry->{entry}{title} = $_[0] : $entry->{entry}{title}; +} + +sub link { + my $entry = shift; + if (@_) { + $entry->{entry}{link} = $_[0]; + ## For RSS 2.0 output from XML::RSS. Sigh. + $entry->{entry}{permaLink} = $_[0]; + } else { + my $link = $entry->{entry}{link} || + $entry->{entry}{permaLink} || + $entry->{entry}{guid}; + if (defined $link) { + $link =~ s/^\s+//; + $link =~ s/\s+$//; + } + return $link; + } +} + +sub summary { + my $item = shift->{entry}; + if (@_) { + $item->{description} = ref($_[0]) eq 'XML::Feed::Content' ? + $_[0]->body : $_[0]; + ## Because of the logic below, we need to add some dummy content, + ## so that we'll properly recognize the description we enter as + ## the summary. + if (!$item->{content}{encoded} && + !$item->{'http://www.w3.org/1999/xhtml'}{body}) { + $item->{content}{encoded} = ' '; + } + } else { + ## Some RSS feeds use for a summary, and some use it + ## for the full content. Pretty gross. We don't want to return the + ## full content if the caller expects a summary, so the heuristic is: + ## if the contains both a and one of the elements + ## typically used for the full content, use as summary. + my $txt; + if ($item->{description} && + ($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 content { + my $item = shift->{entry}; + if (@_) { + my $c; + if (ref($_[0]) eq 'XML::Feed::Content') { + if (defined $_[0]->base) { + $c = { 'content' => $_[0]->body, 'xml:base' => $_[0]->base }; + } else { + $c = $_[0]->body; + } + } else { + $c = $_[0]; + } + $item->{content}{encoded} = $c; + } else { + my $base; + my $body = + $item->{content}{encoded} || + $item->{'http://www.w3.org/1999/xhtml'}{body} || + $item->{description}; + if ('HASH' eq ref($body)) { + $base = $body->{'xml:base'}; + $body = $body->{content}; + } + XML::Feed::Content->wrap({ type => 'text/html', body => $body, base => $base }); + } +} + +sub category { + my $entry = shift; + my $item = $entry->{entry}; + if (@_) { + my @tmp = ($entry->category, @_); + $item->{category} = [@tmp]; + $item->{dc}{subject} = [@tmp]; + } else { + my $r = $item->{category} || $item->{dc}{subject}; + my @r = ref($r) eq 'ARRAY' ? @$r : defined $r? ($r) : (); + return wantarray? @r : $r[0]; + } +} + +sub author { + my $item = shift->{entry}; + if (@_) { + $item->{author} = $item->{dc}{creator} = $_[0]; + } else { + $item->{author} || $item->{dc}{creator}; + } +} + +## XML::RSS doesn't give us access to the rdf:about for the , +## so we have to fall back to the element in RSS 1.0 feeds. +sub id { + my $item = shift->{entry}; + if (@_) { + $item->{guid} = $_[0]; + } else { + $item->{guid} || $item->{link}; + } +} + +sub issued { + my $item = shift->{entry}; + if (@_) { + $item->{dc}{date} = DateTime::Format::W3CDTF->format_datetime($_[0]); + $item->{pubDate} = DateTime::Format::Mail->format_datetime($_[0]); + } else { + ## Either of these could die if the format is invalid. + my $date; + eval { + 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} or $ts = $item->{dcterms}{date}) { + $ts =~ s/^\s+//; + $ts =~ s/\s+$//; + $date = DateTime::Format::W3CDTF->parse_datetime($ts); + } + }; + return $date; + } +} + +sub modified { + my $item = shift->{entry}; + if (@_) { + $item->{dcterms}{modified} = + DateTime::Format::W3CDTF->format_datetime($_[0]); + } else { + 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) }; + } + } +} + +sub lat { + my $item = shift->{entry}; + if (@_) { + $item->{geo}{lat} = $_[0]; + } else { + return $item->{geo}{lat}; + } +} + +sub long { + my $item = shift->{entry}; + if (@_) { + $item->{geo}{long} = $_[0]; + } else { + return $item->{geo}{long}; + } +} + +sub enclosure { + my $entry = shift; + + if (@_) { + my $enclosure = shift; + 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 { + 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; + } +} + +1; + diff --git a/lib/XML/Feed/Format/Atom.pm b/lib/XML/Feed/Format/Atom.pm index a875899..37bab42 100644 --- a/lib/XML/Feed/Format/Atom.pm +++ b/lib/XML/Feed/Format/Atom.pm @@ -14,6 +14,7 @@ use XML::Atom::Entry; XML::Atom::Entry->mk_elem_accessors(qw( lat long ), ['http://www.w3.org/2003/01/geo/wgs84_pos#']); use XML::Atom::Content; +use XML::Feed::Entry::Format::Atom; sub identify { my $class = shift; @@ -126,204 +127,4 @@ sub add_entry { sub as_xml { $_[0]->{atom}->as_xml } -package XML::Feed::Entry::Format::Atom; -use strict; - -use base qw( XML::Feed::Entry ); -use XML::Atom::Util qw( iso2dt ); -use XML::Feed::Content; -use XML::Atom::Entry; -use List::Util qw( first ); - -sub init_empty { - my $entry = shift; - $entry->{entry} = XML::Atom::Entry->new(Version => 1.0); - 1; -} - -sub format { 'Atom' } - -sub title { shift->{entry}->title(@_) } -sub source { shift->{entry}->source(@_) } -sub updated { shift->{entry}->updated(@_) } -sub base { shift->{entry}->base(@_) } - -sub link { - my $entry = shift; - if (@_) { - $entry->{entry}->add_link({ rel => 'alternate', href => $_[0], - type => 'text/html', }); - } else { - my $l = first { !defined $_->rel || $_->rel eq 'alternate' } $entry->{entry}->link; - $l ? $l->href : undef; - } -} - -sub summary { - my $entry = shift; - if (@_) { - my %param; - if (ref($_[0]) eq 'XML::Feed::Content') { - %param = (Body => $_[0]->body); - } else { - %param = (Body => $_[0]); - } - $entry->{entry}->summary(XML::Atom::Content->new(%param, Version => 1.0)); - } else { - my $s = $entry->{entry}->summary; - # map Atom types to MIME types - my $type = ($s && ref($s) eq 'XML::Feed::Content') ? $s->type : undef; - if ($type) { - $type = 'text/html' if $type eq 'xhtml' || $type eq 'html'; - $type = 'text/plain' if $type eq 'text'; - } - my $body = $s; - if (defined $s && ref($s) eq 'XML::Feed::Content') { - $body = $s->body; - } - XML::Feed::Content->wrap({ type => $type, - body => $body }); - } -} - -my %types = ( - 'text/xhtml' => 'xhtml', - 'text/html' => 'html', - 'text/plain' => 'text', -); - -sub content { - my $entry = shift; - if (@_) { - my %param; - my $base; - my $orig_body; - if (ref($_[0]) eq 'XML::Feed::Content') { - $orig_body = $_[0]->body; - if (defined $_[0]->type && defined $types{$_[0]->type}) { - %param = (Body => $orig_body, Type => $types{$_[0]->type}); - - if ($param{'Type'} eq "html") { - $param{'Body'} = HTML::Entities::encode_entities($param{'Body'}); - } - } else { - } - $base = $_[0]->base if defined $_[0]->base; - } else { - $orig_body = $_[0]; - } - if (!exists($param{Body})) - { - $param{Body} = $orig_body; - } - $entry->{entry}->content(XML::Atom::Content->new(%param, Version => 1.0)); - # Assigning again so the type will be normalized. This seems to be - # an XML-Atom do-what-I-don't-meannery. - $entry->{entry}->content->body($orig_body); - $entry->{entry}->content->base($base) if defined $base; - } else { - my $c = $entry->{entry}->content; - - # map Atom types to MIME types - my $type = $c ? $c->type : undef; - if ($type) { - $type = 'text/html' if $type eq 'xhtml' || $type eq 'html'; - $type = 'text/plain' if $type eq 'text'; - } - - XML::Feed::Content->wrap({ type => $type, - base => $c ? $c->base : undef, - body => $c ? $c->body : undef }); - } -} - -sub category { - my $entry = shift; - my $ns = XML::Atom::Namespace->new(dc => 'http://purl.org/dc/elements/1.1/'); - if (@_) { - $entry->{entry}->add_category({ term => $_ }) for @_; - return 1 - } else { - - - my @category = ($entry->{entry}->can('categories')) ? $entry->{entry}->categories : $entry->{entry}->category; - my @return = @category - ? (map { $_->label || $_->term } @category) - : $entry->{entry}->getlist($ns, 'subject'); - - return wantarray? @return : $return[0]; - } -} - -sub author { - my $entry = shift; - if (@_ && $_[0]) { - my $person = XML::Atom::Person->new(Version => 1.0); - $person->name($_[0]); - $entry->{entry}->author($person); - } else { - $entry->{entry}->author ? $entry->{entry}->author->name : undef; - } -} - -sub id { shift->{entry}->id(@_) } - -sub issued { - my $entry = shift; - if (@_) { - $entry->{entry}->issued(DateTime::Format::W3CDTF->format_datetime($_[0])) if $_[0]; - } else { - $entry->{entry}->issued ? iso2dt($entry->{entry}->issued) : undef; - } -} - -sub modified { - my $entry = shift; - if (@_) { - $entry->{entry}->modified(DateTime::Format::W3CDTF->format_datetime($_[0])) if $_[0]; - } else { - return iso2dt($entry->{entry}->modified) if $entry->{entry}->modified; - return iso2dt($entry->{entry}->updated) if $entry->{entry}->updated; - return undef; - } -} - -sub lat { - my $entry = shift; - if (@_) { - $entry->{entry}->lat($_[0]) if $_[0]; - } else { - $entry->{entry}->lat; - } -} - -sub long { - my $entry = shift; - if (@_) { - $entry->{entry}->long($_[0]) if $_[0]; - } else { - $entry->{entry}->long; - } -} - - -sub enclosure { - my $entry = shift; - - if (@_) { - my $enclosure = shift; - my $method = ($XML::Feed::MULTIPLE_ENCLOSURES)? 'add_link' : 'link'; - $entry->{entry}->$method({ rel => 'enclosure', href => $enclosure->{url}, - length => $enclosure->{length}, - type => $enclosure->{type} }); - return 1; - } else { - my @links = grep { defined $_->rel && $_->rel eq 'enclosure' } $entry->{entry}->link; - return unless @links; - my @encs = map { XML::Feed::Enclosure->new({ url => $_->href, length => $_->length, type => $_->type }) } @links ; - return ($XML::Feed::MULTIPLE_ENCLOSURES)? @encs : $encs[-1]; - } -} - - 1; diff --git a/lib/XML/Feed/Format/RSS.pm b/lib/XML/Feed/Format/RSS.pm index ab150ad..3a589c9 100644 --- a/lib/XML/Feed/Format/RSS.pm +++ b/lib/XML/Feed/Format/RSS.pm @@ -8,6 +8,7 @@ use DateTime::Format::Mail; use DateTime::Format::W3CDTF; use XML::Atom::Util qw(iso2dt); use XML::Feed::Enclosure; +use XML::Feed::Entry::Format::RSS; our $PREFERRED_PARSER = "XML::RSS"; @@ -172,221 +173,5 @@ sub add_entry { sub as_xml { $_[0]->{rss}->as_string } -package XML::Feed::Entry::Format::RSS; -use strict; - -sub format { 'RSS ' . $_[0]->{'_version'} } - -use XML::Feed::Content; - -use base qw( XML::Feed::Entry ); - -sub init_empty { $_[0]->{entry} = { } } - -sub base { - my $entry = shift; - @_ ? $entry->{entry}->{'xml:base'} = $_[0] : $entry->{entry}->{'xml:base'}; -} - -sub title { - my $entry = shift; - @_ ? $entry->{entry}{title} = $_[0] : $entry->{entry}{title}; -} - -sub link { - my $entry = shift; - if (@_) { - $entry->{entry}{link} = $_[0]; - ## For RSS 2.0 output from XML::RSS. Sigh. - $entry->{entry}{permaLink} = $_[0]; - } else { - my $link = $entry->{entry}{link} || - $entry->{entry}{permaLink} || - $entry->{entry}{guid}; - if (defined $link) { - $link =~ s/^\s+//; - $link =~ s/\s+$//; - } - return $link; - } -} - -sub summary { - my $item = shift->{entry}; - if (@_) { - $item->{description} = ref($_[0]) eq 'XML::Feed::Content' ? - $_[0]->body : $_[0]; - ## Because of the logic below, we need to add some dummy content, - ## so that we'll properly recognize the description we enter as - ## the summary. - if (!$item->{content}{encoded} && - !$item->{'http://www.w3.org/1999/xhtml'}{body}) { - $item->{content}{encoded} = ' '; - } - } else { - ## Some RSS feeds use for a summary, and some use it - ## for the full content. Pretty gross. We don't want to return the - ## full content if the caller expects a summary, so the heuristic is: - ## if the contains both a and one of the elements - ## typically used for the full content, use as summary. - my $txt; - if ($item->{description} && - ($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 content { - my $item = shift->{entry}; - if (@_) { - my $c; - if (ref($_[0]) eq 'XML::Feed::Content') { - if (defined $_[0]->base) { - $c = { 'content' => $_[0]->body, 'xml:base' => $_[0]->base }; - } else { - $c = $_[0]->body; - } - } else { - $c = $_[0]; - } - $item->{content}{encoded} = $c; - } else { - my $base; - my $body = - $item->{content}{encoded} || - $item->{'http://www.w3.org/1999/xhtml'}{body} || - $item->{description}; - if ('HASH' eq ref($body)) { - $base = $body->{'xml:base'}; - $body = $body->{content}; - } - XML::Feed::Content->wrap({ type => 'text/html', body => $body, base => $base }); - } -} - -sub category { - my $entry = shift; - my $item = $entry->{entry}; - if (@_) { - my @tmp = ($entry->category, @_); - $item->{category} = [@tmp]; - $item->{dc}{subject} = [@tmp]; - } else { - my $r = $item->{category} || $item->{dc}{subject}; - my @r = ref($r) eq 'ARRAY' ? @$r : defined $r? ($r) : (); - return wantarray? @r : $r[0]; - } -} - -sub author { - my $item = shift->{entry}; - if (@_) { - $item->{author} = $item->{dc}{creator} = $_[0]; - } else { - $item->{author} || $item->{dc}{creator}; - } -} - -## XML::RSS doesn't give us access to the rdf:about for the , -## so we have to fall back to the element in RSS 1.0 feeds. -sub id { - my $item = shift->{entry}; - if (@_) { - $item->{guid} = $_[0]; - } else { - $item->{guid} || $item->{link}; - } -} - -sub issued { - my $item = shift->{entry}; - if (@_) { - $item->{dc}{date} = DateTime::Format::W3CDTF->format_datetime($_[0]); - $item->{pubDate} = DateTime::Format::Mail->format_datetime($_[0]); - } else { - ## Either of these could die if the format is invalid. - my $date; - eval { - 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} or $ts = $item->{dcterms}{date}) { - $ts =~ s/^\s+//; - $ts =~ s/\s+$//; - $date = DateTime::Format::W3CDTF->parse_datetime($ts); - } - }; - return $date; - } -} - -sub modified { - my $item = shift->{entry}; - if (@_) { - $item->{dcterms}{modified} = - DateTime::Format::W3CDTF->format_datetime($_[0]); - } else { - 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) }; - } - } -} - -sub lat { - my $item = shift->{entry}; - if (@_) { - $item->{geo}{lat} = $_[0]; - } else { - return $item->{geo}{lat}; - } -} - -sub long { - my $item = shift->{entry}; - if (@_) { - $item->{geo}{long} = $_[0]; - } else { - return $item->{geo}{long}; - } -} - -sub enclosure { - my $entry = shift; - - if (@_) { - my $enclosure = shift; - 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 { - 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; - } -} - 1; +