journal/journal.py
2025-11-12 23:33:46 +01:00

104 lines
3.1 KiB
Python
Executable file
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/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 doesnt 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()