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