forked from genewildish/Mainline
refactor: phase 4 - event-driven architecture foundation
- Add EventBus class with pub/sub messaging (thread-safe) - Add emitter Protocol classes (EventEmitter, Startable, Stoppable) - Add event emission to NtfyPoller (NtfyMessageEvent) - Add event emission to MicMonitor (MicLevelEvent) - Update StreamController to publish stream start/end events - Add comprehensive tests for eventbus and emitters modules
This commit is contained in:
@@ -16,8 +16,12 @@ import json
|
||||
import threading
|
||||
import time
|
||||
import urllib.request
|
||||
from collections.abc import Callable
|
||||
from datetime import datetime
|
||||
from urllib.parse import parse_qs, urlencode, urlparse, urlunparse
|
||||
|
||||
from engine.events import NtfyMessageEvent
|
||||
|
||||
|
||||
class NtfyPoller:
|
||||
"""SSE stream listener for ntfy.sh topics. Messages arrive in ~1s (network RTT)."""
|
||||
@@ -28,6 +32,24 @@ class NtfyPoller:
|
||||
self.display_secs = display_secs
|
||||
self._message = None # (title, body, monotonic_timestamp) or None
|
||||
self._lock = threading.Lock()
|
||||
self._subscribers: list[Callable[[NtfyMessageEvent], None]] = []
|
||||
|
||||
def subscribe(self, callback: Callable[[NtfyMessageEvent], None]) -> None:
|
||||
"""Register a callback to be called when a message is received."""
|
||||
self._subscribers.append(callback)
|
||||
|
||||
def unsubscribe(self, callback: Callable[[NtfyMessageEvent], None]) -> None:
|
||||
"""Remove a registered callback."""
|
||||
if callback in self._subscribers:
|
||||
self._subscribers.remove(callback)
|
||||
|
||||
def _emit(self, event: NtfyMessageEvent) -> None:
|
||||
"""Emit an event to all subscribers."""
|
||||
for cb in self._subscribers:
|
||||
try:
|
||||
cb(event)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
def start(self):
|
||||
"""Start background stream thread. Returns True."""
|
||||
@@ -88,6 +110,13 @@ class NtfyPoller:
|
||||
data.get("message", ""),
|
||||
time.monotonic(),
|
||||
)
|
||||
event = NtfyMessageEvent(
|
||||
title=data.get("title", ""),
|
||||
body=data.get("message", ""),
|
||||
message_id=data.get("id"),
|
||||
timestamp=datetime.now(),
|
||||
)
|
||||
self._emit(event)
|
||||
except Exception:
|
||||
pass
|
||||
time.sleep(self.reconnect_delay)
|
||||
|
||||
Reference in New Issue
Block a user