diff --git a/Dockerfile.gemini b/Dockerfile.gemini index e77eb5c..426d8c4 100644 --- a/Dockerfile.gemini +++ b/Dockerfile.gemini @@ -1,6 +1,8 @@ FROM alpine:latest -RUN apk add perl lowdown WORKDIR /app -COPY generate_capsule.sh . -ENTRYPOINT [ "./generate_capsule.sh" ] +COPY requirements.txt . +RUN apk add python3 py3-pip lowdown \ + && python3 -m pip install -r requirements.txt --break-system-packages +COPY generate_capsule.py . +ENTRYPOINT [ "python3", "generate_capsule.py" ] diff --git a/_config.yml b/_config.yml index afbadbc..fe06aa8 100644 --- a/_config.yml +++ b/_config.yml @@ -6,7 +6,8 @@ exclude: - Dockerfile* - compose.yaml - Makefile - - generate_capsule.sh + - generate_capsule.py + - requirements.txt jekyll_compose: default_front_matter: diff --git a/generate_capsule.py b/generate_capsule.py new file mode 100644 index 0000000..3a20158 --- /dev/null +++ b/generate_capsule.py @@ -0,0 +1,83 @@ +import glob +import os +import subprocess +from datetime import datetime + +import frontmatter + +if not os.path.exists("_capsule"): + os.makedirs("_capsule") + +with open("_layouts/home.gmi", mode="r", encoding="utf8") as file: + home_body = file.read() +with open("_layouts/article.gmi", mode="r", encoding="utf8") as file: + article_body = file.read() +with open("_includes/header.gmi", mode="r", encoding="utf8") as file: + header_body = file.read() +with open("_includes/footer.gmi", mode="r", encoding="utf8") as file: + footer_body = file.read() +with open("_includes/links.gmi", mode="r", encoding="utf8") as file: + links_body = file.read() + +articles = glob.glob("_posts/*.md") +if os.getenv("GEMINI_ENV") != "production": + articles += glob.glob("_drafts/*.md") + +today = datetime.today().strftime("%Y-%m-%d") +year = datetime.today().strftime("%Y") + +articles_list = [] + +for article in articles: + gmi = article.replace("_posts/", "").replace("_drafts/", "").replace(".md", ".gmi") + + fm = frontmatter.load(article) + article_title = fm.get("title") + article_date = fm.get("date") + + links = fm.get("links", "end") + + result = subprocess.run( + ["lowdown", "-tgemini", f"--gemini-link-{links}", article], + capture_output=True, + text=True, + ) + article_content = result.stdout + + if article_date is None: + article_date = today + gmi = f"{article_date}-{gmi}" + elif isinstance(article_date, str): + article_date = datetime.fromisoformat(article_date).strftime("%Y-%m-%d") + + body = ( + article_body.replace("%%header%%", header_body) + .replace("%%links%%", links_body) + .replace("%%title%%", f"{article_title}\n{article_date}\n") + .replace("%%body%%", article_content) + .replace("%%footer%%", footer_body) + .replace("%%year%%", year) + ) + + articles_list.append(f"=> {gmi} {article_date} {article_title}") + with open(f"_capsule/{gmi}", mode="w", encoding="utf8") as file: + file.write(body) + +articles_list.sort(reverse=True) + +result = subprocess.run( + ["lowdown", "-tgemini", "index.md"], capture_output=True, text=True +) +home_content = result.stdout + +body = ( + home_body.replace("%%header%%", header_body) + .replace("%%links%%", links_body) + .replace("%%body%%", home_content) + .replace("%%articles%%", "\n".join(articles_list)) + .replace("%%footer%%", footer_body) + .replace("%%year%%", year) +) + +with open("_capsule/index.gmi", mode="w", encoding="utf8") as file: + file.write(body) diff --git a/generate_capsule.sh b/generate_capsule.sh deleted file mode 100755 index 40ccb0b..0000000 --- a/generate_capsule.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env sh - -mkdir -p _capsule - -articles_list="" - -current_year=$(date +%Y) -header_body=$(cat _includes/header.gmi) -footer_body=$(cat _includes/footer.gmi) -links_body=$(cat _includes/links.gmi) - -for post in $(ls _posts/*.md); do - article_title=$(lowdown -X title $post) - article_date=$(lowdown -X date $post | awk '{print $1}') - article_body=$(lowdown -tgemini $post) - - echo "Rendering post $article_title..." - - gemfile=$post - gemfile=${gemfile/_posts/_capsule} - gemfile=${gemfile/.md/.gmi} - - cat _layouts/article.gmi \ - | perl -pe "s|%%header%%|${header_body}|" \ - | perl -pe "s|%%links%%|${links_body}|" \ - | perl -pe "s|%%title%%|${article_title}\n${article_date}\n|" \ - | perl -pe "s|%%body%%|${article_body}|" \ - | perl -pe "s|%%footer%%|${footer_body}|" \ - | perl -pe "s|%%year%%|${current_year}|" \ - > $gemfile - - articles_list="$articles_list=> ${gemfile/_capsule\//} $article_date $article_title\n" -done - -drafts_list="" - -if [ "${GEMINI_ENV}" != 'production' ]; then - for post in $(ls _drafts/*.md); do - article_title=$(lowdown -X title $post) - article_body=$(lowdown -tgemini $post) - - echo "Rendering draft $article_title..." - - gemfile=$post - gemfile=${gemfile/_drafts/_capsule} - gemfile=${gemfile/.md/.gmi} - - cat _layouts/article.gmi \ - | perl -pe "s|%%header%%|${header_body}|" \ - | perl -pe "s|%%links%%|${links_body}|" \ - | perl -pe "s|%%title%%|${article_title}|" \ - | perl -pe "s|%%body%%|${article_body}|" \ - | perl -pe "s|%%footer%%|${footer_body}|" \ - | perl -pe "s|%%year%%|${current_year}|" \ - > $gemfile - - drafts_list="$drafts_list=> ${gemfile/_capsule\//} $article_title\n" - done -fi - -echo "Rendering index..." - -index_body=$(lowdown -tgemini index.md) - -articles="" -if [ ! -z "$articles_list" ]; then - articles="## Articles\n\n${articles_list}" -fi - -drafts="" -if [ ! -z "$drafts_list" ]; then - drafts="## Drafts\n\n${drafts_list}" -fi - -cat _layouts/home.gmi \ - | perl -pe "s|%%header%%|${header_body}|" \ - | perl -pe "s|%%links%%|${links_body}|" \ - | perl -pe "s|%%body%%|${index_body}|" \ - | perl -pe "s|%%articles%%|${articles}|" \ - | perl -pe "s|%%drafts%%|${drafts}|" \ - | perl -pe "s|%%footer%%|${footer_body}|" \ - | perl -pe "s|%%year%%|${current_year}|" \ - > _capsule/index.gmi - -echo "Done" diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..f0499e4 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +packaging==24.2 +pyparsing==3.1.4 +python-frontmatter==1.1.0 +PyYAML==6.0.2 +setuptools==70.3.0