mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-22 13:38:43 +00:00
docs: localize shared module documentation to Vietnamese
Translate Chinese docstrings and comments in the shared module to Vietnamese without changing runtime logic or public API values.
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
共享模块 - 通用工具和常量
|
||||
Mô-đun chia sẻ - Công cụ dùng chung và hằng số.
|
||||
"""
|
||||
|
||||
from .constants import ContentType, Platform, ReportFormat, TaskStatus
|
||||
|
||||
+27
-25
@@ -1,5 +1,5 @@
|
||||
"""
|
||||
常量 - 插件中使用的共享常量
|
||||
Hằng số - Các hằng số dùng chung trong plugin.
|
||||
"""
|
||||
|
||||
from enum import Enum
|
||||
@@ -7,9 +7,9 @@ from enum import Enum
|
||||
|
||||
class Platform(str, Enum):
|
||||
"""
|
||||
支持的聊天平台枚举
|
||||
Liệt kê các nền tảng trò chuyện được hỗ trợ.
|
||||
|
||||
定义了插件适配的所有基础通讯平台标识。
|
||||
Định nghĩa mã định danh của các nền tảng giao tiếp cơ bản mà plugin hỗ trợ.
|
||||
"""
|
||||
|
||||
ONEBOT = "onebot"
|
||||
@@ -22,9 +22,10 @@ class Platform(str, Enum):
|
||||
|
||||
class TaskStatus(str, Enum):
|
||||
"""
|
||||
分析任务执行状态枚举
|
||||
Liệt kê các trạng thái thực thi của tác vụ phân tích.
|
||||
|
||||
用于在异步处理流水线中标记分析任务的生命阶段。
|
||||
Dùng để đánh dấu giai đoạn trong vòng đời của tác vụ phân tích
|
||||
thuộc quy trình xử lý bất đồng bộ.
|
||||
"""
|
||||
|
||||
PENDING = "pending"
|
||||
@@ -36,9 +37,10 @@ class TaskStatus(str, Enum):
|
||||
|
||||
class ContentType(str, Enum):
|
||||
"""
|
||||
统一消息内容类型枚举
|
||||
Liệt kê các loại nội dung tin nhắn hợp nhất.
|
||||
|
||||
将不同平台(OneBot, Discord 等)的消息片段抽象为统一的类型体系。
|
||||
Trừu tượng hóa các thành phần tin nhắn từ nhiều nền tảng
|
||||
(OneBot, Discord, v.v.) thành một hệ thống kiểu thống nhất.
|
||||
"""
|
||||
|
||||
TEXT = "text"
|
||||
@@ -55,9 +57,9 @@ class ContentType(str, Enum):
|
||||
|
||||
class ReportFormat(str, Enum):
|
||||
"""
|
||||
分析报告导出格式枚举
|
||||
Liệt kê các định dạng xuất báo cáo phân tích.
|
||||
|
||||
控制最终呈现给用户的报告呈现形式。
|
||||
Kiểm soát hình thức trình bày báo cáo cuối cùng cho người dùng.
|
||||
"""
|
||||
|
||||
TEXT = "text"
|
||||
@@ -66,25 +68,25 @@ class ReportFormat(str, Enum):
|
||||
HTML = "html"
|
||||
|
||||
|
||||
# 插件元数据
|
||||
# Siêu dữ liệu của plugin
|
||||
PLUGIN_NAME = "astrbot_plugin_qq_group_daily_analysis"
|
||||
PLUGIN_VERSION = "2.0.0"
|
||||
|
||||
# 平台标识符
|
||||
# Mã định danh nền tảng
|
||||
SUPPORTED_PLATFORMS = [
|
||||
Platform.ONEBOT.value,
|
||||
Platform.TELEGRAM.value,
|
||||
Platform.DISCORD.value,
|
||||
]
|
||||
|
||||
# 分析默认值
|
||||
# Giá trị phân tích mặc định
|
||||
DEFAULT_MAX_TOPICS = 5
|
||||
DEFAULT_MAX_USER_TITLES = 10
|
||||
DEFAULT_MAX_GOLDEN_QUOTES = 5
|
||||
DEFAULT_MIN_MESSAGES = 50
|
||||
DEFAULT_MAX_TOKENS = 2000
|
||||
|
||||
# 时间段
|
||||
# Các khoảng thời gian
|
||||
HOUR_RANGES = {
|
||||
"morning": (6, 12),
|
||||
"afternoon": (12, 18),
|
||||
@@ -92,30 +94,30 @@ HOUR_RANGES = {
|
||||
"night": (0, 6),
|
||||
}
|
||||
|
||||
# 错误代码
|
||||
# Mã lỗi
|
||||
ERROR_INSUFFICIENT_DATA = "INSUFFICIENT_DATA"
|
||||
ERROR_LLM_FAILED = "LLM_FAILED"
|
||||
ERROR_PLATFORM_ERROR = "PLATFORM_ERROR"
|
||||
ERROR_CONFIG_ERROR = "CONFIG_ERROR"
|
||||
ERROR_TIMEOUT = "TIMEOUT"
|
||||
|
||||
# 缓存 TTL(秒)
|
||||
CACHE_TTL_SHORT = 60 # 1 分钟
|
||||
CACHE_TTL_MEDIUM = 300 # 5 分钟
|
||||
CACHE_TTL_LONG = 3600 # 1 小时
|
||||
CACHE_TTL_DAY = 86400 # 24 小时
|
||||
# Thời gian tồn tại của bộ nhớ đệm (giây)
|
||||
CACHE_TTL_SHORT = 60 # 1 phút
|
||||
CACHE_TTL_MEDIUM = 300 # 5 phút
|
||||
CACHE_TTL_LONG = 3600 # 1 giờ
|
||||
CACHE_TTL_DAY = 86400 # 24 giờ
|
||||
|
||||
# 速率限制默认值
|
||||
RATE_LIMIT_LLM_CALLS = 10 # 每分钟调用次数
|
||||
RATE_LIMIT_API_CALLS = 60 # 每分钟调用次数
|
||||
RATE_LIMIT_BURST = 5 # 突发大小
|
||||
# Giá trị giới hạn tốc độ mặc định
|
||||
RATE_LIMIT_LLM_CALLS = 10 # Số lượt gọi mỗi phút
|
||||
RATE_LIMIT_API_CALLS = 60 # Số lượt gọi mỗi phút
|
||||
RATE_LIMIT_BURST = 5 # Quy mô gọi đột biến
|
||||
|
||||
# 重试默认值
|
||||
# Giá trị thử lại mặc định
|
||||
RETRY_MAX_ATTEMPTS = 3
|
||||
RETRY_BASE_DELAY = 1.0
|
||||
RETRY_MAX_DELAY = 30.0
|
||||
|
||||
# 文件路径
|
||||
# Đường dẫn tệp
|
||||
HISTORY_DIR = "history"
|
||||
CACHE_DIR = "cache"
|
||||
TEMP_DIR = "temp"
|
||||
|
||||
+73
-61
@@ -1,7 +1,7 @@
|
||||
"""
|
||||
追踪上下文 - 请求追踪和关联
|
||||
Ngữ cảnh truy vết - Theo dõi và liên kết yêu cầu.
|
||||
|
||||
提供用于在插件中跟踪请求的上下文。
|
||||
Cung cấp ngữ cảnh dùng để theo dõi yêu cầu trong plugin.
|
||||
"""
|
||||
|
||||
import functools
|
||||
@@ -13,14 +13,14 @@ from dataclasses import dataclass, field
|
||||
from datetime import datetime
|
||||
from typing import Any, Optional
|
||||
|
||||
# Trace ID 中群名的最大长度(平衡可读性和日志宽度)
|
||||
# Độ dài tối đa của tên nhóm trong Trace ID (cân bằng khả năng đọc và độ rộng nhật ký)
|
||||
_MAX_GROUP_NAME_LEN = 10
|
||||
|
||||
# 用于匹配报告 Caption 中去重 Token 的正则模式
|
||||
# 格式: "| MM-DD HH:MM:SS"
|
||||
# Mẫu biểu thức chính quy dùng để khớp token khử trùng lặp trong Caption báo cáo
|
||||
# Định dạng: "| MM-DD HH:MM:SS"
|
||||
REPORT_CAPTION_PATTERN = re.compile(r"\| (\d{2}-\d{2} \d{2}:\d{2}:\d{2})")
|
||||
|
||||
# 当前追踪的上下文变量
|
||||
# Biến ngữ cảnh đang được truy vết
|
||||
_current_trace: ContextVar[Optional["TraceContext"]] = ContextVar(
|
||||
"current_trace", default=None
|
||||
)
|
||||
@@ -29,18 +29,20 @@ _current_trace: ContextVar[Optional["TraceContext"]] = ContextVar(
|
||||
@dataclass
|
||||
class TraceContext:
|
||||
"""
|
||||
核心组件:全链路追踪上下文 (Tracing Context)
|
||||
Thành phần cốt lõi: ngữ cảnh truy vết toàn bộ chuỗi (Tracing Context).
|
||||
|
||||
该组件用于在复杂的异步分析流程中关联日志、耗时统计及元数据。
|
||||
它不仅提供了 TraceId 的生成与传递,还集成了毫秒级的性能打点(Checkpoint)功能。
|
||||
Thành phần này liên kết nhật ký, thống kê thời gian thực thi và siêu dữ liệu
|
||||
trong các quy trình phân tích bất đồng bộ phức tạp.
|
||||
Ngoài khả năng tạo và truyền Trace ID, thành phần còn tích hợp chức năng
|
||||
ghi nhận hiệu năng ở độ chính xác mili giây (Checkpoint).
|
||||
|
||||
Attributes:
|
||||
trace_id (str): 链路唯一标识码,默认为 UUID 前 8 位
|
||||
group_id (str): 当前关联的群组 ID
|
||||
platform (str): 当前消息所属平台
|
||||
operation (str): 当前执行的操作名称 (如 'DAILY_ANALYSIS')
|
||||
start_time (datetime): 追踪开始的具体时刻
|
||||
metadata (dict[str, Any]): 随链路传递的额外上下文数据
|
||||
trace_id (str): Mã định danh duy nhất của chuỗi, mặc định là 8 ký tự đầu của UUID.
|
||||
group_id (str): ID của nhóm đang được liên kết.
|
||||
platform (str): Nền tảng của tin nhắn hiện tại.
|
||||
operation (str): Tên thao tác đang thực hiện, ví dụ: 'DAILY_ANALYSIS'.
|
||||
start_time (datetime): Thời điểm cụ thể bắt đầu truy vết.
|
||||
metadata (dict[str, Any]): Dữ liệu ngữ cảnh bổ sung được truyền theo chuỗi.
|
||||
"""
|
||||
|
||||
trace_id: str = field(default_factory=lambda: str(uuid.uuid4())[:8])
|
||||
@@ -50,27 +52,28 @@ class TraceContext:
|
||||
start_time: datetime = field(default_factory=datetime.now)
|
||||
metadata: dict[str, Any] = field(default_factory=dict)
|
||||
|
||||
# 内部计时器,用于多阶段耗时分析
|
||||
# Bộ hẹn giờ nội bộ, dùng để phân tích thời gian thực thi qua nhiều giai đoạn
|
||||
_checkpoints: dict[str, datetime] = field(default_factory=dict, init=False)
|
||||
|
||||
def checkpoint(self, name: str) -> None:
|
||||
"""
|
||||
在当前时间轴上设置一个命名锚点(打点)。
|
||||
Đặt một mốc có tên trên trục thời gian hiện tại.
|
||||
|
||||
Args:
|
||||
name (str): 锚点标识符,如 'LLM_REPLY_RECEIVED'
|
||||
name (str): Mã định danh của mốc, ví dụ: 'LLM_REPLY_RECEIVED'.
|
||||
"""
|
||||
self._checkpoints[name] = datetime.now()
|
||||
|
||||
def elapsed_ms(self, from_checkpoint: str | None = None) -> float:
|
||||
"""
|
||||
计算从开始或指定锚点到当前时刻经过的毫秒数。
|
||||
Tính số mili giây đã trôi qua từ lúc bắt đầu hoặc từ một mốc chỉ định đến hiện tại.
|
||||
|
||||
Args:
|
||||
from_checkpoint (str, optional): 起始锚点名称。若为 None 则从链路启动时算起。
|
||||
from_checkpoint (str, optional): Tên mốc bắt đầu. Nếu là None,
|
||||
tính từ thời điểm chuỗi được khởi tạo.
|
||||
|
||||
Returns:
|
||||
float: 经过的毫秒数
|
||||
float: Số mili giây đã trôi qua.
|
||||
"""
|
||||
start = self.start_time
|
||||
if from_checkpoint and from_checkpoint in self._checkpoints:
|
||||
@@ -81,10 +84,11 @@ class TraceContext:
|
||||
|
||||
def to_dict(self) -> dict[str, Any]:
|
||||
"""
|
||||
将链路快照序列化为字典格式,便于持久化或 JSON 日志输出。
|
||||
Tuần tự hóa ảnh chụp trạng thái của chuỗi thành dạng từ điển,
|
||||
thuận tiện cho việc lưu trữ hoặc xuất nhật ký JSON.
|
||||
|
||||
Returns:
|
||||
dict[str, Any]: 序列化后的追踪状态
|
||||
dict[str, Any]: Trạng thái truy vết sau khi tuần tự hóa.
|
||||
"""
|
||||
return {
|
||||
"trace_id": self.trace_id,
|
||||
@@ -100,12 +104,12 @@ class TraceContext:
|
||||
_token: Token | None = field(default=None, init=False, repr=False)
|
||||
|
||||
def __enter__(self) -> "TraceContext":
|
||||
"""进入上下文管理器,将当前实例绑定到当前协程上下文。"""
|
||||
"""Bước vào trình quản lý ngữ cảnh và liên kết instance hiện tại với ngữ cảnh coroutine."""
|
||||
self._token = _current_trace.set(self)
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb) -> None:
|
||||
"""退出上下文管理器,清理绑定状态。"""
|
||||
"""Thoát khỏi trình quản lý ngữ cảnh và dọn dẹp trạng thái liên kết."""
|
||||
if self._token:
|
||||
_current_trace.reset(self._token)
|
||||
self._token = None
|
||||
@@ -113,10 +117,11 @@ class TraceContext:
|
||||
@classmethod
|
||||
def current(cls) -> Optional["TraceContext"]:
|
||||
"""
|
||||
静态获取当前协程活跃的追踪上下文。
|
||||
Lấy ngữ cảnh truy vết đang hoạt động trong coroutine hiện tại.
|
||||
|
||||
Returns:
|
||||
Optional[TraceContext]: 若当前处于追踪链路中则返回实例,否则返回 None
|
||||
Optional[TraceContext]: Instance nếu hiện tại đang ở trong chuỗi truy vết,
|
||||
ngược lại trả về None.
|
||||
"""
|
||||
return _current_trace.get()
|
||||
|
||||
@@ -129,16 +134,17 @@ class TraceContext:
|
||||
auto_bind: bool = False,
|
||||
) -> "TraceContext":
|
||||
"""
|
||||
尝试获取现有链路,若不存在则按需创建一个。
|
||||
Thử lấy chuỗi hiện có; nếu không tồn tại thì tạo một chuỗi mới khi cần.
|
||||
|
||||
Args:
|
||||
group_id (str): 群组 ID
|
||||
platform (str): 平台名称
|
||||
operation (str): 操作描述
|
||||
auto_bind (bool): 若新建,是否自动绑定到当前上下文(仅在 non-with 场景有用,谨慎使用)
|
||||
group_id (str): ID nhóm.
|
||||
platform (str): Tên nền tảng.
|
||||
operation (str): Mô tả thao tác.
|
||||
auto_bind (bool): Nếu tạo mới, có tự động liên kết với ngữ cảnh hiện tại
|
||||
hay không (chỉ hữu ích trong trường hợp không dùng with, hãy thận trọng).
|
||||
|
||||
Returns:
|
||||
TraceContext: 活跃或新生成的实例
|
||||
TraceContext: Instance đang hoạt động hoặc vừa được tạo.
|
||||
"""
|
||||
current = cls.current()
|
||||
if current:
|
||||
@@ -156,20 +162,21 @@ class TraceContext:
|
||||
@staticmethod
|
||||
def generate(prefix: str = "", group_name: str = "") -> str:
|
||||
"""
|
||||
生成语义化、易读的追踪 ID。
|
||||
Tạo Trace ID có ngữ nghĩa và dễ đọc.
|
||||
|
||||
格式: {来源}_{群名}_{时间点}
|
||||
示例: manual_系统交流群_1733
|
||||
Định dạng: {nguồn}_{tên_nhóm}_{thời_điểm}
|
||||
Ví dụ: manual_Nhóm_hệ_thống_1733
|
||||
|
||||
由于插件存在任务锁 (DuplicateGroupTaskError),确保了一个群同一时间只有一个分析任务,
|
||||
因此 时间点 (HHmm) 已足够提供唯一性,无需 UUID 缀。
|
||||
Do plugin có khóa tác vụ (DuplicateGroupTaskError), bảo đảm mỗi nhóm
|
||||
chỉ có một tác vụ phân tích tại một thời điểm. Vì vậy, thời điểm (HHmm)
|
||||
đã đủ để tạo tính duy nhất và không cần thêm UUID.
|
||||
|
||||
Args:
|
||||
prefix (str): 来源标识,如 'manual', 'group', 'incr', 'report'
|
||||
group_name (str): 可选群名,用于日志中快速识别
|
||||
prefix (str): Mã nguồn, ví dụ: 'manual', 'group', 'incr', 'report'.
|
||||
group_name (str): Tên nhóm tùy chọn, dùng để nhận diện nhanh trong nhật ký.
|
||||
|
||||
Returns:
|
||||
str: 语义化 TraceID 字符串
|
||||
str: Chuỗi Trace ID có ngữ nghĩa.
|
||||
"""
|
||||
timestamp = datetime.now().strftime("%H%M")
|
||||
|
||||
@@ -177,7 +184,7 @@ class TraceContext:
|
||||
if prefix:
|
||||
parts.append(prefix)
|
||||
if group_name:
|
||||
# 清理:移除空白符和文件系统不安全字符
|
||||
# Làm sạch: loại bỏ khoảng trắng và các ký tự không an toàn cho hệ thống tệp
|
||||
safe_name = re.sub(r'[\s\n\r\t/\\:*?"<>|\[\]{}]', "", group_name)
|
||||
safe_name = safe_name[:_MAX_GROUP_NAME_LEN]
|
||||
if safe_name:
|
||||
@@ -189,13 +196,15 @@ class TraceContext:
|
||||
@staticmethod
|
||||
def make_report_caption() -> str:
|
||||
"""
|
||||
生成整洁的、面向用户的报告 Caption,包含用于去重的隐式时间戳。
|
||||
Tạo Caption báo cáo gọn gàng hướng đến người dùng,
|
||||
có chứa dấu thời gian ẩn dùng để khử trùng lặp.
|
||||
|
||||
该时间戳用作图片去重检查的 Token。
|
||||
格式: "📊 每日群聊分析报告已生成 | MM-DD HH:MM:SS"
|
||||
Dấu thời gian này được dùng làm token kiểm tra trùng lặp hình ảnh.
|
||||
Định dạng gồm biểu tượng báo cáo, nội dung Caption hiện tại và dấu thời gian
|
||||
theo mẫu ``MM-DD HH:MM:SS``.
|
||||
|
||||
Returns:
|
||||
str: 报告 Caption 字符串
|
||||
str: Chuỗi Caption của báo cáo.
|
||||
"""
|
||||
ts = datetime.now().strftime("%m-%d %H:%M:%S")
|
||||
return f"📊 每日群聊分析报告已生成 | {ts}"
|
||||
@@ -203,29 +212,30 @@ class TraceContext:
|
||||
@classmethod
|
||||
def set(cls, trace_id: str) -> None:
|
||||
"""
|
||||
[兼容性接口] 直接设置当前上下文的 TraceID。
|
||||
这会创建一个新的 TraceContext 实例并将其推入 ContextVar。
|
||||
[Giao diện tương thích] Đặt trực tiếp Trace ID của ngữ cảnh hiện tại.
|
||||
Thao tác này tạo một instance TraceContext mới và đưa vào ContextVar.
|
||||
|
||||
Args:
|
||||
trace_id (str): 要设置的追踪 ID 字符串
|
||||
trace_id (str): Chuỗi Trace ID cần đặt.
|
||||
"""
|
||||
ctx = cls(trace_id=trace_id)
|
||||
# 注意:此处不手动存储 Token,依靠异步任务结束时 ContextVar 的自动清理。
|
||||
# Lưu ý: không lưu Token thủ công ở đây; dựa vào việc ContextVar tự dọn dẹp
|
||||
# khi tác vụ bất đồng bộ kết thúc.
|
||||
_current_trace.set(ctx)
|
||||
|
||||
@classmethod
|
||||
def get(cls) -> str:
|
||||
"""
|
||||
[兼容性接口] 获取当前活跃的追踪 ID 字符串。
|
||||
[Giao diện tương thích] Lấy chuỗi Trace ID đang hoạt động hiện tại.
|
||||
"""
|
||||
return get_trace_id()
|
||||
|
||||
|
||||
class TraceLogFilter(logging.Filter):
|
||||
"""
|
||||
日志过滤器:自动将当前的 TraceID 注入每一条日志记录中。
|
||||
Bộ lọc nhật ký: tự động chèn Trace ID hiện tại vào mỗi bản ghi nhật ký.
|
||||
|
||||
配合日志格式化字符串 `[%(trace_id)s]` 使用。
|
||||
Được sử dụng cùng chuỗi định dạng nhật ký `[%(trace_id)s]`.
|
||||
"""
|
||||
|
||||
def filter(self, record: logging.LogRecord) -> bool:
|
||||
@@ -235,10 +245,11 @@ class TraceLogFilter(logging.Filter):
|
||||
|
||||
def get_trace_id() -> str:
|
||||
"""
|
||||
便捷接口:快速获取当前活跃的 TraceID 或零时生成一个临时 ID。
|
||||
Giao diện tiện ích: nhanh chóng lấy Trace ID đang hoạt động,
|
||||
hoặc tạm thời tạo một ID mới nếu chưa có.
|
||||
|
||||
Returns:
|
||||
str: 8 位十六进制追踪 ID
|
||||
str: Trace ID hệ thập lục phân gồm 8 ký tự.
|
||||
"""
|
||||
trace = TraceContext.current()
|
||||
if trace:
|
||||
@@ -252,21 +263,22 @@ def with_trace(
|
||||
operation: str = "",
|
||||
):
|
||||
"""
|
||||
装饰器:自动为异步函数包裹追踪上下文。
|
||||
Decorator: tự động bao bọc hàm bất đồng bộ bằng ngữ cảnh truy vết.
|
||||
|
||||
Args:
|
||||
group_id (str): 设置追踪的群组
|
||||
platform (str): 设置追踪的平台
|
||||
operation (str): 操作名称,默认为函数名
|
||||
group_id (str): Nhóm cần truy vết.
|
||||
platform (str): Nền tảng cần truy vết.
|
||||
operation (str): Tên thao tác, mặc định là tên hàm.
|
||||
|
||||
Returns:
|
||||
Callable: 装饰后的函数
|
||||
Callable: Hàm sau khi được trang trí.
|
||||
"""
|
||||
|
||||
def decorator(func):
|
||||
@functools.wraps(func)
|
||||
async def wrapper(*args, **kwargs):
|
||||
# 优先使用装饰器声明的 operation,否则取函数原始名称
|
||||
# Ưu tiên operation được khai báo trong decorator; nếu không có,
|
||||
# sử dụng tên gốc của hàm.
|
||||
op_name = operation or func.__name__
|
||||
with TraceContext(
|
||||
group_id=group_id,
|
||||
|
||||
Reference in New Issue
Block a user