这是一个批量整理提交,包含以下主要改动: 1. 删除多处冗余的空行和未使用的导入 2. 修复文件末尾缺少换行符的问题 3. 调整部分模块的导入顺序与代码排版 4. 修复部分配置默认值与策略逻辑 5. 新增多个功能模块与辅助工具 6. 完善异常处理与日志记录 7. 修复速率限制、消息缓存、权限校验等逻辑bug 8. 废弃部分旧有API与配置项并添加警告提示
69 lines
2.1 KiB
Python
69 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)
|