add review flag
This commit is contained in:
parent
e27893ad81
commit
f4635fdc74
2 changed files with 37 additions and 17 deletions
|
|
@ -22,6 +22,7 @@ A simple markdown journal entry generator, with the following folder structure:
|
||||||
| empty | Create an entry for the next day |
|
| empty | Create an entry for the next day |
|
||||||
| `-t` | Create an entry for today's date |
|
| `-t` | Create an entry for today's date |
|
||||||
| `-n` | Create an entry for the next day |
|
| `-n` | Create an entry for the next day |
|
||||||
|
| `-r` | Review an existing entry |
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
|
|
|
||||||
49
journal.py
49
journal.py
|
|
@ -1,39 +1,38 @@
|
||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
from datetime import date, timedelta
|
import random
|
||||||
import subprocess
|
import subprocess
|
||||||
|
from datetime import date, timedelta
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
# --- Helper functions ---
|
# --- Helper functions ---
|
||||||
|
|
||||||
|
|
||||||
def ordinal(n: int) -> str:
|
def ordinal(n: int) -> str:
|
||||||
"""Return ordinal suffix for a given day number."""
|
"""Return ordinal suffix for a given day number."""
|
||||||
if 10 <= n % 100 <= 20:
|
if 10 <= n % 100 <= 20:
|
||||||
suffix = 'th'
|
suffix = "th"
|
||||||
else:
|
else:
|
||||||
suffix = {1: 'st', 2: 'nd', 3: 'rd'}.get(n % 10, 'th')
|
suffix = {1: "st", 2: "nd", 3: "rd"}.get(n % 10, "th")
|
||||||
return f"{n}{suffix}"
|
return f"{n}{suffix}"
|
||||||
|
|
||||||
def month_name(month: int) -> str:
|
|
||||||
return date(2000, month, 1).strftime("%B")
|
|
||||||
|
|
||||||
def get_latest_entry(base_path: Path):
|
def get_latest_entry(base_path: Path):
|
||||||
"""Return the latest existing journal file, or None if none exist."""
|
"""Return the latest existing journal file, or None if none exist."""
|
||||||
entries = sorted(base_path.glob("*/*/*.md"))
|
entries = sorted(base_path.glob("*/*/*.md"))
|
||||||
return entries[-1] if entries else None
|
return entries[-1] if entries else None
|
||||||
|
|
||||||
|
|
||||||
def next_date_from_latest(latest_path: Path):
|
def next_date_from_latest(latest_path: Path):
|
||||||
"""Compute the next date after the latest entry."""
|
"""Compute the next date after the latest entry."""
|
||||||
parts = latest_path.stem.split("_")[0].split("-")
|
|
||||||
# stem example: 04_tuesday -> day=4
|
|
||||||
# full path: year/month/date_day.md
|
|
||||||
year = int(latest_path.parent.parent.name)
|
year = int(latest_path.parent.parent.name)
|
||||||
month = int(latest_path.parent.name)
|
month = int(latest_path.parent.name)
|
||||||
day = int(parts[0])
|
day = int(latest_path.stem.split("_")[0])
|
||||||
d = date(year, month, day)
|
d = date(year, month, day)
|
||||||
return d + timedelta(days=1)
|
return d + timedelta(days=1)
|
||||||
|
|
||||||
|
|
||||||
def make_entry_path(base_path: Path, entry_date: date):
|
def make_entry_path(base_path: Path, entry_date: date):
|
||||||
year = entry_date.year
|
year = entry_date.year
|
||||||
month = entry_date.month
|
month = entry_date.month
|
||||||
|
|
@ -44,42 +43,62 @@ def make_entry_path(base_path: Path, entry_date: date):
|
||||||
filename = f"{day:02d}_{weekday}.md"
|
filename = f"{day:02d}_{weekday}.md"
|
||||||
return folder / filename
|
return folder / filename
|
||||||
|
|
||||||
|
|
||||||
def write_entry_header(path: Path, entry_date: date):
|
def write_entry_header(path: Path, entry_date: date):
|
||||||
|
"""Create new entry file with date header if it doesn’t exist."""
|
||||||
if path.exists():
|
if path.exists():
|
||||||
return # Don't overwrite
|
return
|
||||||
header = f"# {entry_date.strftime('%A')}, {ordinal(entry_date.day)} {entry_date.strftime('%B %Y')}\n\n"
|
header = f"# {entry_date.strftime('%A')}, {ordinal(entry_date.day)} {entry_date.strftime('%B %Y')}\n\n"
|
||||||
path.write_text(header, encoding="utf-8")
|
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 ---
|
# --- Main logic ---
|
||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
base_path = Path.cwd()
|
base_path = Path.cwd()
|
||||||
|
base_path.mkdir(exist_ok=True)
|
||||||
|
|
||||||
# Parse args
|
|
||||||
arg = sys.argv[1] if len(sys.argv) > 1 else None
|
arg = sys.argv[1] if len(sys.argv) > 1 else None
|
||||||
latest = get_latest_entry(base_path)
|
latest = get_latest_entry(base_path)
|
||||||
|
|
||||||
if arg == "-t":
|
if arg == "-t":
|
||||||
entry_date = date.today()
|
entry_date = date.today()
|
||||||
|
entry_path = make_entry_path(base_path, entry_date)
|
||||||
|
write_entry_header(entry_path, entry_date)
|
||||||
elif arg == "-n":
|
elif arg == "-n":
|
||||||
if latest:
|
if latest:
|
||||||
entry_date = next_date_from_latest(latest)
|
entry_date = next_date_from_latest(latest)
|
||||||
else:
|
else:
|
||||||
entry_date = date.today()
|
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:
|
else:
|
||||||
# Default behavior
|
|
||||||
if latest:
|
if latest:
|
||||||
entry_date = next_date_from_latest(latest)
|
entry_date = next_date_from_latest(latest)
|
||||||
else:
|
else:
|
||||||
entry_date = date.today()
|
entry_date = date.today()
|
||||||
|
|
||||||
entry_path = make_entry_path(base_path, entry_date)
|
entry_path = make_entry_path(base_path, entry_date)
|
||||||
write_entry_header(entry_path, entry_date)
|
write_entry_header(entry_path, entry_date)
|
||||||
|
|
||||||
# Open in text editor
|
|
||||||
editor = os.environ.get("EDITOR", "nano")
|
editor = os.environ.get("EDITOR", "nano")
|
||||||
subprocess.run([editor, str(entry_path)])
|
subprocess.run([editor, str(entry_path)])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue