ForcePilot/backend/package/yuxi/channels/adapters/qqbot/group_buffer.py
Kris ef5483dc1a refactor(qqbot): 重构QQ机器人适配器代码,优化多项功能与结构
主要变更:
1. 修复速率限流器使用setdefault替代重复创建令牌桶
2. 重构交互注册表匹配逻辑,优化精确匹配查找
3. 重构去重缓存逻辑,移到适配器实例方法
4. 重构发送URL解析,增加合法性校验并拆分公共方法
5. 优化流式消息处理逻辑,简化flush_controller调用
6. 重构群聊类型判断代码,简化语法
7. 修复重连管理器对None类型关闭分类的处理
8. 新增消息缓存、线程模拟器、发送初始化模块
9. 重构凭证备份与会话存储逻辑,支持环境变量指定状态目录
10. 新增配置提示与向导二维码绑定功能
11. 优化媒体上传逻辑,增加重试机制与缓存
12. 新增审批键盘模板构建函数
13. 重构消息格式处理,修正媒体发送字段与长度限制
14. 修复令牌过期时间计算,使用time.time替代monotonic
15. 新增群组激活缓冲区与用户追踪器增强功能
16. 修复换行符问题,统一文件结尾格式
2026-05-13 16:13:48 +08:00

80 lines
2.5 KiB
Python

from __future__ import annotations
import time
from collections import defaultdict
from dataclasses import dataclass, field
@dataclass
class GroupMessage:
msg_id: str
author_id: str
author_name: str
content: str
timestamp: float
mentions_bot: bool = False
@dataclass
class GroupSession:
group_id: str = ""
messages: list[GroupMessage] = field(default_factory=list)
last_active: float = 0.0
buffer_limit: int = 50
ttl_seconds: float = 3600.0
def add(self, msg: GroupMessage) -> None:
self.messages.append(msg)
self.last_active = time.time()
if len(self.messages) > self.buffer_limit:
self.messages = self.messages[-self.buffer_limit :]
def is_expired(self, now: float | None = None) -> bool:
if now is None:
now = time.time()
return now - self.last_active > self.ttl_seconds
def recent_context(self, count: int = 10) -> list[GroupMessage]:
return self.messages[-count:]
class GroupHistoryBuffer:
def __init__(self, buffer_limit: int = 50, ttl_seconds: float = 3600.0) -> None:
self._sessions: dict[str, GroupSession] = defaultdict(GroupSession)
self._buffer_limit = buffer_limit
self._ttl_seconds = ttl_seconds
self._group_activations: dict[str, str] = {}
def set_group_activation(self, group_id: str, activation: str) -> None:
self._group_activations[group_id] = activation
def resolve_group_activation(self, group_id: str) -> str:
return self._group_activations.get(group_id, "")
def get_all_activations(self) -> dict[str, str]:
return dict(self._group_activations)
def record(self, group_id: str, msg: GroupMessage) -> None:
session = self._sessions[group_id]
session.buffer_limit = self._buffer_limit
session.ttl_seconds = self._ttl_seconds
if not session.group_id:
session.group_id = group_id
session.add(msg)
def recent_context(self, group_id: str, count: int = 10) -> list[GroupMessage]:
session = self._sessions.get(group_id)
if session is None:
return []
if session.is_expired():
del self._sessions[group_id]
return []
return session.recent_context(count)
def gc(self) -> int:
now = time.time()
expired = [gid for gid, s in self._sessions.items() if s.is_expired(now)]
for gid in expired:
del self._sessions[gid]
return len(expired)