70 lines
2.1 KiB
Python
70 lines
2.1 KiB
Python
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)
|