Merge branch 'main' of github.com:SXP-Simon/astrbot-qq-group-daily-analysis

This commit is contained in:
SXP-Simon
2026-01-07 00:30:14 +08:00
5 changed files with 52 additions and 40 deletions
+31
View File
@@ -93,6 +93,16 @@ retro_futurism 模板效果图
- `status`: 查看当前群的启用状态
- 例如:`/分析设置 enable`
#### 模板设置
```
/查看模板
/设置模板 [模板名称或序号]
```
- `/查看模板`: 查看所有可用模板及预览图
- `/设置模板`: 查看当前模板和可用模板列表
- `/设置模板 [序号]`: 切换到指定序号的模板
- 例如:`/设置模板 1``/设置模板 scrapbook`
## 安装要求
> [!CAUTION]
@@ -275,6 +285,27 @@ retro_futurism 模板效果图
</div>
### 开发环境设置
为了保持代码质量,本项目使用 [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
```
### 模板贡献指南
<details>
+2 -2
View File
@@ -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": {
-33
View File
@@ -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
+12 -3
View File
@@ -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号列表"""
+7 -2
View File
@@ -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()