mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-22 20:01:04 +00:00
Merge branch 'main' of github.com:SXP-Simon/astrbot-qq-group-daily-analysis
This commit is contained in:
@@ -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
@@ -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": {
|
||||
|
||||
@@ -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
@@ -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号列表"""
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user