website/lib/Atom.rakumod

63 lines
2.1 KiB
Raku

use v6.e.PREVIEW;
use DB::Post;
use DB::BlogMeta;
use Render::Util;
use XML;
unit module Atom;
#| Convert a single post to an atom item
sub post-to-item(BlogMeta:D $meta, Int:D $id, Post:D $post --> XML::Element) {
my $link = post-link-abs $meta, $id, $post;
my $desc = $post.description;
my $xml = XML::Element.new(:name<entry>);
$xml.append:
XML::Element.new(:name<id>, :nodes([$link]));
$xml.append:
XML::Element.new(:name<title>, :nodes([$post.title]));
$xml.append:
XML::Element.new(:name<updated>, :nodes([$post.updated]));
$xml.append:
XML::Element.new(:name<published>, :nodes([$post.posted-at]));
my $author = XML::Element.new(:name<author>);
$author.append:
XML::Element.new(:name<email>, :nodes(["thatonelutenist@stranger.systems"]));
$author.append:
XML::Element.new(:name<name>, :nodes(["Nathan McCarty"]));
$xml.append: $author;
$xml.append:
XML::Element.new(:name<link>, :attribs({:href($link), :rel<alternate>}));
# TODO: Actually embed the content
$xml.append:
XML::Element.new(:name<content>, :attribs({:src($link), :type<html>}));
$xml.append:
XML::Element.new(:name<summary>, :nodes([$desc])) if $desc;
if $post.tags {
for $post.tags -> $tag {
$xml.append:
XML::Element.new(:name<category>, :attribs({:term($tag)}));
}
}
$xml
}
#| Produce an atom feed from the database
sub posts-to-atom($db --> XML::Element) is export {
my $updated = $db.posts.values.map(*.updated).max;
my $xml =
XML::Element.new(
:name<feed>,
:attribs({:xmlns('http://www.w3.org/2005/Atom')}));
$xml.append: XML::Element.new(:name<id>, :nodes([$db.meta.get-base-url]));
$xml.append: XML::Element.new(:name<title>, :nodes([$db.meta.title]));
$xml.append: XML::Element.new(:name<updated>, :nodes([$updated]));
for $db.sorted-posts -> $pair {
unless $pair.value.hidden {
$xml.append: post-to-item $db.meta, $pair.key, $pair.value;
}
}
$xml
}