Commit | Line | Data |
221c4151 |
1 | package SCSite::FeedGenerator; |
2 | |
da140bff |
3 | use URI; |
221c4151 |
4 | use Moo; |
5 | no warnings 'once'; |
6 | |
221c4151 |
7 | has pages => (is => 'ro', required => 1); |
8 | |
9 | sub feed_http_response { |
da140bff |
10 | my ($self, $code, $feed_config, $env) = @_; |
221c4151 |
11 | $self->_feed_response( |
da140bff |
12 | $code, $self->_config_to_data($feed_config, $env) |
221c4151 |
13 | ); |
14 | } |
15 | |
16 | sub _config_to_data { |
da140bff |
17 | my ($self, $config, $env) = @_; |
18 | my $url_scheme = $env->{'psgi.url_scheme'} || "http"; |
19 | my $url_port = $env->{SERVER_PORT}||80; |
20 | my $base_url = URI->new( |
21 | $url_scheme |
22 | .'://' |
23 | .($env->{HTTP_HOST} |
24 | or ( |
25 | ($env->{SERVER_NAME} || "") |
26 | .($url_scheme eq 'http' && $url_port == 80 |
27 | ? '' |
28 | : ":${url_port}" |
29 | ) |
30 | )) |
31 | .($env->{SCRIPT_NAME} || '/') |
32 | ); |
33 | my $abs = sub { URI->new_abs($_[0], $base_url)->as_string }; |
221c4151 |
34 | my $base_page = $self->pages->get({ path => $config->{base} }); |
35 | my @entry_pages = $base_page->children(%{$config->{entries}}) |
36 | ->latest(10)->flatten; |
b0df368c |
37 | my $updated = (sort map $_->created, @entry_pages)[-1]; |
221c4151 |
38 | +{ |
39 | %$config, |
da140bff |
40 | id => $abs->("feed/${\$config->{base}}/"), |
41 | web_url => $abs->($config->{base}.'/'), |
42 | feed_url => $abs->("feed/${\$config->{base}}/"), |
b0df368c |
43 | updated => join('T', split(' ',$updated)).'Z', |
da140bff |
44 | entries => [ map { |
45 | my $page_url = $abs->(do { (my $p = $_->path) =~ s/^\///; "$p/" }); |
46 | +{ |
47 | title => $_->title, |
48 | summary_html => do { |
49 | use HTML::Tags; |
50 | join '', HTML::Tags::to_html_string(<p>, $_->description, </p>) |
51 | }, |
52 | content_html => $self->_absolutify_html($_->body, $base_url, $page_url), |
53 | created => join('T', split(' ',$_->created)).'Z', |
54 | web_url => $page_url, |
55 | } |
56 | } @entry_pages ], |
221c4151 |
57 | } |
58 | } |
59 | |
221c4151 |
60 | sub _feed_response { |
61 | my ($self, $code, $data) = @_; |
62 | [ $code, |
63 | [ 'Content-type' => 'application/atom+xml' ], |
64 | [ $self->_feed_string($data) ] |
65 | ] |
66 | } |
67 | |
68 | sub _feed_string { |
69 | my ($self, $data) = @_; |
70 | XML::Tags::to_xml_string( |
71 | $self->_feed_data_to_tags($data) |
72 | ); |
73 | } |
74 | |
75 | sub _feed_data_to_tags { |
76 | my ($self, $data) = @_; |
77 | use XML::Tags qw( |
78 | feed title subtitle link id |
79 | ); |
80 | my ($web_url, $feed_url) = @{$data}{qw(web_url feed_url)}; |
8509b33b |
81 | (\'<?xml version="1.0" encoding="UTF-8"?>', "\n", |
82 | <feed xmlns="http://www.w3.org/2005/Atom">, "\n", |
83 | ' ', <title type="text">, $data->{title}, </title>, "\n", |
221c4151 |
84 | ($data->{subtitle} |
8509b33b |
85 | ? (' ', <subtitle type="text">, $data->{subtitle}, </subtitle>, "\n",) |
221c4151 |
86 | : ()), |
8509b33b |
87 | ' ', <link rel="alternate" type="text/html" href="${web_url}" />, "\n", |
88 | ' ', <link rel="self" type="application/atom+xml" href="${feed_url}" />, "\n", |
b0df368c |
89 | ' ', <updated>, $data->{updated}, </updated>, "\n", |
8509b33b |
90 | ' ', <id>, $data->{id}, </id>, "\n", |
221c4151 |
91 | (map $self->_entry_data_to_tags($_), @{$data->{entries}}), |
92 | </feed>); |
93 | } |
94 | |
95 | sub _entry_data_to_tags { |
96 | my ($self, $data) = @_; |
b0df368c |
97 | use XML::Tags qw( |
98 | entry title author name link id published updated summary content |
99 | ); |
221c4151 |
100 | my $web_url = $data->{web_url}; |
8509b33b |
101 | ' ', <entry>, "\n", |
102 | ' ', <title>, $data->{title}, </title>, "\n", |
b0df368c |
103 | ' ', <author>, <name>, "Shadowcat Staff", </name>, </author>, "\n", |
8509b33b |
104 | ' ', <link href="${web_url}" />, "\n", |
da140bff |
105 | ' ', <id>, $web_url, </id>, "\n", |
8509b33b |
106 | ' ', <published>, $data->{created}, </published>, "\n", |
107 | ' ', <updated>, ($data->{created}||$data->{updated}), </updated>, "\n", |
221c4151 |
108 | ($data->{summary_html} |
b0df368c |
109 | ? (' ', <summary type="html">, \('<![CDATA['.$data->{summary_html}.']]>'), </summary>, "\n") |
221c4151 |
110 | : () |
111 | ), |
b0df368c |
112 | ' ', <content type="html">, \('<![CDATA['.$data->{content_html}.']]>'), </content>, "\n", |
8509b33b |
113 | ' ', </entry>, "\n"; |
221c4151 |
114 | } |
115 | |
da140bff |
116 | sub _absolutify_html { |
117 | my ($self, $html, $base_url, $page_url) = @_; |
118 | $html; |
119 | } |
120 | |
221c4151 |
121 | 1; |