From 96d437baab4a622eb540719feb90ea810fb01756 Mon Sep 17 00:00:00 2001 From: Dmitry Ilvokhin Date: Sat, 19 Apr 2025 21:43:53 +0100 Subject: Add support for atom / rss feed Date format was changed to support `updated` in ISO format. Now every post will require date and time, which might be a usability regression, but we'll see. Also, `updated` field was introduced in metadata. If there is no such field, them date field will be used instead. --- blog/post.py | 50 +++++++++++++++++++++++++++++--------------------- 1 file changed, 29 insertions(+), 21 deletions(-) (limited to 'blog/post.py') diff --git a/blog/post.py b/blog/post.py index 8a7c880..955724a 100644 --- a/blog/post.py +++ b/blog/post.py @@ -2,27 +2,23 @@ import os import shutil import datetime import functools -from typing import Dict +from typing import Dict, List from jinja2 import Template +from dataclasses import dataclass + import render +@dataclass(slots=True) class Metadata(object): - __slots__ = ("title", "author", "date", "status") title: str author: str - date: str + date: datetime.datetime + updated: datetime.datetime status: str - def __init__(self, title: str, author: str, - date: str, status: str) -> None: - self.title = title - self.author = author - self.date = date - self.status = status - class Post(object): template: Template @@ -52,33 +48,45 @@ class Post(object): title = raw["Title"] author = raw["Author"] - date = raw.get("Date", datetime.date.today().strftime("%Y-%m-%d")) + date = raw["Date"] + updated = raw.get("Updated", date) status = raw.get("Status", "draft") - return Metadata(title, author, date, status) + return Metadata( + title, + author, + datetime.datetime.fromisoformat(date), + datetime.datetime.fromisoformat(updated), + status + ) + + @functools.cached_property + def content(self) -> str: + md = None + for filename in os.listdir(self.directory): + if filename.endswith(".md"): + return render.to_html(os.path.join(self.directory, filename)) + assert False, f"There is no markdown file in `{self.directory}`" def generate(self, basedir: str) -> None: postdir = os.path.basename(self.directory) workdir = os.path.join(basedir, postdir) os.makedirs(workdir) - md = None for filename in os.listdir(self.directory): source = os.path.join(self.directory, filename) destination = os.path.join(workdir, filename) - shutil.copy(source, destination) - if filename.endswith(".md"): - md = source - - assert md, f"There is no markdown file in `{self.directory}`" - - content = render.to_html(md) rendered = self.template.render(title=self.metadata.title, author=self.metadata.author, date=self.metadata.date, + updated=self.metadata.updated, status=self.metadata.status, - content=content) + content=self.content) render.write_file_content(os.path.join(workdir, "index.html"), rendered) + + +def remove_drafts(posts: List[Post]) -> List[Post]: + return list(filter(lambda x: x.metadata.status != "draft", posts)) -- cgit v1.2.3-70-g09d2