add atom feed support (this code is getting messy)

This commit is contained in:
nebula 2025-04-08 04:13:39 +00:00
parent bbcf752b98
commit 7cad56eb1f
3 changed files with 80 additions and 15 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
bin
include
lib
lib64
pyvenv.cfg

View File

@ -1,15 +1,18 @@
from sys import argv from sys import argv
from subprocess import Popen, PIPE, STDOUT, run, call from subprocess import Popen, PIPE, run, call
from PIL import Image from PIL import Image
from jinja2 import Environment, FileSystemLoader from jinja2 import Environment, FileSystemLoader
from markdown import markdown from markdown import markdown
from glob import glob from glob import glob
from json import dump, dumps, load from json import dump, dumps, load
from os import path from os import path
from feedgen.feed import FeedGenerator
import re import re
import datetime
numbers = re.compile("[0-9]+") numbers_re = re.compile("[0-9]+")
name_from_url = re.compile(r"https:\/\/helixnebula.space/(.*)/") name_from_url_re = re.compile(r"https:\/\/helixnebula.space/(.*)/")
md_links_re = re.compile(r"\[([^\]]*)\]\([^\)]*\)")
out_dir = "/var/www/html/" out_dir = "/var/www/html/"
gemini_out_dir = "/var/gemini/" gemini_out_dir = "/var/gemini/"
base_url = "https://helixnebula.space/" base_url = "https://helixnebula.space/"
@ -37,11 +40,22 @@ for placename in metadata.keys():
pass pass
metadata[placename]["count"] = len(photos) metadata[placename]["count"] = len(photos)
metadata[placename]["photos"] = photos metadata[placename]["photos"] = photos
metadata[placename]["photos"].sort(key=lambda path: int(numbers.search(path).group(0))) metadata[placename]["photos"].sort(key=lambda path: int(numbers_re.search(path).group(0)))
with open(f"{out_dir}photos.json", "w") as f: with open(f"{out_dir}photos.json", "w") as f:
dump(metadata, f) dump(metadata, f)
def header_from_code(code):
path = f"{md_dir}{code}.md"
with open(path, "r") as f:
md = f.read()
header = ""
for char in md[2:]:
if char == "\n":
break
header += char
return header
def covers(overwrite=False): def covers(overwrite=False):
print("running covers") print("running covers")
for placename, info in metadata.items(): for placename, info in metadata.items():
@ -153,7 +167,7 @@ def render_gemini_places():
content = f.read() content = f.read()
process = Popen(["gemgen"], stdout=PIPE, stdin=PIPE, stderr=PIPE, text=True) process = Popen(["gemgen"], stdout=PIPE, stdin=PIPE, stderr=PIPE, text=True)
gemtext = process.communicate(input=content)[0] gemtext = process.communicate(input=content)[0]
gemtext_with_local_urls = name_from_url.sub(sub_http_local_urls, gemtext) gemtext_with_local_urls = name_from_url_re.sub(sub_http_local_urls, gemtext)
with open(gemini_out_dir + post_name + ".gmi", "w") as f: with open(gemini_out_dir + post_name + ".gmi", "w") as f:
f.write(template.render({ f.write(template.render({
"post_code": post_name, "post_code": post_name,
@ -162,6 +176,40 @@ def render_gemini_places():
"state": metadata[post_name]["state"] "state": metadata[post_name]["state"]
})) }))
def md_from_code(code):
with open(f"{md_dir}{code}.md", "r") as f:
return markdown(f.read())
def path_to_story_name(story_path):
return path.basename(story_path).split('/')[-1][:-3]
def render_atom():
posts_sorted = story_names.copy()
posts_sorted.sort(key=lambda i: metadata[i]["story_time"])
feed = FeedGenerator()
feed.id("helixnebula.space")
feed.title("helixnebula.space")
feed.updated(datetime.datetime.fromtimestamp(metadata[posts_sorted[-1]]["story_time"], datetime.timezone.utc))
feed.author({"name":"~nebula","email":"nebula@tilde.town"})
feed.link(href="https://helixnebula.space/", rel="alternate")
feed.link(href="https://helixnebula.space/feed.atom", rel="self")
feed.subtitle("Exploring America the Beautiful")
feed.icon("https://helixnebula.space/favicon.ico")
feed.language("en")
for post_code in posts_sorted:
post_metadata = metadata[post_code]
header = header_from_code(post_code)
title = f"{post_metadata['title']}, {post_metadata['state']}: {header}"
entry = feed.add_entry()
entry.id(post_code)
entry.title(title)
entry.updated(datetime.datetime.fromtimestamp(metadata[post_code]["story_time"], datetime.timezone.utc))
entry.link(href=f"https://helixnebula.space/{post_code}/")
entry.summary(header)
entry.description(header)
entry.content(md_from_code(post_code), type="html")
feed.atom_file(out_dir + "feed_html.atom")
def copy_files(): def copy_files():
call(f"cp js/* {out_dir}js/", shell=True) call(f"cp js/* {out_dir}js/", shell=True)
call(f"cp style.css {out_dir}style.css", shell=True) call(f"cp style.css {out_dir}style.css", shell=True)
@ -179,3 +227,4 @@ if __name__ == "__main__":
copy_files() copy_files()
render_gemini_index() render_gemini_index()
render_gemini_places() render_gemini_places()
render_atom()

View File

@ -2,7 +2,8 @@
"BasinRange": { "BasinRange": {
"title": "Basin & Range National Monument", "title": "Basin & Range National Monument",
"state": "Nevada", "state": "Nevada",
"cover": "99.jpg" "cover": "99.jpg",
"story_time": 1740873600
}, },
"Berlin": { "Berlin": {
"title": "Berlin Ichthyosaur State Park", "title": "Berlin Ichthyosaur State Park",
@ -12,7 +13,8 @@
"Bisti": { "Bisti": {
"title": "Bisti Badlands", "title": "Bisti Badlands",
"state": "New Mexico", "state": "New Mexico",
"cover": "19.jpg" "cover": "19.jpg",
"story_time": 1740787200
}, },
"Canyonlands": { "Canyonlands": {
"title": "Canyonlands National Park", "title": "Canyonlands National Park",
@ -82,7 +84,8 @@
"Caballo": { "Caballo": {
"title": "Caballo", "title": "Caballo",
"state": "New Mexico", "state": "New Mexico",
"cover": "IMG_0760.JPEG" "cover": "IMG_0760.JPEG",
"story_time": 1742662800
}, },
"Peralta": { "Peralta": {
"title": "Peralta Trail (Weaver's Needle)", "title": "Peralta Trail (Weaver's Needle)",
@ -107,7 +110,8 @@
"Rubies": { "Rubies": {
"title": "Ruby Mountains", "title": "Ruby Mountains",
"state": "Nevada", "state": "Nevada",
"cover": "IMG_0667.JPEG" "cover": "IMG_0667.JPEG",
"story_time": 1742058000
}, },
"ElMalpais": { "ElMalpais": {
"title": "El Malpais National Monument", "title": "El Malpais National Monument",
@ -162,7 +166,8 @@
"PrescottNF": { "PrescottNF": {
"title": "Prescott National Forest", "title": "Prescott National Forest",
"state": "Arizona", "state": "Arizona",
"cover": "IMG_7458.JPEG" "cover": "IMG_7458.JPEG",
"story_time": 1744009200
}, },
"BoyceThompson": { "BoyceThompson": {
"title": "Boyce Thompson Arboretum", "title": "Boyce Thompson Arboretum",
@ -172,12 +177,14 @@
"ToApacheLake": { "ToApacheLake": {
"title": "To Apache Lake", "title": "To Apache Lake",
"state": "Arizona", "state": "Arizona",
"cover": "IMG_1735.JPG" "cover": "IMG_1735.JPG",
"story_time": 1742749200
}, },
"SonoranSnow": { "SonoranSnow": {
"title": "Sonoran Desert Snow Day", "title": "Sonoran Desert Snow Day",
"state": "Arizona", "state": "Arizona",
"cover": "IMG_8764.JPEG" "cover": "IMG_8764.JPEG",
"story_time": 1744083545
}, },
"GoldwaterLakes": { "GoldwaterLakes": {
"title": "Goldwater Lakes", "title": "Goldwater Lakes",
@ -197,7 +204,8 @@
"ChiNaturePark": { "ChiNaturePark": {
"title": "Chihuahuan Desert Nature Park", "title": "Chihuahuan Desert Nature Park",
"state": "New Mexico", "state": "New Mexico",
"cover": "IMG_6236.JPEG" "cover": "IMG_6236.JPEG",
"story_time": 1743699600
}, },
"Bumblebee": { "Bumblebee": {
"title": "Bumblebee", "title": "Bumblebee",
@ -227,12 +235,14 @@
"Pushawalla": { "Pushawalla": {
"title": "Pushawalla Palms Trail", "title": "Pushawalla Palms Trail",
"state": "California", "state": "California",
"cover": "IMG_1424.JPG" "cover": "IMG_1424.JPG",
"story_time": 1744002000
}, },
"SmokyMountains": { "SmokyMountains": {
"title": "Smoky Mountains", "title": "Smoky Mountains",
"state": "Tennessee", "state": "Tennessee",
"cover": "IMG_5708.JPEG" "cover": "IMG_5708.JPEG",
"story_time": 1742922000
}, },
"TruthOrConsequences": { "TruthOrConsequences": {
"title": "Truth or Consequences", "title": "Truth or Consequences",