""" 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 "code" if "--code" 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)) # ─── THEME MANAGEMENT ───────────────────────────────────────── ACTIVE_THEME = None def set_active_theme(theme_id: str = "green"): """Set the active theme by ID. Args: theme_id: Theme identifier ("green", "orange", or "purple") Defaults to "green" Raises: KeyError: If theme_id is not in the theme registry Side Effects: Sets the ACTIVE_THEME global variable """ global ACTIVE_THEME from engine import themes ACTIVE_THEME = themes.get_theme(theme_id)