from __future__ import annotations from collections import OrderedDict class SentMessageCache: def __init__(self, max_size: int = 5000): self._cache: OrderedDict[str, str] = OrderedDict() self._max_size = max_size def add(self, chat_id: str, content_hash: str, event_id: str) -> None: key = f"{chat_id}:{content_hash}" self._cache[key] = event_id self._cache.move_to_end(key) if len(self._cache) > self._max_size: self._cache.popitem(last=False) def get(self, chat_id: str, content_hash: str) -> str | None: key = f"{chat_id}:{content_hash}" return self._cache.get(key) def get_event_id_for_content(self, chat_id: str, content: str) -> str | None: import hashlib content_hash = hashlib.md5(content.encode()).hexdigest()[:12] return self.get(chat_id, content_hash) def remove(self, chat_id: str, event_id: str) -> None: keys_to_remove = [k for k, v in self._cache.items() if v == event_id and k.startswith(f"{chat_id}:")] for key in keys_to_remove: del self._cache[key] def clear(self) -> None: self._cache.clear() def clear_room(self, chat_id: str) -> None: keys_to_remove = [k for k in self._cache if k.startswith(f"{chat_id}:")] for key in keys_to_remove: del self._cache[key] def __len__(self) -> int: return len(self._cache) def hash_content(content: str) -> str: import hashlib return hashlib.md5(content.encode()).hexdigest()[:12] class ResponseSizeLimiter: def __init__(self, max_bytes: int = 50 * 1024 * 1024): self._max_bytes = max_bytes def check(self, size_bytes: int) -> tuple[bool, str]: if size_bytes > self._max_bytes: return False, f"Response size {size_bytes} bytes exceeds limit of {self._max_bytes} bytes" return True, "" @property def max_bytes(self) -> int: return self._max_bytes @classmethod def from_config(cls, config: dict) -> ResponseSizeLimiter: max_mb = config.get("mediaMaxMb", 100) return cls(max_bytes=max_mb * 1024 * 1024)