diff --git a/engine/app.py b/engine/app.py index 10eea6d..8ba2803 100644 --- a/engine/app.py +++ b/engine/app.py @@ -413,6 +413,14 @@ def main(): if config.FIREHOSE: boot_ln("Firehose", "ENGAGED", True) + if config.FIGMENT: + try: + from effects_plugins.figment import FigmentEffect # noqa: F401 + + boot_ln("Figment", f"ARMED [{config.FIGMENT_INTERVAL}s interval]", True) + except (ImportError, OSError): + boot_ln("Figment", "UNAVAILABLE — run: brew install cairo", False) + time.sleep(0.4) slow_print(" > STREAMING...\n") time.sleep(0.2) diff --git a/engine/config.py b/engine/config.py index c5ce46c..8ca8191 100644 --- a/engine/config.py +++ b/engine/config.py @@ -196,6 +196,8 @@ MODE = ( else "news" ) FIREHOSE = "--firehose" in sys.argv +FIGMENT = "--figment" in sys.argv +FIGMENT_INTERVAL = _arg_int("--figment-interval", 60) # seconds between appearances # ─── NTFY MESSAGE QUEUE ────────────────────────────────── NTFY_TOPIC = "https://ntfy.sh/klubhaus_terminal_mainline/json" diff --git a/engine/figment_render.py b/engine/figment_render.py index 4b8b696..0b9e0ea 100644 --- a/engine/figment_render.py +++ b/engine/figment_render.py @@ -7,8 +7,20 @@ Follows the same pixel-pair approach as engine/render.py for OTF fonts. from __future__ import annotations +import os +import sys from io import BytesIO +# cairocffi (used by cairosvg) calls dlopen() to find the Cairo C library. +# On macOS with Homebrew, Cairo lives in /opt/homebrew/lib (Apple Silicon) or +# /usr/local/lib (Intel), which are not in dyld's default search path. +# Setting DYLD_LIBRARY_PATH before the import directs dlopen() to those paths. +if sys.platform == "darwin" and not os.environ.get("DYLD_LIBRARY_PATH"): + for _brew_lib in ("/opt/homebrew/lib", "/usr/local/lib"): + if os.path.exists(os.path.join(_brew_lib, "libcairo.2.dylib")): + os.environ["DYLD_LIBRARY_PATH"] = _brew_lib + break + import cairosvg from PIL import Image diff --git a/engine/scroll.py b/engine/scroll.py index d297b3d..1bb90a2 100644 --- a/engine/scroll.py +++ b/engine/scroll.py @@ -55,14 +55,16 @@ def stream(items, ntfy_poller, mic_monitor, display: Display | None = None): frame_number = 0 # Figment overlay (optional — requires cairosvg) - try: - from effects_plugins.figment import FigmentEffect - from engine.effects.registry import get_registry + figment = None + if config.FIGMENT: + try: + from effects_plugins.figment import FigmentEffect - _fg_plugin = get_registry().get("figment") - figment = _fg_plugin if isinstance(_fg_plugin, FigmentEffect) else None - except ImportError: - figment = None + figment = FigmentEffect() + figment.config.enabled = True + figment.config.params["interval_secs"] = config.FIGMENT_INTERVAL + except (ImportError, OSError): + pass while True: if queued >= config.HEADLINE_LIMIT and not active: