diff options
Diffstat (limited to 'blog')
| -rw-r--r-- | blog/atom.py | 34 | ||||
| -rw-r--r-- | blog/blog.py | 4 | ||||
| -rw-r--r-- | blog/feed.py | 9 | ||||
| -rw-r--r-- | blog/post.py | 50 | 
4 files changed, 70 insertions, 27 deletions
| diff --git a/blog/atom.py b/blog/atom.py new file mode 100644 index 0000000..e6d836c --- /dev/null +++ b/blog/atom.py @@ -0,0 +1,34 @@ +import os +import datetime +import functools +from typing import List + +from jinja2 import Template + +import render +from post import Post, remove_drafts + + +class Atom(object): +    template: Template +    posts: List[Post] + +    def __init__(self, template: Template, posts: List[Post]) -> None: +        self.template = template +        self.posts = remove_drafts(posts) + +    @staticmethod +    def _now() -> datetime.datetime: +        now = datetime.datetime.now(datetime.timezone.utc) +        return now.replace(microsecond=0) + +    @functools.cached_property +    def updated(self) -> datetime.datetime: +        if not self.posts: +            return self._now() +        return self.posts[0].metadata.updated + +    def generate(self, basedir: str) -> None: +        atom = os.path.join(basedir, "atom.xml") +        rendered = self.template.render(updated=self.updated, posts=self.posts) +        render.write_file_content(atom, rendered) diff --git a/blog/blog.py b/blog/blog.py index 27845bc..4b9a345 100644 --- a/blog/blog.py +++ b/blog/blog.py @@ -10,6 +10,7 @@ from jinja2 import Template, Environment, FileSystemLoader, select_autoescape  from post import Post  from feed import Feed +from atom import Atom  def recreate_workdir(basedir: str) -> None: @@ -49,6 +50,9 @@ def generate_blog() -> None:      feed = Feed(env.get_template("feed.html"), posts)      feed.generate(workdir) +    atom = Atom(env.get_template("atom.xml"), posts) +    atom.generate(workdir) +      copy_share(workdir) diff --git a/blog/feed.py b/blog/feed.py index 3e5b2e0..381aab6 100644 --- a/blog/feed.py +++ b/blog/feed.py @@ -1,10 +1,11 @@  import os +import datetime  from typing import List  from jinja2 import Template  import render -from post import Post +from post import Post, remove_drafts  class Feed(object): @@ -13,11 +14,7 @@ class Feed(object):      def __init__(self, template: Template, posts: List[Post]) -> None:          self.template = template -        self.posts = Feed._remove_drafts(posts) - -    @staticmethod -    def _remove_drafts(posts: List[Post]) -> List[Post]: -        return list(filter(lambda x: x.metadata.status != "draft", posts)) +        self.posts = remove_drafts(posts)      def generate(self, basedir: str) -> None:          index = os.path.join(basedir, "index.html") 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)) |