61 lines
1.9 KiB
Python
61 lines
1.9 KiB
Python
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}
|
|
)
|