from __future__ import annotations from typing import TYPE_CHECKING from userbot.modules.watches.evaluator import ( KIND_KEYWORD, KIND_PEER_ONLINE, match_keyword, match_peer_online, ) from utils.logging import logger from utils.read import watches as watches_read if TYPE_CHECKING: import asyncpg from utils.read.models import WatchView class WatchCache: def __init__(self, pool: asyncpg.Pool, account_id: int) -> None: self._pool = pool self._account_id = account_id self.watches: list[WatchView] = [] self._online: set[int] = set() async def refresh(self) -> None: rows = await watches_read.list_watches(self._pool, self._account_id) self.watches = [watch for watch in rows if watch.enabled] logger.info(f"[green]Watches cached:[/] {len(self.watches)}") async def on_text(self, chat_id: int, message_id: int, text: str | None) -> None: if not text: return for watch in self.watches: if watch.kind == KIND_KEYWORD and match_keyword( text, chat_id, watch.params ): await watches_read.insert_alert( self._pool, self._account_id, watch.id, {"chat_id": chat_id, "message_id": message_id}, dedup_key=f"{chat_id}:{message_id}", ) async def on_status(self, peer_id: int, *, is_online: bool) -> None: if not is_online: self._online.discard(peer_id) return if peer_id in self._online: return self._online.add(peer_id) for watch in self.watches: if watch.kind == KIND_PEER_ONLINE and match_peer_online( peer_id, watch.params ): await watches_read.insert_alert( self._pool, self._account_id, watch.id, {"peer_id": peer_id} )