package SCSite::FeedGenerator;
+use URI;
use Moo;
no warnings 'once';
-has id_prefix => (is => 'ro', required => 1);
has pages => (is => 'ro', required => 1);
sub feed_http_response {
- my ($self, $code, $feed_config) = @_;
+ my ($self, $code, $feed_config, $env) = @_;
$self->_feed_response(
- $code, $self->_config_to_data($feed_config)
+ $code, $self->_config_to_data($feed_config, $env)
);
}
sub _config_to_data {
- my ($self, $config) = @_;
+ my ($self, $config, $env) = @_;
+ my $url_scheme = $env->{'psgi.url_scheme'} || "http";
+ my $url_port = $env->{SERVER_PORT}||80;
+ my $base_url = URI->new(
+ $url_scheme
+ .'://'
+ .($env->{HTTP_HOST}
+ or (
+ ($env->{SERVER_NAME} || "")
+ .($url_scheme eq 'http' && $url_port == 80
+ ? ''
+ : ":${url_port}"
+ )
+ ))
+ .($env->{SCRIPT_NAME} || '/')
+ );
+ my $abs = sub { URI->new_abs($_[0], $base_url)->as_string };
my $base_page = $self->pages->get({ path => $config->{base} });
my @entry_pages = $base_page->children(%{$config->{entries}})
->latest(10)->flatten;
+ my $updated = (sort map $_->created, @entry_pages)[-1];
+{
%$config,
- id => $self->_id_for($base_page->path),
- web_url => $base_page->path,
- feed_url => "/feed/${\$config->{base}}",
- entries => [ map +{
- title => $_->title,
- summary_html => do {
- use HTML::Tags;
- HTML::Tags::to_html_string(<p>, $_->description, </p>)
- },
- content_html => $_->body,
- created => $_->created,
- web_url => $_->path,
- }, @entry_pages ],
+ id => $abs->("feed/${\$config->{base}}/"),
+ web_url => $abs->($config->{base}.'/'),
+ feed_url => $abs->("feed/${\$config->{base}}/"),
+ updated => join('T', split(' ',$updated)).'Z',
+ entries => [ map {
+ my $page_url = $abs->(do { (my $p = $_->path) =~ s/^\///; "$p/" });
+ +{
+ title => $_->title,
+ summary_html => do {
+ use HTML::Tags;
+ join '', HTML::Tags::to_html_string(<p>, $_->description, </p>)
+ },
+ content_html => $self->_absolutify_html($_->body, $base_url, $page_url),
+ created => join('T', split(' ',$_->created)).'Z',
+ web_url => $page_url,
+ }
+ } @entry_pages ],
}
}
-sub _id_for {
- my ($self, $for) = @_;
- join '', $self->id_prefix, $for;
-}
-
sub _feed_response {
my ($self, $code, $data) = @_;
[ $code,
feed title subtitle link id
);
my ($web_url, $feed_url) = @{$data}{qw(web_url feed_url)};
- (\'<?xml version="1.0" encoding="UTF-8"?>',
- <feed xmlns="http://www.w3.org/2005/Atom">,
- <title type="text">, $data->{title}, </title>,
+ (\'<?xml version="1.0" encoding="UTF-8"?>', "\n",
+ <feed xmlns="http://www.w3.org/2005/Atom">, "\n",
+ ' ', <title type="text">, $data->{title}, </title>, "\n",
($data->{subtitle}
- ? (<subtitle type="text">, $data->{subtitle}, </subtitle>)
+ ? (' ', <subtitle type="text">, $data->{subtitle}, </subtitle>, "\n",)
: ()),
- <link rel="alternate" type="text/html" href="${web_url}" />,
- <link rel="self" type="application/atom+xml" href="${feed_url}" />,
- <id>, $data->{id}, </id>,
+ ' ', <link rel="alternate" type="text/html" href="${web_url}" />, "\n",
+ ' ', <link rel="self" type="application/atom+xml" href="${feed_url}" />, "\n",
+ ' ', <updated>, $data->{updated}, </updated>, "\n",
+ ' ', <id>, $data->{id}, </id>, "\n",
(map $self->_entry_data_to_tags($_), @{$data->{entries}}),
</feed>);
}
sub _entry_data_to_tags {
my ($self, $data) = @_;
- use XML::Tags qw(entry title link id published updated summary content);
+ use XML::Tags qw(
+ entry title author name link id published updated summary content
+ );
my $web_url = $data->{web_url};
- <entry>,
- <title>, $data->{title}, </title>,
- <link href="${web_url}" />,
- <id>, $self->_id_for($data->{web_url}), </id>,
- <published>, $data->{created}, </published>,
- <updated>, ($data->{created}||$data->{updated}), </updated>,
+ ' ', <entry>, "\n",
+ ' ', <title>, $data->{title}, </title>, "\n",
+ ' ', <author>, <name>, "Shadowcat Staff", </name>, </author>, "\n",
+ ' ', <link href="${web_url}" />, "\n",
+ ' ', <id>, $web_url, </id>, "\n",
+ ' ', <published>, $data->{created}, </published>, "\n",
+ ' ', <updated>, ($data->{created}||$data->{updated}), </updated>, "\n",
($data->{summary_html}
- ? (<summary type="html">, \($data->{summary_html}), </summary>)
+ ? (' ', <summary type="html">, \('<![CDATA['.$data->{summary_html}.']]>'), </summary>, "\n")
: ()
),
- <content type="html">, \($data->{body_html}), </content>,
- </entry>;
+ ' ', <content type="html">, \('<![CDATA['.$data->{content_html}.']]>'), </content>, "\n",
+ ' ', </entry>, "\n";
+}
+
+sub _absolutify_html {
+ my ($self, $html, $base_url, $page_url) = @_;
+ $html;
}
1;