App-DocKnot
view release on metacpan or search on metacpan
lib/App/DocKnot/Spin/RSS.pm view on Meta::CPAN
sub _rss_output {
my ($self, $file, $base, $metadata_ref, $entries_ref) = @_;
# Determine the current date and latest publication date of all of the
# entries, published in the obnoxious format used by RSS.
my $lang = Date::Language->new('English');
my $format = '%a, %d %b %Y %H:%M:%S %z';
my $now = $lang->strftime($format, [localtime()]);
my $latest = $now;
if ($entries_ref->@*) {
$latest = strftime($format, localtime($entries_ref->[0]{date}));
}
# Determine the URL of the RSS file we're generating, if possible.
my $url;
if ($metadata_ref->{'rss-base'}) {
my $name = $file->basename();
$url = $metadata_ref->{'rss-base'} . $name;
}
# Format the entries.
my @formatted_entries;
for my $entry_ref ($entries_ref->@*) {
my $date = $lang->strftime($format, [localtime($entry_ref->{date})]);
my $description;
if ($entry_ref->{description}) {
$description = _escape($entry_ref->{description});
$description =~ s{ ^ }{ }xmsg;
$description =~ s{ \A (\s*) }{$1<p>}xms;
$description =~ s{ \n* \z }{</p>\n}xms;
} elsif ($entry_ref->{journal}) {
my $path = path($entry_ref->{journal})->absolute($base);
$description = $self->_rss_journal($path);
} elsif ($entry_ref->{review}) {
my $path = path($entry_ref->{review})->absolute($base);
$description = $self->_rss_review($path);
}
# Make all relative URLs absolute.
$description =~ s{
( < (?:a [ ] href | img [ ] src) = \" )
(?!http:)
( [./\w] [^\"]+ ) \"
}{ $1 . _absolute_url($2, $entry_ref->{link}) . qq{\"} }xmsge;
# Convert this into an object suitable for the output template.
my $formatted_ref = {
date => $date,
description => $description,
guid => $entry_ref->{guid},
link => $entry_ref->{link},
title => $entry_ref->{title},
};
push(@formatted_entries, $formatted_ref);
}
# Generate the RSS output using the template.
my %vars = (
base => $metadata_ref->{base},
description => $metadata_ref->{description},
docknot_version => $App::DocKnot::VERSION,
entries => \@formatted_entries,
language => $metadata_ref->{language},
latest => $latest,
now => $now,
title => $metadata_ref->{title},
url => $url,
);
my $result;
$self->{template}->process($self->{templates}{rss}, \%vars, \$result)
or croak($self->{template}->error());
# Write the result to the output file.
$file->spew_utf8($result);
return;
}
##############################################################################
# Thread output
##############################################################################
# Print out the thread version of the recent changes list.
#
# $file - Path::Tiny output path
# $metadata_ref - RSS feed metadata
# $entries_ref - Entries
sub _thread_output {
my ($self, $file, $metadata_ref, $entries_ref) = @_;
# The entries are in a flat list, but we want a two-level list of entries
# by month so that the template can add appropriate month headings.
# Restructure the entry list accordingly.
my (@entries_by_month, $last_month);
for my $entry_ref ($entries_ref->@*) {
my $month = strftime('%B %Y', localtime($entry_ref->{date}));
my $date = strftime('%Y-%m-%d', localtime($entry_ref->{date}));
# Copy the entry with a reformatted description.
my $description = $entry_ref->{description};
$description =~ s{ ^ }{ }xmsg;
$description =~ s{ \\ }{\\\\}xmsg;
my $formatted_ref = {
date => $date,
description => $description,
link => $entry_ref->{link},
title => $entry_ref->{title},
};
# Add the entry to the appropriate month.
if (!$last_month || $month ne $last_month) {
my $month_ref = { heading => $month, entries => [$formatted_ref] };
push(@entries_by_month, $month_ref);
$last_month = $month;
} else {
push($entries_by_month[-1]{entries}->@*, $formatted_ref);
}
}
# Generate the RSS output using the template.
my %vars = (
prefix => $metadata_ref->{'thread-prefix'},
( run in 1.333 second using v1.01-cache-2.11-cpan-39bf76dae61 )