forked from genewildish/Mainline
- Fix import sorting (isort) across all engine modules - Fix SIM105 try-except-pass patterns (contextlib.suppress) - Fix nested with statements in tests - Fix unused loop variables Run 'uv run pytest' to verify tests still pass.
101 lines
3.8 KiB
Python
101 lines
3.8 KiB
Python
"""
|
||
Configuration constants, CLI flags, and glyph tables.
|
||
"""
|
||
|
||
import sys
|
||
from pathlib import Path
|
||
|
||
_REPO_ROOT = Path(__file__).resolve().parent.parent
|
||
_FONT_EXTENSIONS = {".otf", ".ttf", ".ttc"}
|
||
|
||
|
||
def _arg_value(flag):
|
||
"""Get value following a CLI flag, if present."""
|
||
if flag not in sys.argv:
|
||
return None
|
||
i = sys.argv.index(flag)
|
||
return sys.argv[i + 1] if i + 1 < len(sys.argv) else None
|
||
|
||
|
||
def _arg_int(flag, default):
|
||
"""Get int CLI argument with safe fallback."""
|
||
raw = _arg_value(flag)
|
||
if raw is None:
|
||
return default
|
||
try:
|
||
return int(raw)
|
||
except ValueError:
|
||
return default
|
||
|
||
|
||
def _resolve_font_path(raw_path):
|
||
"""Resolve font path; relative paths are anchored to repo root."""
|
||
p = Path(raw_path).expanduser()
|
||
if p.is_absolute():
|
||
return str(p)
|
||
return str((_REPO_ROOT / p).resolve())
|
||
|
||
|
||
def _list_font_files(font_dir):
|
||
"""List supported font files within a font directory."""
|
||
font_root = Path(font_dir)
|
||
if not font_root.exists() or not font_root.is_dir():
|
||
return []
|
||
return [
|
||
str(path.resolve())
|
||
for path in sorted(font_root.iterdir())
|
||
if path.is_file() and path.suffix.lower() in _FONT_EXTENSIONS
|
||
]
|
||
|
||
|
||
def list_repo_font_files():
|
||
"""Public helper for discovering repository font files."""
|
||
return _list_font_files(FONT_DIR)
|
||
# ─── RUNTIME ──────────────────────────────────────────────
|
||
HEADLINE_LIMIT = 1000
|
||
FEED_TIMEOUT = 10
|
||
MIC_THRESHOLD_DB = 50 # dB above which glitches intensify
|
||
MODE = 'poetry' if '--poetry' in sys.argv or '-p' in sys.argv else 'news'
|
||
FIREHOSE = '--firehose' in sys.argv
|
||
|
||
# ─── NTFY MESSAGE QUEUE ──────────────────────────────────
|
||
NTFY_TOPIC = "https://ntfy.sh/klubhaus_terminal_mainline/json"
|
||
NTFY_RECONNECT_DELAY = 5 # seconds before reconnecting after a dropped stream
|
||
MESSAGE_DISPLAY_SECS = 30 # how long a message holds the screen
|
||
|
||
# ─── FONT RENDERING ──────────────────────────────────────
|
||
FONT_DIR = _resolve_font_path(_arg_value('--font-dir') or "fonts")
|
||
_FONT_FILE_ARG = _arg_value('--font-file')
|
||
_FONT_FILES = _list_font_files(FONT_DIR)
|
||
FONT_PATH = (
|
||
_resolve_font_path(_FONT_FILE_ARG)
|
||
if _FONT_FILE_ARG
|
||
else (_FONT_FILES[0] if _FONT_FILES else "")
|
||
)
|
||
FONT_INDEX = max(0, _arg_int('--font-index', 0))
|
||
FONT_PICKER = '--no-font-picker' not in sys.argv
|
||
FONT_SZ = 60
|
||
RENDER_H = 8 # terminal rows per rendered text line
|
||
|
||
# ─── FONT RENDERING (ADVANCED) ────────────────────────────
|
||
SSAA = 4 # super-sampling factor: render at SSAA× then downsample
|
||
|
||
# ─── SCROLL / FRAME ──────────────────────────────────────
|
||
SCROLL_DUR = 5.625 # seconds per headline (2/3 original speed)
|
||
FRAME_DT = 0.05 # 50ms base frame rate (20 FPS)
|
||
FIREHOSE_H = 12 # firehose zone height (terminal rows)
|
||
GRAD_SPEED = 0.08 # gradient traversal speed (cycles/sec, ~12s full sweep)
|
||
|
||
# ─── GLYPHS ───────────────────────────────────────────────
|
||
GLITCH = "░▒▓█▌▐╌╍╎╏┃┆┇┊┋"
|
||
KATA = "ハミヒーウシナモニサワツオリアホテマケメエカキムユラセネスタヌヘ"
|
||
|
||
|
||
def set_font_selection(font_path=None, font_index=None):
|
||
"""Set runtime primary font selection."""
|
||
global FONT_PATH, FONT_INDEX
|
||
if font_path is not None:
|
||
FONT_PATH = _resolve_font_path(font_path)
|
||
if font_index is not None:
|
||
FONT_INDEX = max(0, int(font_index))
|