From d93c0a86bce426be0b1e276e0664aaf908402621 Mon Sep 17 00:00:00 2001 From: Kumi Date: Tue, 23 Jul 2024 08:54:35 +0200 Subject: [PATCH 1/6] chore: update .gitignore to ignore build artifacts and venv Renamed .hugo-build.lock to .hugo_build.lock to match actual file naming. Added venv/ to ignore list to prevent virtual environment files from being tracked, avoiding unnecessary clutter in the repository. --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 2caa929..0c06b83 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ .DS_Store public/ resources/ -.hugo-build.lock \ No newline at end of file +.hugo_build.lock +venv/ \ No newline at end of file From c10217ea486873fad8692b54cbb08dadf0f29d57 Mon Sep 17 00:00:00 2001 From: Kumi Date: Tue, 23 Jul 2024 08:55:07 +0200 Subject: [PATCH 2/6] feat: Added template SVG for weekly post cover image --- assets/img/cover-template.svg | 4493 +++++++++++++++++++++++++++++++++ 1 file changed, 4493 insertions(+) create mode 100644 assets/img/cover-template.svg diff --git a/assets/img/cover-template.svg b/assets/img/cover-template.svg new file mode 100644 index 0000000..919813f --- /dev/null +++ b/assets/img/cover-template.svg @@ -0,0 +1,4493 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + __TITLE__ + __DATE__ + __SITE__ + + + + From f3207b7a7df2c327deacb48c8f0f4fa1f8a3bad3 Mon Sep 17 00:00:00 2001 From: Kumi Date: Tue, 23 Jul 2024 08:55:43 +0200 Subject: [PATCH 3/6] feat: automate creation of new weekly issue Added a new Python script to automate the creation of new weekly issues for the site. The script determines the latest issue number, generates a new one, and includes creation of a cover image with relevant dates. This streamlines the weekly update process and ensures consistency. This script is work in progress and will get additional features. --- new_issue.py | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100755 new_issue.py diff --git a/new_issue.py b/new_issue.py new file mode 100755 index 0000000..b2a77e4 --- /dev/null +++ b/new_issue.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python3 + +import subprocess +import pathlib +import argparse +import datetime +import tempfile +import tomllib + +def create_issue(issue_number): + subprocess.run(['hugo', 'new', f'weekly/issue-{issue_number}/_index.md']) + +def create_issue_image(site_title, issue_number, period_start, period_end): + with open('assets/img/cover-template.svg') as f: + cover_template = f.read() + + cover_template = cover_template.replace('__SITE__', site_title) + cover_template = cover_template.replace('__ISSUE__', issue_number) + cover_template = cover_template.replace('__DATE__', f'{period_start} - {period_end}') + + with tempfile.TemporaryDirectory() as tempdir: + cover_path = pathlib.Path(tempdir) / 'cover.svg' + with open(cover_path, 'w') as f: + f.write(cover_template) + + subprocess.run(['inkscape', str(cover_path), '-e', f'content/weekly/issue-{issue_number}/cover.png']) + + +def get_latest_issue(): + issues = list(pathlib.Path('content/weekly').iterdir()) + latest_issue = max(issues, key=lambda x: int(x.name.split('-')[1])) + return latest_issue.name.split('-')[1] + +if __name__ == '__main__': + with open('hugo.toml', "rb") as f: + hugo_config = tomllib.load(f) + + parser = argparse.ArgumentParser(description='Create a new issue') + parser.add_argument('--issue', type=int, help='Issue number') + args = parser.parse_args() + + if args.issue: + new_issue = args.issue + else: + latest_issue = get_latest_issue() + new_issue = int(latest_issue) + 1 + + period_start = datetime.datetime.now().strftime('%Y-%m-%d') + period_end = (datetime.datetime.now() + datetime.timedelta(days=7)).strftime('%Y-%m-%d') + + create_issue(new_issue) + \ No newline at end of file From e231c4d8c5de333f6a2d5a406fc3486379bcbd51 Mon Sep 17 00:00:00 2001 From: Kumi Date: Tue, 23 Jul 2024 08:56:14 +0200 Subject: [PATCH 4/6] refactor: improve code readability and formatting Unified string quotes and used consistent indentation to enhance the readability of the script. Refactored the creation of issue cover image for better clarity and maintainability. These changes optimize future code reviews and reduce the potential for errors. --- new_issue.py | 73 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 43 insertions(+), 30 deletions(-) diff --git a/new_issue.py b/new_issue.py index b2a77e4..5b58e2d 100755 --- a/new_issue.py +++ b/new_issue.py @@ -7,46 +7,59 @@ import datetime import tempfile import tomllib + def create_issue(issue_number): - subprocess.run(['hugo', 'new', f'weekly/issue-{issue_number}/_index.md']) + subprocess.run(["hugo", "new", f"weekly/issue-{issue_number}/_index.md"]) + def create_issue_image(site_title, issue_number, period_start, period_end): - with open('assets/img/cover-template.svg') as f: - cover_template = f.read() + with open("assets/img/cover-template.svg") as f: + cover_template = f.read() - cover_template = cover_template.replace('__SITE__', site_title) - cover_template = cover_template.replace('__ISSUE__', issue_number) - cover_template = cover_template.replace('__DATE__', f'{period_start} - {period_end}') + cover_template = cover_template.replace("__SITE__", site_title) + cover_template = cover_template.replace("__ISSUE__", issue_number) + cover_template = cover_template.replace( + "__DATE__", f"{period_start} - {period_end}" + ) - with tempfile.TemporaryDirectory() as tempdir: - cover_path = pathlib.Path(tempdir) / 'cover.svg' - with open(cover_path, 'w') as f: - f.write(cover_template) + with tempfile.TemporaryDirectory() as tempdir: + cover_path = pathlib.Path(tempdir) / "cover.svg" + with open(cover_path, "w") as f: + f.write(cover_template) + + subprocess.run( + [ + "inkscape", + str(cover_path), + "-e", + f"content/weekly/issue-{issue_number}/cover.png", + ] + ) - subprocess.run(['inkscape', str(cover_path), '-e', f'content/weekly/issue-{issue_number}/cover.png']) - def get_latest_issue(): - issues = list(pathlib.Path('content/weekly').iterdir()) - latest_issue = max(issues, key=lambda x: int(x.name.split('-')[1])) - return latest_issue.name.split('-')[1] + issues = list(pathlib.Path("content/weekly").iterdir()) + latest_issue = max(issues, key=lambda x: int(x.name.split("-")[1])) + return latest_issue.name.split("-")[1] -if __name__ == '__main__': - with open('hugo.toml', "rb") as f: - hugo_config = tomllib.load(f) - parser = argparse.ArgumentParser(description='Create a new issue') - parser.add_argument('--issue', type=int, help='Issue number') - args = parser.parse_args() +if __name__ == "__main__": + with open("hugo.toml", "rb") as f: + hugo_config = tomllib.load(f) - if args.issue: - new_issue = args.issue - else: - latest_issue = get_latest_issue() - new_issue = int(latest_issue) + 1 + parser = argparse.ArgumentParser(description="Create a new issue") + parser.add_argument("--issue", type=int, help="Issue number") + args = parser.parse_args() - period_start = datetime.datetime.now().strftime('%Y-%m-%d') - period_end = (datetime.datetime.now() + datetime.timedelta(days=7)).strftime('%Y-%m-%d') + if args.issue: + new_issue = args.issue + else: + latest_issue = get_latest_issue() + new_issue = int(latest_issue) + 1 - create_issue(new_issue) - \ No newline at end of file + period_start = datetime.datetime.now().strftime("%Y-%m-%d") + period_end = (datetime.datetime.now() + datetime.timedelta(days=7)).strftime( + "%Y-%m-%d" + ) + + create_issue(new_issue) From 3968fd42481137e28d87e8c089e42c0cc05d235d Mon Sep 17 00:00:00 2001 From: Kumi Date: Tue, 23 Jul 2024 09:30:02 +0200 Subject: [PATCH 5/6] feat(issue-creation): add period input and title update Enhanced the issue creation script by adding functionality to input and format the period dates when creating new issues. The script now supports custom period start and end dates and updates the issue title accordingly in the markdown file. This change ensures more accurate issue titles and periods, improving clarity and organization of issues. Additionally added error handling for the Hugo command and Python file operations, improving robustness and reliability. --- new_issue.py | 141 +++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 125 insertions(+), 16 deletions(-) diff --git a/new_issue.py b/new_issue.py index 5b58e2d..41ccdcf 100755 --- a/new_issue.py +++ b/new_issue.py @@ -8,19 +8,104 @@ import tempfile import tomllib -def create_issue(issue_number): - subprocess.run(["hugo", "new", f"weekly/issue-{issue_number}/_index.md"]) +def get_period_string( + start: datetime.datetime, + end: datetime.datetime, + year: bool = False, +) -> str: + """Get a string representation of the period + + Args: + start (datetime.datetime): The start of the period + end (datetime.datetime): The end of the period + year (bool, optional): Include the year in the string. Defaults to False. + + Returns: + str: The period string + """ + if period_start.year == period_end.year: + if period_start.month == period_end.month: + period_string = ( + f"{period_start.strftime('%B %d')} - {period_end.strftime('%d')}" + ) + else: + period_string = ( + f"{period_start.strftime('%B %d')} - {period_end.strftime('%B %d')}" + ) + + if year: + period_string += f", {period_start.year}" + + else: + period_string = ( + f"{period_start.strftime('%B %d, %Y')} - {period_end.strftime('%B %d, %Y')}" + ) + + return period_string -def create_issue_image(site_title, issue_number, period_start, period_end): +def create_issue( + issue_number: int, period_start: datetime.datetime, period_end: datetime.datetime +) -> None: + """Create a new issue + + Args: + issue_number (int): The issue number + period_start (datetime.datetime): The start of the period + period_end (datetime.datetime): The end of the period + + Raises: + subprocess.CalledProcessError: If the Hugo command fails + IOError: If any of the Python file operations fail + """ + subprocess.run( + ["hugo", "new", f"weekly/issue-{issue_number}/_index.md"], check=True + ) + + with open(f"content/weekly/issue-{issue_number}/_index.md", "r") as f: + content = f.read() + + # Get line that starts with "title" and replace it with the new title + lines = content.split("\n") + + period_string = get_period_string(period_start, period_end, True) + + for i, line in enumerate(lines): + if line.startswith("title:"): + lines[i] = f"title: Issue {issue_number} - {period_string}" + + content = "\n".join(lines) + + with open(f"content/weekly/issue-{issue_number}/_index.md", "w") as f: + f.write(content) + + +def create_issue_image( + site_title: str, + issue_number: int, + period_start: datetime.datetime, + period_end: datetime.datetime, +) -> None: + """Create a cover image for the issue + + Args: + site_title (str): The title of the site + issue_number (int): The issue number + period_start (datetime.datetime): The start of the period + period_end (datetime.datetime): The end of the period + + Raises: + FileNotFoundError: If the cover template is not found + IOError: If any of the file operations fail + """ with open("assets/img/cover-template.svg") as f: cover_template = f.read() + period_string = get_period_string(period_start, period_end) + cover_template = cover_template.replace("__SITE__", site_title) - cover_template = cover_template.replace("__ISSUE__", issue_number) - cover_template = cover_template.replace( - "__DATE__", f"{period_start} - {period_end}" - ) + cover_template = cover_template.replace("__TITLE__", f"Issue {issue_number}") + cover_template = cover_template.replace("__DATE__", period_string) with tempfile.TemporaryDirectory() as tempdir: cover_path = pathlib.Path(tempdir) / "cover.svg" @@ -31,16 +116,21 @@ def create_issue_image(site_title, issue_number, period_start, period_end): [ "inkscape", str(cover_path), - "-e", + "--export-filename", f"content/weekly/issue-{issue_number}/cover.png", ] ) -def get_latest_issue(): +def get_latest_issue() -> int: + """Get the latest issue number from the weekly directory + + Returns: + int: The latest issue number + """ issues = list(pathlib.Path("content/weekly").iterdir()) latest_issue = max(issues, key=lambda x: int(x.name.split("-")[1])) - return latest_issue.name.split("-")[1] + return int(latest_issue.name.split("-")[1]) if __name__ == "__main__": @@ -49,17 +139,36 @@ if __name__ == "__main__": parser = argparse.ArgumentParser(description="Create a new issue") parser.add_argument("--issue", type=int, help="Issue number") + parser.add_argument("--period-start", type=str, help="Period start") + parser.add_argument("--period-end", type=str, help="Period end") + parser.add_argument("--quiet", "-q", action="store_true", help="Quiet mode") args = parser.parse_args() + if not (args.period_start and args.period_end): + if not args.quiet: + # Query the user for the period start and end + today = datetime.datetime.now().strftime("%Y-%m-%d") + + period_start_str = input(f"Period start [{today}]: ") or today + period_start = datetime.datetime.strptime(period_start_str, "%Y-%m-%d") + + seven_days = (period_start + datetime.timedelta(days=7)).strftime( + "%Y-%m-%d" + ) + + period_end_str = input(f"Period end [{seven_days}]: ") or seven_days + period_end = datetime.datetime.strptime(period_end_str, "%Y-%m-%d") + + else: + # Assume the period is the next 7 days - # TODO: Check if this is correct + period_start = datetime.datetime.now() + period_end = datetime.datetime.now() + datetime.timedelta(days=7) + if args.issue: new_issue = args.issue else: latest_issue = get_latest_issue() new_issue = int(latest_issue) + 1 - period_start = datetime.datetime.now().strftime("%Y-%m-%d") - period_end = (datetime.datetime.now() + datetime.timedelta(days=7)).strftime( - "%Y-%m-%d" - ) - - create_issue(new_issue) + create_issue(new_issue, period_start, period_end) + create_issue_image(hugo_config["title"], new_issue, period_start, period_end) From cf25a22641a446f59c885a5f5d27a443490d3427 Mon Sep 17 00:00:00 2001 From: Kumi Date: Tue, 23 Jul 2024 09:31:16 +0200 Subject: [PATCH 6/6] feat(issues): add comments for subprocess and file ops Added explanatory comments for steps using the Hugo CLI to generate new issues and subsequent file operations, improving code readability and maintainability. No functional changes were made. --- new_issue.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/new_issue.py b/new_issue.py index 41ccdcf..504d0aa 100755 --- a/new_issue.py +++ b/new_issue.py @@ -58,10 +58,12 @@ def create_issue( subprocess.CalledProcessError: If the Hugo command fails IOError: If any of the Python file operations fail """ + # Use the Hugo CLI to create a new issue subprocess.run( ["hugo", "new", f"weekly/issue-{issue_number}/_index.md"], check=True ) + # Read the content of the new file with open(f"content/weekly/issue-{issue_number}/_index.md", "r") as f: content = f.read() @@ -76,6 +78,7 @@ def create_issue( content = "\n".join(lines) + # Overwrite the file with the new content with open(f"content/weekly/issue-{issue_number}/_index.md", "w") as f: f.write(content)