From d746d0c4ce1b3a54434ea56af6176610b1ff2b73 Mon Sep 17 00:00:00 2001 From: tslilc Date: Mon, 4 May 2026 14:51:34 +0100 Subject: thoughts.md as a webpage --- atom.xml | 14 +++--- index-all.gmi | 1 + index.gmi | 2 +- log-260504-1.gmi | 127 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 136 insertions(+), 8 deletions(-) create mode 100644 log-260504-1.gmi diff --git a/atom.xml b/atom.xml index 4fb43bb..c844ff5 100644 --- a/atom.xml +++ b/atom.xml @@ -2,19 +2,13 @@ gemini://l-3.space/ l-3.space - 2025-08-25T08:15:00+00:00 + 2026-05-04T13:50:00+00:00 tslil hello@l-3.space - - gemini://l-3.space/split-keys.gmi - Qubes split-SSH - 2023-12-23T13:59:51.267749+00:00 - - gemini://l-3.space/log-211006-1.gmi Play Tak against a bot over Gemini! @@ -69,4 +63,10 @@ 2025-08-25T08:15:00+00:00 + + gemini://l-3.space/log-260504-1.gmi + Keeping track of thoughts.md as a webpage + 2026-05-04T13:50:00+00:00 + + diff --git a/index-all.gmi b/index-all.gmi index 751921a..0a17d5d 100644 --- a/index-all.gmi +++ b/index-all.gmi @@ -1,6 +1,7 @@ # l-3.space: all All content +=> gemini://l-3.space/log-260504-1.gmi 2026-05-04 - Keeping track of thoughts.md as a webpage => gemini://l-3.space/log-250825-1.gmi 2025-08-25 - Updated certs to 99 years and post-post Antenna hook => gemini://l-3.space/log-250824-1.gmi 2025-08-24 - Thoughts about keyboard layouts i have used => gemini://l-3.space/log-250823-2.gmi 2025-08-23 - Maybe there are different kinds of lifters diff --git a/index.gmi b/index.gmi index 7c9ce65..3f27195 100644 --- a/index.gmi +++ b/index.gmi @@ -22,11 +22,11 @@ Contact: hello@l-3.space ## Recent posts +=> gemini://l-3.space/log-260504-1.gmi 2026-05-04 - Keeping track of thoughts.md as a webpage => gemini://l-3.space/log-250825-1.gmi 2025-08-25 - Updated certs to 99 years and post-post Antenna hook => gemini://l-3.space/log-250824-1.gmi 2025-08-24 - Thoughts about keyboard layouts i have used => gemini://l-3.space/log-250823-2.gmi 2025-08-23 - Maybe there are different kinds of lifters => gemini://l-3.space/log-250823-1.gmi 2025-08-23 - Well done Debian team -=> gemini://l-3.space/log-240222-1.gmi 2024-02-22 - Formatting strings with separators in BQN ## Indices diff --git a/log-260504-1.gmi b/log-260504-1.gmi new file mode 100644 index 0000000..fe11f86 --- /dev/null +++ b/log-260504-1.gmi @@ -0,0 +1,127 @@ +Time-stamp: <2026-05-04 13h50 UTC> + +# Keeping track of thoughts.md as a webpage + +I realise that this is not exactly in the spirit of the smol web, and i have yet to decide on way to make this accessible over gemini, but here's a quick solution i found to scratch an itch i had. + +## The "problem" + +I have a file called `thoughts.md` on my laptop, where i keep track of things that i ought to write down™ lest they become eroded by steady march of entropy, so that i have a central place where i can forget about things. But, and this is important, that file is on my laptop --- only. + +What if it wasn't? + +## Enter python, bottle, nginx, systemd + +As i'm already hosting a website, what about a quick and dirty script that served a webpage with a textarea, and loaded the latest %YYYYMMDDHHMMSS.md file from a directory. If the user posts with "save", then make a new file. + +There are many, many features that this could grow, but for now having a text area i can reach from anyway, behind some auth'd endpoint from anywhere is all that i need. + +## Implementation details + +This takes a tiny amount of glue, but here's the basic idea + +```systemd unit file +[Unit] +Description=Note server +After=network.target + +[Service] +Type=simple +DynamicUser=yes +StateDirectory=notes +WorkingDirectory=/var/lib/private/notes +ExecStart=/usr/bin/python3 /usr/local/bin/note.py /var/lib/private/notes --host 127.0.0.1 --port NNN-CHANGE-ME +Restart=always +RestartSec=5 + +[Install] +WantedBy=multi-user.target +``` + +```nginx config snippet +location /CHANGE-ME-XXX { + rewrite ^/CHANGE-ME-XXX/?(.*)$ /$1 break; + proxy_pass http://127.0.0.1:18088; + proxy_set_header Host $host; + proxy_set_header X-Real-IP $remote_addr; + + auth_basic "notes"; + auth_basic_user_file /etc/nginx/.htpasswd; +} +``` + +```python webserver +#!/usr/bin/env python3 +import argparse +import re +from datetime import datetime +from pathlib import Path + +import bottle +from bottle import request, run + + +def latest_file(directory: Path) -> Path | None: + files = [p for p in directory.glob("*.md") if re.match(r"^\d{14}\.md$", p.name)] + return max(files, key=lambda p: p.stat().st_mtime) if files else None + + +def save(directory: Path, text: str) -> Path: + filename = f"{datetime.now():%Y%m%d%H%M%S}.md" + path = directory / filename + _ = path.write_text(text, encoding="utf-8") + return path + + +def make_page(directory: Path) -> str: + latest = latest_file(directory) + content = latest.read_text(encoding="utf-8") if latest else "" + filename = latest.name if latest else "(none)" + return f""" + + + + +notes + + + +
latest: {filename}
+
+ +
+
+ +""" + + +def main(): + parser = argparse.ArgumentParser(description="note server") + parser.add_argument("directory", type=Path, help="where to store .md files") + parser.add_argument("--host", default="127.0.0.1") + parser.add_argument("--port", type=int, default=8080) + args = parser.parse_args() + + args.directory.mkdir(parents=True, exist_ok=True) + + @bottle.route("/") + def index(): + return make_page(args.directory) + + @bottle.route("/save", method="POST") + def save_route(): + text = request.forms.get("text", "") + path = save(args.directory, text) + return make_page(args.directory) + + run(host=args.host, port=args.port) + + +if __name__ == "__main__": + main() +``` -- cgit v1.3.1