#!/usr/bin/env python3 """Smol “three good things” notepad.""" import datetime import re import smolcgi as scgi scgi.require_client_cert() def get_month_dir(year, month): return scgi.get_user_dir() / f"{str(year).zfill(4)}-{str(month).zfill(2)}" def get_day_file(year, month, day): filename = str(day).zfill(2) + ".gmi" return get_month_dir(year, month) / filename def reply_home(): scgi.header(20, "text/gemini") print("# Trikiff! 🌄🥰🌃\n") print("## Actions\n") scgi.link("/new/today", "Add kiffs of today") scgi.link("/new/yesterday", "Add kiffs of yesterday") scgi.link("/new", "Add kiffs for another day") print() print("## This month\n") today = datetime.date.today() month_dir = get_month_dir(today.year, today.month) if month_dir.is_dir(): print_month(month_dir) else: print("No kiffs yet!") print("## Past months\n") scgi.link("/browse", "Browse archives") def reply_new(date: datetime.date): if (kiffs := scgi.query_string_dec): kiffs = filter(lambda s: s, kiffs.split(";")) kiffs = map(lambda s: "* " + s.strip(), kiffs) content = "\n".join(kiffs) + "\n" day_file = get_day_file(date.year, date.month, date.day) if not (parent_dir := day_file.parent).exists(): parent_dir.mkdir(parents=True) with open(get_day_file(date.year, date.month, date.day), "at") as f: f.write(content) scgi.redirect_temp(f"{scgi.script_name}") else: scgi.require_input("Input one or more kiffs (separated with ';')") def reply_prompt_day(): if (query := scgi.query_string_dec): try: if (match := re.match(r"^\d{1,2}$", query)): date = datetime.date.today().replace(day=int(match.group(0))) elif (match := re.match(r"^\d{4}-\d{2}-\d{2}$", query)): date = datetime.date.fromisoformat(match.group(0)) else: scgi.bad_request("Invalid day or date format") except ValueError: scgi.bad_request("Invalid day or date format") scgi.redirect_temp(f"{scgi.script_name}/new/{date.isoformat()}") else: scgi.require_input( "Which day? You can input only the day for the current month, " "or a complete date using the YYYY-MM-DD format." ) def reply_browse(directory=None): if directory: path = scgi.get_user_dir() / directory if not path.is_dir(): scgi.not_found() scgi.header(20, "text/gemini") print(f"# Kiffs for {directory}\n") print_month(path) else: scgi.header(20, "text/gemini") print("# Trikiff archives 📜\n") for path in sorted(scgi.get_user_dir().iterdir(), reverse=True): if not path.is_dir(): continue scgi.link(f"/browse/{path.name}", path.name) def print_month(month_dir): for day_filename in sorted(month_dir.iterdir(), reverse=True): day = day_filename.name[:-4] print(f"### {day}") with open(day_filename, "rt") as f: print(f.read()) if scgi.path_info == "/new/today": reply_new(datetime.date.today()) elif scgi.path_info == "/new/yesterday": reply_new(datetime.date.today() - datetime.timedelta(days=1)) elif scgi.path_info == "/new": reply_prompt_day() elif (match := re.match(r"^/new/(\d{4}-\d{2}-\d{2})$", scgi.path_info)): try: reply_new(datetime.date.fromisoformat(match.group(1))) except ValueError: scgi.not_found() elif scgi.path_info == "/browse": reply_browse() elif (match := re.match(r"^/browse/(\d{4}-\d{2})$", scgi.path_info)): reply_browse(directory=match.group(1)) else: reply_home()