126 lines
3.6 KiB
Python
126 lines
3.6 KiB
Python
from pathlib import Path
|
|
from datetime import date
|
|
|
|
BASE = Path(__file__).resolve().parent.parent
|
|
SESSION = BASE / 'session'
|
|
LOG_DIR = SESSION / 'log'
|
|
CHAR_PATH = SESSION / 'character.md'
|
|
WORLD_PATH = SESSION / 'world.md'
|
|
JOURNAL_PATH = SESSION / 'journal.md'
|
|
AMBIENCE_PATH = SESSION / 'ambience.md'
|
|
AMBIENCE_OPTIONS_PATH = SESSION / 'ambience_options.md'
|
|
BOOK_PATH = SESSION / 'book.md'
|
|
LAST_PROMPT_PATH = SESSION / 'last_prompt.md'
|
|
CHANGES_PATH = SESSION / 'changes.md'
|
|
SETTINGS_PATH = SESSION / 'settings.json'
|
|
AUDIO_DIR = SESSION / 'audio'
|
|
TODAY = date.today().isoformat()
|
|
LOG_PATH = LOG_DIR / f'{TODAY}.md'
|
|
|
|
REFRESH_SECS = 2
|
|
|
|
|
|
def ensure_log():
|
|
LOG_DIR.mkdir(parents=True, exist_ok=True)
|
|
if not LOG_PATH.exists():
|
|
LOG_PATH.write_text(f"# Session Log — {TODAY}\n\n")
|
|
_populate_if_empty()
|
|
|
|
|
|
def _populate_if_empty():
|
|
content = LOG_PATH.read_text().strip()
|
|
if content and len(content.splitlines()) > 2:
|
|
return
|
|
|
|
|
|
def clear_llm_log():
|
|
from engine_lib.paths import LLM_LOG_PATH
|
|
LLM_LOG_PATH.parent.mkdir(parents=True, exist_ok=True)
|
|
LLM_LOG_PATH.write_text("")
|
|
|
|
|
|
def read_todo():
|
|
if not JOURNAL_PATH.exists():
|
|
return ["—— No journal yet ——"]
|
|
lines = JOURNAL_PATH.read_text().splitlines()
|
|
in_todo = False
|
|
todo = []
|
|
for l in lines:
|
|
if l.strip().lstrip("#").strip().startswith("TODO"):
|
|
in_todo = True
|
|
continue
|
|
if l.strip().startswith("#") and in_todo:
|
|
break
|
|
if in_todo and l.strip():
|
|
todo.append(l.strip().lstrip("- "))
|
|
return todo or ["—— All done! ——"]
|
|
|
|
|
|
def read_log_tail(n=200):
|
|
if not LOG_PATH.exists():
|
|
return []
|
|
lines = LOG_PATH.read_text().splitlines()
|
|
return [l for l in lines if l.strip() and not l.startswith("#")][-n:]
|
|
|
|
|
|
def status_summary():
|
|
if not CHAR_PATH.exists():
|
|
return "no character"
|
|
lines = CHAR_PATH.read_text().splitlines()
|
|
name = "?"
|
|
health = "?"
|
|
for l in lines:
|
|
if l.startswith('**Name:**'):
|
|
name = l.split(':', 1)[1].strip().strip('_').strip('*')
|
|
if l.startswith('**Current Health:**'):
|
|
h = l.split(':', 1)[1].strip().strip('_').strip('*')
|
|
if h:
|
|
health = h
|
|
if l.startswith('**Max Health:**'):
|
|
m = l.split(':', 1)[1].strip().strip('_').strip('*')
|
|
if m and health == '?':
|
|
health = m
|
|
return f"{name} ❤ {health}"
|
|
|
|
|
|
def log_count():
|
|
return len(read_log_tail())
|
|
|
|
|
|
def load_book_pages():
|
|
if not BOOK_PATH.exists() or not BOOK_PATH.read_text().strip():
|
|
return ["*The story has not begun.*"]
|
|
text = BOOK_PATH.read_text().strip()
|
|
turns = text.split('\n## ')
|
|
pages = []
|
|
for i, t in enumerate(turns):
|
|
pages.append(t if i == 0 else '## ' + t)
|
|
return pages or ["*The story has not begun.*"]
|
|
|
|
|
|
def parse_ambience_options():
|
|
if not AMBIENCE_OPTIONS_PATH.exists():
|
|
return {}
|
|
options = {}
|
|
lines = AMBIENCE_OPTIONS_PATH.read_text().splitlines()
|
|
in_table = False
|
|
for line in lines:
|
|
s = line.strip()
|
|
if not s.startswith('|') or not s.endswith('|'):
|
|
in_table = False
|
|
continue
|
|
parts = [p.strip() for p in s.split('|')]
|
|
parts = [p for p in parts if p]
|
|
if len(parts) < 2:
|
|
continue
|
|
if not in_table:
|
|
in_table = True
|
|
continue
|
|
if all(c in '-:| ' for c in s):
|
|
continue
|
|
name = parts[0].lower()
|
|
files = [f.strip() for f in parts[1].split(',') if f.strip()]
|
|
paths = [AUDIO_DIR / f for f in files]
|
|
options[name] = paths
|
|
return options
|