diff --git a/README.md b/README.md index fdede21..16d7768 100644 --- a/README.md +++ b/README.md @@ -93,6 +93,16 @@ retro_futurism 模板效果图 - `status`: 查看当前群的启用状态 - 例如:`/分析设置 enable` +#### 模板设置 +``` +/查看模板 +/设置模板 [模板名称或序号] +``` +- `/查看模板`: 查看所有可用模板及预览图 +- `/设置模板`: 查看当前模板和可用模板列表 +- `/设置模板 [序号]`: 切换到指定序号的模板 +- 例如:`/设置模板 1` 或 `/设置模板 scrapbook` + ## 安装要求 > [!CAUTION] @@ -275,6 +285,27 @@ retro_futurism 模板效果图 +### 开发环境设置 + +为了保持代码质量,本项目使用 [pre-commit](https://pre-commit.com/) 钩子进行代码规范检查和自动修复。所有的贡献代码都必须通过 pre-commit 检查。 + +#### 1. 安装 pre-commit +```bash +pip install pre-commit +``` + +#### 2. 安装 git hook +在项目根目录下运行,这将确保在每次提交时自动运行检查: +```bash +pre-commit install +``` + +#### 3. 手动运行检查 +如果需要手动触发所有文件的检查(推荐在提交前运行一次): +```bash +pre-commit run --all-files +``` + ### 模板贡献指南
diff --git a/_conf_schema.json b/_conf_schema.json index f5ecb9c..39b43fe 100644 --- a/_conf_schema.json +++ b/_conf_schema.json @@ -70,7 +70,7 @@ "type": "string", "description": "报告模板", "default": "scrapbook", - "hint": "分析报告使用的HTML模板名称,使用 `/设置模板` 查看使用指南,效果见 README(文档)" + "hint": "分析报告使用的HTML模板名称,使用 `/设置模板` 查看使用指南,使用`/查看模板` 命令查看模板样式效果" }, "min_messages_threshold": { @@ -182,7 +182,7 @@ "pdf_output_dir": { "type": "string", "description": "PDF输出目录", - "default": "data/plugins/astrbot-qq-group-daily-analysis/reports", + "default": "data/plugins/astrbot_qq_group_daily_analysis/reports", "hint": "PDF报告文件的保存目录" }, "pdf_filename_format": { diff --git a/src/analysis/analyzers/topic_analyzer.py b/src/analysis/analyzers/topic_analyzer.py index 93e90cf..fb8d395 100644 --- a/src/analysis/analyzers/topic_analyzer.py +++ b/src/analysis/analyzers/topic_analyzer.py @@ -63,22 +63,14 @@ class TopicAnalyzer(BaseAnalyzer): # 提取文本消息 text_messages = [] for i, msg in enumerate(messages): - logger.debug(f"build_prompt 处理第 {i + 1} 条消息,类型: {type(msg)}") - # 确保msg是字典类型,避免'str' object has no attribute 'get'错误 if not isinstance(msg, dict): - logger.warning( - f"build_prompt 跳过非字典类型的消息: {type(msg)} - {msg}" - ) continue try: sender = msg.get("sender", {}) # 确保sender是字典类型,避免'str' object has no attribute 'get'错误 if not isinstance(sender, dict): - logger.warning( - f"build_prompt 跳过sender非字典类型的消息: {type(sender)} - {sender}" - ) continue # 获取发送者ID并过滤机器人消息 @@ -87,37 +79,23 @@ class TopicAnalyzer(BaseAnalyzer): # 跳过机器人自己的消息 if bot_qq_ids and user_id in [str(qq) for qq in bot_qq_ids]: - logger.debug(f"build_prompt 过滤掉机器人QQ号: {user_id}") continue nickname = InfoUtils.get_user_nickname(self.config_manager, sender) msg_time = datetime.fromtimestamp(msg.get("time", 0)).strftime("%H:%M") message_list = msg.get("message", []) - logger.debug( - f"build_prompt 消息 {i + 1} 的 message 字段类型: {type(message_list)}, 长度: {len(message_list) if hasattr(message_list, '__len__') else 'N/A'}" - ) # 提取文本内容,可能分布在多个 content 中 text_parts = [] for j, content in enumerate(message_list): - logger.debug( - f"build_prompt 处理消息 {i + 1} 的内容 {j + 1}, 类型: {type(content)}" - ) if not isinstance(content, dict): - logger.warning( - f"build_prompt 跳过非字典类型的内容: {type(content)} - {content}" - ) continue content_type = content.get("type", "") - logger.debug(f"build_prompt 内容类型: {content_type}") if content_type == "text": text = content.get("data", {}).get("text", "").strip() - logger.debug( - f"build_prompt 提取到的文本: '{text}' (长度: {len(text)})" - ) if text: text_parts.append(text) elif content_type == "at": @@ -126,20 +104,15 @@ class TopicAnalyzer(BaseAnalyzer): if at_qq: at_text = f"@{at_qq}" text_parts.append(at_text) - logger.debug(f"build_prompt 提取到@消息: {at_text}") elif content_type == "reply": # 处理回复消息,添加标记 reply_id = content.get("data", {}).get("id", "") if reply_id: reply_text = f"[回复:{reply_id}]" text_parts.append(reply_text) - logger.debug(f"build_prompt 提取到回复消息: {reply_text}") # 合并所有文本部分 combined_text = "".join(text_parts).strip() - logger.debug( - f"build_prompt 合并后的文本: '{combined_text}' (长度: {len(combined_text)})" - ) if ( combined_text @@ -153,15 +126,9 @@ class TopicAnalyzer(BaseAnalyzer): cleaned_text = cleaned_text.replace("\t", " ") cleaned_text = re.sub(r"[\x00-\x1f\x7f-\x9f]", "", cleaned_text) - logger.debug(f"build_prompt 清理后的文本: '{cleaned_text}'") - text_messages.append( {"sender": nickname, "time": msg_time, "content": cleaned_text} ) - else: - logger.debug( - f"build_prompt 跳过文本: '{combined_text}' (长度不足或以/开头)" - ) except Exception as e: logger.error( f"build_prompt 处理第 {i + 1} 条消息时出错: {e}", exc_info=True diff --git a/src/core/config.py b/src/core/config.py index 32955cb..e1398f2 100644 --- a/src/core/config.py +++ b/src/core/config.py @@ -6,6 +6,7 @@ import sys from astrbot.api import AstrBotConfig, logger +from astrbot.core.utils.astrbot_path import get_astrbot_data_path class ConfigManager: @@ -139,9 +140,17 @@ class ConfigManager: def get_pdf_output_dir(self) -> str: """获取PDF输出目录""" - return self.config.get( - "pdf_output_dir", "data/plugins/astrbot-qq-group-daily-analysis/reports" - ) + try: + plugin_name = "astrbot_plugin_qq_group_daily_analysis" + data_path = get_astrbot_data_path() + default_path = data_path / "plugin_data" / plugin_name / "reports" + return self.config.get("pdf_output_dir", str(default_path)) + except Exception: + # Fallback for older versions or import errors + return self.config.get( + "pdf_output_dir", + "data/plugins/astrbot_plugin_qq_group_daily_analysis/reports", + ) def get_bot_qq_ids(self) -> list: """获取bot QQ号列表""" diff --git a/src/utils/helpers.py b/src/utils/helpers.py index e0fb3f0..1c175b4 100644 --- a/src/utils/helpers.py +++ b/src/utils/helpers.py @@ -3,6 +3,7 @@ 包含消息分析和其他通用功能 """ +import asyncio from astrbot.api import logger from ...src.analysis.llm_analyzer import LLMAnalyzer @@ -49,10 +50,14 @@ class MessageAnalyzer: """完整的消息分析流程""" try: # 基础统计 - statistics = self.message_handler.calculate_statistics(messages) + statistics = await asyncio.to_thread( + self.message_handler.calculate_statistics, messages + ) # 用户分析 - user_analysis = self.user_analyzer.analyze_users(messages) + user_analysis = await asyncio.to_thread( + self.user_analyzer.analyze_users, messages + ) # 获取活跃用户列表 - 使用get_top_users方法,limit从配置中读取 max_user_titles = self.config_manager.get_max_user_titles()