website/generator/feeds.py
2025-02-15 14:51:00 +00:00

91 lines
3.2 KiB
Python

import datetime
import json as libjson
import xml.etree.ElementTree as ElementTree
from typedef import *
from util import *
def _format_atom_date(date: datetime.date) -> str:
return date_to_datetime(date).astimezone(datetime.timezone.utc).isoformat()
def _get_feed_title(site_config: any) -> str:
return f"{site_config['person']['nickname']}'s blog"
def atom(site_config: any, posts: list[AbbreviatedPost]) -> str:
root = ElementTree.Element("feed", xmlns="http://www.w3.org/2005/Atom")
blog_url = get_absolute_url(site_config, "/blog/")
feed_url = get_absolute_url(site_config, "/blog/feed.atom")
ElementTree.SubElement(root, "title").text = _get_feed_title(site_config)
ElementTree.SubElement(root, "id").text = blog_url
ElementTree.SubElement(root, "updated").text = (
_format_atom_date(
max(
[post.publishedDate for post in posts]
+ [post.updatedDate for post in posts if post.updatedDate is not None]
)
)
if len(posts) != 0
else ""
)
_atom_link(root, blog_url, rel="alternate")
_atom_link(root, feed_url, rel="self")
ElementTree.SubElement(
ElementTree.SubElement(root, "author"),
"name",
).text = f"{site_config['person']['firstName']} {site_config['person']['surname']}"
for post in posts:
entry = ElementTree.SubElement(root, "entry")
ElementTree.SubElement(entry, "title").text = post.title
ElementTree.SubElement(entry, "updated").text = _format_atom_date(
post.updatedDate if post.updatedDate is not None else post.publishedDate
)
ElementTree.SubElement(entry, "id").text = post.slug
_atom_link(entry, get_absolute_url(site_config, f"/blog/{post.slug}/"))
ElementTree.SubElement(entry, "summary", type="text").text = post.description
ElementTree.indent(root) # pretty formatting
return ElementTree.tostring(root, xml_declaration=True, encoding="unicode")
def _atom_link(entry: ElementTree.Element, href: str, rel: str | None = None):
kwargs = {"href": href}
if rel is not None:
kwargs["rel"] = rel
ElementTree.SubElement(entry, "link", **kwargs)
def json(site_config: any, posts: list[AbbreviatedPost]) -> str:
root = {
"version": "https://jsonfeed.org/version/1.1",
"title": _get_feed_title(site_config),
"home_page_url": get_absolute_url(site_config, "/blog/"),
"feed_url": get_absolute_url(site_config, "/blog/feed.json"),
"authors": [
{
"name": f"{site_config['person']['firstName']} {site_config['person']['surname']}"
}
],
"items": [],
}
for post in posts:
x = {
"id": post.slug,
"url": get_absolute_url(site_config, f"/blog/{post.slug}/"),
"title": post.title,
"content_text": "",
"date_published": _format_atom_date(post.publishedDate),
}
if post.description != "":
x["summary"] = post.description
if post.updatedDate is not None:
x["date_modified"] = _format_atom_date(post.updatedDate)
root["items"].append(x)
return libjson.dumps(root, indent="\t")