My personal website and Gemini capsule

-scripts/

Changed files
-158
scripts
-146
scripts/blog2gemlog
···
-
#!/usr/bin/env -S uv run --script
-
# /// script
-
# dependencies = [
-
# "feedgen",
-
# "feedparser",
-
# "md2gemini",
-
# ]
-
# ///
-
-
# 1. Take a markdown blog post as input, convert it to gemtext.
-
# 2. Update gemlog index.
-
# 3. Update the gemlog Atom feed.
-
-
import sys
-
from datetime import datetime
-
from pathlib import Path
-
from zoneinfo import ZoneInfo
-
-
import feedparser
-
from feedgen.feed import FeedGenerator
-
from md2gemini import md2gemini
-
-
# This is so that Python doesn't yell at me if I forget an argument. Not
-
# likely to happen, but still.
-
if len(sys.argv) != 3:
-
print('Usage: blog2gemlog /path/to/blog/post.md "Blog Post Title"')
-
exit(1)
-
-
# Set the absolute path to the gemini content directory
-
gemini_dir = Path.home().joinpath(
-
"repos/tildegit.org/hyperreal/hyperreal.coffee/gemini"
-
)
-
-
# Get the current date in YYYY-MM-DD format
-
date_now = datetime.now().strftime("%Y-%m-%d")
-
-
# Read blog post path from sys.argv[1] and ensure it is an absolute path
-
blog_post_path = Path(sys.argv[1])
-
if not blog_post_path.is_absolute():
-
print("Supply absolute path to blog post.")
-
exit(1)
-
-
# Convert the markdown blog post to gemtext
-
with open(blog_post_path, "r") as md_f:
-
content = md2gemini(md_f.read(), frontmatter=True, links="paragraph", md_links=True)
-
-
# Set the absolute path to the gemlog post
-
gemlog_post_path = gemini_dir.joinpath(f"gemlog/{blog_post_path.stem}.gmi")
-
-
# Write the gemtext content to the gemlog post path
-
with open(gemlog_post_path, "w") as gmi_f:
-
gmi_f.write(content)
-
-
# Set the string for the END section of the gemlog post
-
gemlog_end = f"\n\n## END\nLast updated: {date_now}\n\n=> ../gemlog Gemlog archive\n=> ../ hyperreal.coffee"
-
-
# Append gemlog_end to the end of the gemlog post
-
with open(gemlog_post_path, "a") as gmi_f:
-
gmi_f.write(gemlog_end)
-
-
# Read the gemlog post file lines into a list
-
with open(gemlog_post_path, "r") as gmi_f:
-
contents = gmi_f.readlines()
-
-
# Get the gemlog post title from sys.argv[2]
-
gemlog_post_title = str(sys.argv[2])
-
-
# Insert the gemlog post title as the level 1 heading on line 1
-
contents.insert(0, f"# {gemlog_post_title}\n\n")
-
-
# Write the new contents as a string to the gemlog file
-
with open(gemlog_post_path, "w") as gmi_f:
-
contents = "".join(contents)
-
gmi_f.write(contents)
-
-
# Read the lines of the gemlog index into a list
-
with open(gemini_dir.joinpath("gemlog/index.gmi"), "r") as index_f:
-
contents = index_f.readlines()
-
-
# Set the content of the gemlog index entry line
-
gemlog_index_line = f"=> ./{gemlog_post_path.name} {date_now} {gemlog_post_title}\n"
-
-
# Insert the new gemlog index line into the list on line 6
-
contents.insert(5, gemlog_index_line)
-
-
# Write the new contents as a string to the gemlog index file
-
with open(gemini_dir.joinpath("gemlog/index.gmi"), "w") as index_f:
-
contents = "".join(contents)
-
index_f.write(contents)
-
-
# Get a timezone-aware datetime object from a timestamp of the present moment
-
aware_ts = datetime.fromtimestamp(
-
datetime.timestamp(datetime.now()), tz=ZoneInfo("America/Chicago")
-
)
-
-
# Format the timezone-aware datetime object for the <updated> element of the
-
# Atom feed
-
updated_ts = aware_ts.strftime("%Y-%m-%dT%H:%M:%S%z")
-
-
# Instantiate a FeedParserDict object
-
d = feedparser.parse(gemini_dir.joinpath("gemlog/atom.xml"))
-
-
# Update the <updated> element's value to the current timestamp
-
d["updated"] = updated_ts
-
-
# Define a dictionary for the new Atom feed entry
-
new_entry_dict = {
-
"id": f"gemini://hyperreal.coffee/gemlog/{gemlog_post_path.name}",
-
"title": gemlog_post_title,
-
"updated": updated_ts,
-
"links": [
-
{
-
"href": f"gemini://hyperreal.coffee/gemlog/{gemlog_post_path.name}",
-
"rel": "alternate",
-
"type": "text/gemini",
-
}
-
],
-
}
-
-
# Insert the new Atom feed entry into the FeedParserDict
-
d["entries"].insert(0, new_entry_dict)
-
-
# Instantiate a FeedGenerator object and set the methods for the feed
-
fg = FeedGenerator()
-
fg.id(d["feed"]["id"])
-
fg.title(d["feed"]["title"])
-
fg.updated(d["feed"]["updated"])
-
fg.link(d["feed"]["links"])
-
-
# Reverse the order of d["entries"] so that they are written to the file in
-
# the correct order
-
d["entries"].reverse()
-
-
# For each entry, add a new entry to the FeedGenerator object
-
for entry in d["entries"]:
-
fe = fg.add_entry()
-
fe.id(entry["id"])
-
fe.title(entry["title"])
-
fe.updated(entry["updated"])
-
fe.link(entry["links"])
-
-
# Finally, render the FeedGenerator object as an Atom feed and write it to
-
# the atom.xml file
-
fg.atom_file(gemini_dir.joinpath("gemlog/atom.xml"), pretty=True)
-
-
# vim: ai et ft=python sts=4 sw=4 ts=4
-12
scripts/board_capsule
···
-
#!/usr/bin/env bash
-
-
WEBSITE_DIR="${HOME}/repos/tildegit.org/hyperreal/hyperreal.coffee/http"
-
GEMINI_DIR="${HOME}/repos/tildegit.org/hyperreal/hyperreal.coffee/gemini"
-
-
find "${WEBSITE_DIR}/content" \
-
-maxdepth 1 \
-
-type f \
-
-not -name "_index.md" \
-
-exec md2gemini -w -d "$GEMINI_DIR" -f -m {} \;
-
-
# vim: ai et ft=bash sts=4 sw=4 ts=4