#!/usr/bin/env python3 import os import sys import random import subprocess from datetime import date, timedelta from pathlib import Path # --- Helper functions --- def ordinal(n: int) -> str: """Return ordinal suffix for a given day number.""" if 10 <= n % 100 <= 20: suffix = "th" else: suffix = {1: "st", 2: "nd", 3: "rd"}.get(n % 10, "th") return f"{n}{suffix}" def get_latest_entry(base_path: Path): """Return the latest existing journal file, or None if none exist.""" entries = sorted(base_path.glob("*/*/*.md")) return entries[-1] if entries else None def next_date_from_latest(latest_path: Path): """Compute the next date after the latest entry.""" year = int(latest_path.parent.parent.name) month = int(latest_path.parent.name) day = int(latest_path.stem.split("_")[0]) d = date(year, month, day) return d + timedelta(days=1) def make_entry_path(base_path: Path, entry_date: date): year = entry_date.year month = entry_date.month day = entry_date.day weekday = entry_date.strftime("%A").lower() folder = base_path / f"{year}" / f"{month:02d}" folder.mkdir(parents=True, exist_ok=True) filename = f"{day:02d}_{weekday}.md" return folder / filename def write_entry_header(path: Path, entry_date: date): """Create new entry file with date header if it doesn’t exist.""" if path.exists(): return header = f"# {entry_date.strftime('%A')}, {ordinal(entry_date.day)} {entry_date.strftime('%B %Y')}\n\n" path.write_text(header, encoding="utf-8") def pick_random_entry(base_path: Path): """Return path to a random existing entry, or None if none exist.""" entries = sorted(base_path.glob("*/*/*.md")) return random.choice(entries) if entries else None # --- Main logic --- def main(): base_path = Path.cwd() base_path.mkdir(exist_ok=True) arg = sys.argv[1] if len(sys.argv) > 1 else None latest = get_latest_entry(base_path) if arg == "-t": entry_date = date.today() entry_path = make_entry_path(base_path, entry_date) write_entry_header(entry_path, entry_date) elif arg == "-n": if latest: entry_date = next_date_from_latest(latest) else: entry_date = date.today() entry_path = make_entry_path(base_path, entry_date) write_entry_header(entry_path, entry_date) elif arg == "-r": entry_path = pick_random_entry(base_path) if not entry_path: print("No journal entries found to review.") sys.exit(1) today = date.today() review_header = f"\n## {today.strftime('%A')}, {ordinal(today.day)} {today.strftime('%B %Y')}\n\n" with entry_path.open("a", encoding="utf-8") as f: f.write(review_header) else: if latest: entry_date = next_date_from_latest(latest) else: entry_date = date.today() entry_path = make_entry_path(base_path, entry_date) write_entry_header(entry_path, entry_date) editor = os.environ.get("EDITOR", "nano") subprocess.run([editor, str(entry_path)]) if __name__ == "__main__": main()