Skip to content

Commit

Permalink
Merge d113e8e into e056523
Browse files Browse the repository at this point in the history
  • Loading branch information
timgimyee committed Nov 1, 2018
2 parents e056523 + d113e8e commit 25ce2c8
Show file tree
Hide file tree
Showing 10 changed files with 230 additions and 66 deletions.
3 changes: 3 additions & 0 deletions Build.PL
Expand Up @@ -9,7 +9,10 @@ my $build = Module::Build
requires => {
'Class::ErrorHandler' => 0,
'DateTime' => 0,
'DateTime::Format::Flexible' => 0,
'DateTime::Format::ISO8601' => 0,
'DateTime::Format::Mail' => 0,
'DateTime::Format::Natural' => 0,
'DateTime::Format::W3CDTF' => 0,
'Feed::Find' => 0,
'HTML::Entities' => 0,
Expand Down
4 changes: 4 additions & 0 deletions MANIFEST
Expand Up @@ -47,6 +47,10 @@ t/22-bug73160.t
t/23-eval.t
t/24-identify-feed.t
t/25-date-format-bug.t
t/26-content-encoded.t
t/27-dummy-content-encoded.t
t/28-rss-guid.t
t/29-date-parsing.t
t/pod-coverage.t
t/pod.t
t/samples/atom-10-example.xml
Expand Down
2 changes: 1 addition & 1 deletion MANIFEST.SKIP
Expand Up @@ -6,5 +6,5 @@ _build
Build$
blib
Makefile$
^MYMETA.yml$
^MYMETA\.yml$
^MYMETA\.json$
17 changes: 5 additions & 12 deletions lib/XML/Feed/Entry/Format/Atom.pm
Expand Up @@ -6,9 +6,8 @@ use v5.10;
our $VERSION = '0.55';

use base qw( XML::Feed::Entry );
use XML::Atom::Util qw( iso2dt );
use XML::Feed::Content;
use XML::Feed::Util qw( format_W3CDTF );
use XML::Feed::Util qw( format_w3cdtf parse_datetime );
use XML::Atom::Entry;
use List::Util qw( first );

Expand Down Expand Up @@ -160,24 +159,18 @@ sub id { shift->{entry}->id(@_) }
sub issued {
my $entry = shift;
if (@_) {
$entry->{entry}->issued(format_W3CDTF($_[0])) if $_[0];
$entry->{entry}->issued(format_w3cdtf($_[0])) if $_[0];
} else {
return iso2dt($entry->{entry}->issued)
if $entry->{entry}->issued;
return iso2dt($entry->{entry}->published)
if $entry->{entry}->published;
return undef;
parse_datetime($entry->{entry}->issued || $entry->{entry}->published);
}
}

sub modified {
my $entry = shift;
if (@_) {
$entry->{entry}->modified(format_W3CDTF($_[0])) if $_[0];
$entry->{entry}->modified(format_w3cdtf($_[0])) if $_[0];
} else {
return iso2dt($entry->{entry}->modified) if $entry->{entry}->modified;
return iso2dt($entry->{entry}->updated) if $entry->{entry}->updated;
return undef;
parse_datetime($entry->{entry}->modified || $entry->{entry}->updated);
}
}

Expand Down
33 changes: 8 additions & 25 deletions lib/XML/Feed/Entry/Format/RSS.pm
Expand Up @@ -8,7 +8,7 @@ our $VERSION = '0.55';
sub format { 'RSS ' . $_[0]->{'_version'} }

use XML::Feed::Content;
use XML::Feed::Util qw( format_W3CDTF );
use XML::Feed::Util qw( format_w3cdtf parse_mail_date parse_w3cdtf_date );

use base qw( XML::Feed::Entry );

Expand Down Expand Up @@ -144,39 +144,22 @@ sub id {
sub issued {
my $item = shift->{entry};
if (@_) {
$item->{dc}{date} = format_W3CDTF($_[0]);
$item->{dc}{date} = format_w3cdtf($_[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;
return parse_mail_date($item->{pubDate})
|| parse_w3cdtf_date($item->{dc}{date} || $item->{dcterms}{date});
}
}

sub modified {
my $item = shift->{entry};
if (@_) {
$item->{dcterms}{modified} = format_W3CDTF($_[0]);
$item->{dcterms}{modified} = format_w3cdtf($_[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) };
}
return parse_w3cdtf_date(
$item->{dcterms}{modified} || $item->{atom}{updated}
);
}
}

Expand Down
9 changes: 3 additions & 6 deletions lib/XML/Feed/Format/Atom.pm
Expand Up @@ -7,8 +7,7 @@ our $VERSION = '0.55';

use base qw( XML::Feed );
use XML::Atom::Feed;
use XML::Atom::Util qw( iso2dt );
use XML::Feed::Util qw( format_W3CDTF );
use XML::Feed::Util qw( format_w3cdtf parse_datetime );
use List::Util qw( first );
use HTML::Entities;

Expand Down Expand Up @@ -120,11 +119,9 @@ sub image {
sub modified {
my $feed = shift;
if (@_) {
$feed->{atom}->modified(format_W3CDTF($_[0]));
$feed->{atom}->modified(format_w3cdtf($_[0]));
} else {
return iso2dt($feed->{atom}->modified) if $feed->{atom}->modified;
return iso2dt($feed->{atom}->updated) if $feed->{atom}->updated;
return undef;
parse_datetime($feed->{atom}->modified || $feed->{atom}->updated);
}
}

Expand Down
18 changes: 3 additions & 15 deletions lib/XML/Feed/Format/RSS.pm
Expand Up @@ -8,13 +8,12 @@ our $VERSION = '0.55';
use base qw( XML::Feed );
use DateTime::Format::Mail;
use DateTime::Format::W3CDTF;
use XML::Atom::Util qw(iso2dt);
use XML::Feed::Enclosure;
use XML::Feed::Entry::Format::RSS;
use XML::Feed::Util qw( parse_mail_date parse_w3cdtf_date );

our $PREFERRED_PARSER = "XML::RSS";


sub identify {
my $class = shift;
my $xml = shift;
Expand Down Expand Up @@ -148,19 +147,8 @@ sub modified {
#$rss->channel->{dc}{date} =
# DateTime::Format::W3CDTF->format_datetime($_[0]);
} else {
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);
}
};
return $date;
return parse_mail_date($rss->channel('pubDate'))
|| parse_w3cdtf_date($rss->channel->{dc}{date});
}
}

Expand Down
87 changes: 82 additions & 5 deletions lib/XML/Feed/Util.pm
Expand Up @@ -5,11 +5,19 @@ use warnings;
our $VERSION = '0.55';

use base qw( Exporter );
use DateTime::Format::Flexible;
use DateTime::Format::ISO8601;
use DateTime::Format::Natural;
use DateTime::Format::W3CDTF;

our @EXPORT_OK = qw( format_W3CDTF );
our @EXPORT_OK = qw(
format_w3cdtf
parse_datetime
parse_w3cdtf_date
parse_mail_date
);

sub format_W3CDTF {
sub format_w3cdtf {
my $date = DateTime::Format::W3CDTF->format_datetime(shift);

# Add timezone "Z" if "floating" DateTime.
Expand All @@ -18,6 +26,44 @@ sub format_W3CDTF {
return $date;
}

sub parse_datetime {
my $ts = shift or return undef;

$ts = _strip_spaces($ts);

return eval { DateTime::Format::ISO8601->parse_datetime($ts) }
|| eval { DateTime::Format::Flexible->parse_datetime($ts) }
|| do {
my $p = DateTime::Format::Natural->new;
my $dt = $p->parse_datetime($ts);
$p->success ? $dt : undef;
};
};

sub parse_mail_date {
my $ts = shift or return undef;

$ts = _strip_spaces($ts);

return eval { DateTime::Format::Mail(loose => 1)->parse_datetime($ts) }
|| parse_datetime($ts);
};

sub parse_w3cdtf_date {
my $ts = shift or return undef;

$ts = _strip_spaces($ts);

return eval { DateTime::Format::W3CDTF->parse_datetime($ts) }
|| parse_datetime($ts);
};

sub _strip_spaces {
local $_ = shift;
s/^\s+//, s/\s+$// if $_;
return $_;
}

1;

__END__
Expand All @@ -28,22 +74,53 @@ XML::Feed::Util - Utility functions
=head1 SYNOPSIS
use XML::Feed::Util qw( format_W3CDTF );
use XML::Feed::Util qw(
format_w3cdtf
parse_datetime
parse_mail_date
parse_w3cdtf_date
);
use DateTime;
print format_W3CDTF(DateTime->now);
print format_w3cdtf(DateTime->now);
my $dt;
$dt = parse_datetime('January 8, 1999');
$dt = parse_mail_date('Fri, 23 Nov 2001 21:57:24 -0600');
$dt = parse_w3cdtf_date('2003-02-15T13:50:05-05:00');
=head1 DESCRIPTION
Common utility or helper functions.
=head1 USAGE
=head2 format_W3CDTF($date)
=head2 format_w3cdtf($datetime)
Convert DateTime object to W3CDTF format string.
Uses default timezone "Z" for "floating" DateTime.
=head2 parse_datetime($date)
Parse any date string using L<DateTime::Format::ISO8601>,
L<DateTime::Format::Flexible> or L<DateTime::Format::Natural>.
Returns DateTime object or undef.
=head2 parse_mail_date($date)
Parse date in RFC2822/822 format using L<DateTime::Format::Mail>.
Fallback to C<parse_datetime()> for other formats.
Returns DateTime object or undef.
=head2 parse_w3cdtf_date($date)
Parse date W3CDTF format using L<DateTime::Format::W3CDTF>.
Fallback to C<parse_datetime()> for other formats.
Returns DateTime object or undef.
=head1 AUTHOR & COPYRIGHT
Please see the I<XML::Feed> manpage for author, copyright, and license
Expand Down

0 comments on commit 25ce2c8

Please sign in to comment.