python-refactor (#1)

While writing a new article, I was having issues with Perl making the replacements (it was trying to execute fenced code blocks). After a little bit of research, trying to keep the original script, I decided to keep things simpler and rewrite the generator script with Python instead.

Reviewed-on: #1
This commit is contained in:
Erick Ruiz de Chavez 2024-12-29 07:49:19 -05:00
parent a7cd4f12c5
commit c875c07933
12 changed files with 109 additions and 97 deletions

View file

@ -1,6 +1,8 @@
FROM alpine:latest FROM alpine:latest
RUN apk add perl lowdown
WORKDIR /app WORKDIR /app
COPY generate_capsule.sh . COPY requirements.txt .
ENTRYPOINT [ "./generate_capsule.sh" ] 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" ]

View file

@ -3,7 +3,7 @@ GEM
specs: specs:
addressable (2.8.7) addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0) public_suffix (>= 2.0.2, < 7.0)
bigdecimal (3.1.8) bigdecimal (3.1.9)
colorator (1.1.0) colorator (1.1.0)
commonmarker (0.23.11) commonmarker (0.23.11)
concurrent-ruby (1.3.4) concurrent-ruby (1.3.4)
@ -81,4 +81,4 @@ DEPENDENCIES
jekyll-feed (~> 0.12) jekyll-feed (~> 0.12)
BUNDLED WITH BUNDLED WITH
2.6.1 2.6.2

View file

@ -6,7 +6,8 @@ exclude:
- Dockerfile* - Dockerfile*
- compose.yaml - compose.yaml
- Makefile - Makefile
- generate_capsule.sh - generate_capsule.py
- requirements.txt
jekyll_compose: jekyll_compose:
default_front_matter: default_front_matter:

View file

@ -1,6 +1,7 @@
--- ---
layout: article layout: article
title: Live Long and Prosper with These Tools title: Live Long and Prosper with These Tools
links: inline
--- ---
I'm not entirely sure why, but I love trying out and testing productivity tools—especially those geared toward programming. Over the years, I've explored and used a wide variety of tools, and these are the ones I can't live without. Below, I've listed them in alphabetical order. For each, I'll include a brief description and explain why it stands out to me. When time and inspiration allow, I plan to write dedicated articles diving deeper into each tool. I'll also do my best to keep this list updated as I discover new favorites or stop using the current ones. I'm not entirely sure why, but I love trying out and testing productivity tools—especially those geared toward programming. Over the years, I've explored and used a wide variety of tools, and these are the ones I can't live without. Below, I've listed them in alphabetical order. For each, I'll include a brief description and explain why it stands out to me. When time and inspiration allow, I plan to write dedicated articles diving deeper into each tool. I'll also do my best to keep this list updated as I discover new favorites or stop using the current ones.
@ -23,7 +24,7 @@ To help you understand the labels I've used, here's a quick guide to the emojis
### Apps ### Apps
- 1Password (💻,📱,🧭,🔃,🌐) - [1Password (💻,📱,🧭,🔃,🌐)](https://1password.com)
- AdGuard Pro (💻,📱,🧭,🔃,A,🌐) - AdGuard Pro (💻,📱,🧭,🔃,A,🌐)
- Alfred (💻,1⃣,🌐) - Alfred (💻,1⃣,🌐)
- Arq (💻,1⃣,🌐) - Arq (💻,1⃣,🌐)

View file

@ -2,9 +2,9 @@
layout: default layout: default
--- ---
<div class="article"> <div class="article">
<h1 class="article__title"> <h2 class="article__title">
{{ page.title | escape }} {{ page.title | escape }}
</h1> </h2>
<time class="article__published"> <time class="article__published">
{{ page.date | date: "%Y-%m-%d" }} {{ page.date | date: "%Y-%m-%d" }}
</time> </time>

View file

@ -1,6 +1,6 @@
%%header%% %%header%%
%%body%% %%body%%
## Articles
%%articles%% %%articles%%
%%drafts%%
%%links%% %%links%%
%%footer%% %%footer%%

View file

@ -1,8 +1,9 @@
--- ---
layout: article layout: article
title: Regenerating My Blog - A Fresh Start title: 'Regenerating My Blog: A Fresh Start'
date: 2024-12-22 00:45 +0000 date: 2024-12-22 00:45 +0000
--- ---
Hey there! Looks like Im back to writing after some time away. Over the years, Ive started many blogs and personal sites, experimenting with different technologies and styles. And here I am again, excited to share my thoughts with you. Hey there! Looks like Im back to writing after some time away. Over the years, Ive started many blogs and personal sites, experimenting with different technologies and styles. And here I am again, excited to share my thoughts with you.
Even though Ive never considered myself a great writer, the idea of having a blog to share my thoughts, experiences, and ideas has always been in the back of my mind. This time, Im keeping it simple—sharing small bits whenever inspiration strikes. Even though Ive never considered myself a great writer, the idea of having a blog to share my thoughts, experiences, and ideas has always been in the back of my mind. This time, Im keeping it simple—sharing small bits whenever inspiration strikes.

View file

@ -1,12 +1,16 @@
services: services:
jekyll: jekyll:
build: . build:
context: .
dockerfile: Dockerfile.jekyll
platform: linux/amd64 platform: linux/amd64
ports: ports:
- 4000:4000 - 4000:4000
- 35729:35729 - 35729:35729
volumes: volumes:
- .:/app - .:/app
gemini: gemini:
build: build:
context: . context: .

83
generate_capsule.py Normal file
View file

@ -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)

View file

@ -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"

5
requirements.txt Normal file
View file

@ -0,0 +1,5 @@
packaging==24.2
pyparsing==3.1.4
python-frontmatter==1.1.0
PyYAML==6.0.2
setuptools==70.3.0