#!/usr/bin/env python3 # SPDX-FileCopyrightText: 2021 Luca Beltrame # SPDX-License-Identifier: BSD-3-Clause import argparse from datetime import datetime from pathlib import Path from subprocess import call import shutil from typing import List from atomicwrites import atomic_write import frontmatter from git import Repo import pytz from slugify import slugify import toml POST_PATH = "content/post" TEMPLATE_PATH = "archetypes/post.blank.md" CONFIG = "config.toml" TIMEZONE = pytz.timezone("Europe/Rome") def new_post_title(title: str) -> str: suffix = "md" current_date = datetime.now().date().isoformat() slugified_title = slugify(title) post_title = f"{current_date}-{slugified_title}.{suffix}" return post_title def commit_initial_post(post_title: str, post_filename: str): repo = Repo("./") repo.index.add([str(post_filename)]) template = f"New post: {post_title}" repo.index.commit(template) def edit_post(post_path): with post_path.open() as handle: with atomic_write(str(post_path), overwrite=True, suffix=".md") as writer: writer.write(handle.read()) writer.write("\n\n") writer.flush() print("Save and close the editor when done.") call(["kate", "--new", str(writer.name), "--tempfile", "-l", "22"]) writer.flush() def create_post(post_title: str, tags: List[str] = None, categories: List[str] = None, comments: bool = True, draft: bool = True) -> Path or None: hugo_cmd = shutil.which("hugo") if hugo_cmd is None: print("hugo executable not found in PATH.") return title = new_post_title(post_title) path = Path(POST_PATH) / title shutil.copy(TEMPLATE_PATH, path) with open(CONFIG) as handle: site_config = toml.load(handle) featured_image = site_config["params"]["featured_image"] header = frontmatter.load(path) if categories is not None: header["categories"] = categories if tags is not None: header["tags"] = tags header["draft"] = draft header["comments"] = comments header["title"] = post_title header["featured_image"] = featured_image date = datetime.now(tz=TIMEZONE) # '2021-01-09 02:14:57+01:00' header["date"] = date.isoformat(timespec="seconds", sep=" ") frontmatter.dump(header, path) print(f"{path} created.") return path def main(): parser = argparse.ArgumentParser() parser.add_argument("-t", "--tags", nargs="+", help="Post tags (space separated)") parser.add_argument("-c", "--categories", nargs="+", help="Post categories (space separated)") parser.add_argument("--disable_comments", action="store_false", help="Disable comments for the post") parser.add_argument("--commit", action="store_true", help="Commit to the repository") parser.add_argument("--draft", action="store_true", help="Create the post as draft") parser.add_argument("--edit", action="store_true", help="Edit the post after creation") parser.add_argument("title", help="Title of the new post") options = parser.parse_args() post_path = create_post(options.title, options.tags, options.categories, comments=options.disable_comments) if post_path is not None: if options.edit: edit_post(post_path) if options.commit: commit_initial_post(options.title, post_path) if __name__ == "__main__": main()