mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-22 13:38:43 +00:00
Fix(bot manager): _get_platform_id_for_group 是一个异步方法(async def),但在 main.py 中调用时忘记加 await (#54)
* fix(bot-manager): 正确处理实例获取 * fix(import); AiocqhttpAdapter 导入 * fix: 通过 meta 实现 aiocqhttp 判断 * fix(_get_platform_id_for_group): _get_platform_id_for_group 是一个异步方法(async def),但在 main.py 中调用时忘记加 await 了,导致它返回了一个协程对象而不是字符串 ID * fix(pre-commit)
This commit is contained in:
@@ -7,23 +7,23 @@ QQ群日常分析插件
|
||||
|
||||
import asyncio
|
||||
|
||||
from astrbot.api import AstrBotConfig, logger
|
||||
from astrbot.api.event import filter
|
||||
from astrbot.api.star import Context, Star
|
||||
from astrbot.api import logger, AstrBotConfig
|
||||
from astrbot.core.message.components import File
|
||||
from astrbot.core.platform.sources.aiocqhttp.aiocqhttp_message_event import (
|
||||
AiocqhttpMessageEvent,
|
||||
)
|
||||
from astrbot.core.message.components import File
|
||||
from astrbot.core.star.filter.permission import PermissionType
|
||||
|
||||
from .src.core.bot_manager import BotManager
|
||||
|
||||
# 导入重构后的模块
|
||||
from .src.core.config import ConfigManager
|
||||
from .src.core.bot_manager import BotManager
|
||||
from .src.reports.generators import ReportGenerator
|
||||
from .src.scheduler.auto_scheduler import AutoScheduler
|
||||
from .src.utils.pdf_utils import PDFInstaller
|
||||
from .src.utils.helpers import MessageAnalyzer
|
||||
|
||||
from .src.utils.pdf_utils import PDFInstaller
|
||||
|
||||
# 全局变量
|
||||
config_manager = None
|
||||
@@ -175,7 +175,7 @@ class QQGroupDailyAnalysis(Star):
|
||||
|
||||
try:
|
||||
# 获取该群对应的平台ID和bot实例
|
||||
platform_id = auto_scheduler._get_platform_id_for_group(group_id)
|
||||
platform_id = await auto_scheduler._get_platform_id_for_group(group_id)
|
||||
bot_instance = bot_manager.get_bot_instance(platform_id)
|
||||
|
||||
if not bot_instance:
|
||||
|
||||
@@ -4,8 +4,8 @@
|
||||
"""
|
||||
|
||||
from .base_analyzer import BaseAnalyzer
|
||||
from .golden_quote_analyzer import GoldenQuoteAnalyzer
|
||||
from .topic_analyzer import TopicAnalyzer
|
||||
from .user_title_analyzer import UserTitleAnalyzer
|
||||
from .golden_quote_analyzer import GoldenQuoteAnalyzer
|
||||
|
||||
__all__ = ["BaseAnalyzer", "TopicAnalyzer", "UserTitleAnalyzer", "GoldenQuoteAnalyzer"]
|
||||
|
||||
@@ -5,13 +5,15 @@
|
||||
|
||||
from abc import ABC, abstractmethod
|
||||
from typing import Any
|
||||
|
||||
from astrbot.api import logger
|
||||
|
||||
from ...models.data_models import TokenUsage
|
||||
from ..utils.json_utils import parse_json_response
|
||||
from ..utils.llm_utils import (
|
||||
call_provider_with_retry,
|
||||
extract_token_usage,
|
||||
extract_response_text,
|
||||
extract_token_usage,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -4,11 +4,13 @@
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
|
||||
from astrbot.api import logger
|
||||
|
||||
from ...models.data_models import GoldenQuote, TokenUsage
|
||||
from .base_analyzer import BaseAnalyzer
|
||||
from ..utils.json_utils import extract_golden_quotes_with_regex
|
||||
from ..utils import InfoUtils
|
||||
from ..utils.json_utils import extract_golden_quotes_with_regex
|
||||
from .base_analyzer import BaseAnalyzer
|
||||
|
||||
|
||||
class GoldenQuoteAnalyzer(BaseAnalyzer):
|
||||
|
||||
@@ -3,13 +3,15 @@
|
||||
专门处理群聊话题分析
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
import re
|
||||
from datetime import datetime
|
||||
|
||||
from astrbot.api import logger
|
||||
|
||||
from ...models.data_models import SummaryTopic, TokenUsage
|
||||
from .base_analyzer import BaseAnalyzer
|
||||
from ..utils.json_utils import extract_topics_with_regex
|
||||
from ..utils import InfoUtils
|
||||
from ..utils.json_utils import extract_topics_with_regex
|
||||
from .base_analyzer import BaseAnalyzer
|
||||
|
||||
|
||||
class TopicAnalyzer(BaseAnalyzer):
|
||||
|
||||
@@ -4,9 +4,10 @@
|
||||
"""
|
||||
|
||||
from astrbot.api import logger
|
||||
from ...models.data_models import UserTitle, TokenUsage
|
||||
from .base_analyzer import BaseAnalyzer
|
||||
|
||||
from ...models.data_models import TokenUsage, UserTitle
|
||||
from ..utils.json_utils import extract_user_titles_with_regex
|
||||
from .base_analyzer import BaseAnalyzer
|
||||
|
||||
|
||||
class UserTitleAnalyzer(BaseAnalyzer):
|
||||
|
||||
@@ -4,13 +4,15 @@ LLM分析器模块
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
|
||||
from astrbot.api import logger
|
||||
from ..models.data_models import SummaryTopic, UserTitle, GoldenQuote, TokenUsage
|
||||
|
||||
from ..models.data_models import GoldenQuote, SummaryTopic, TokenUsage, UserTitle
|
||||
from .analyzers.golden_quote_analyzer import GoldenQuoteAnalyzer
|
||||
from .analyzers.topic_analyzer import TopicAnalyzer
|
||||
from .analyzers.user_title_analyzer import UserTitleAnalyzer
|
||||
from .analyzers.golden_quote_analyzer import GoldenQuoteAnalyzer
|
||||
from .utils.llm_utils import call_provider_with_retry
|
||||
from .utils.json_utils import fix_json
|
||||
from .utils.llm_utils import call_provider_with_retry
|
||||
|
||||
|
||||
class LLMAnalyzer:
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
负责用户活跃度分析和其他统计功能
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from collections import defaultdict
|
||||
from datetime import datetime
|
||||
|
||||
from .utils import InfoUtils
|
||||
|
||||
|
||||
|
||||
@@ -3,22 +3,20 @@
|
||||
包含JSON处理和LLM API请求处理工具
|
||||
"""
|
||||
|
||||
from .info_utils import InfoUtils
|
||||
from .json_utils import (
|
||||
fix_json,
|
||||
parse_json_response,
|
||||
extract_golden_quotes_with_regex,
|
||||
extract_topics_with_regex,
|
||||
extract_user_titles_with_regex,
|
||||
extract_golden_quotes_with_regex,
|
||||
fix_json,
|
||||
parse_json_response,
|
||||
)
|
||||
|
||||
from .llm_utils import (
|
||||
call_provider_with_retry,
|
||||
extract_token_usage,
|
||||
extract_response_text,
|
||||
extract_token_usage,
|
||||
)
|
||||
|
||||
from .info_utils import InfoUtils
|
||||
|
||||
__all__ = [
|
||||
# JSON处理工具
|
||||
"fix_json",
|
||||
|
||||
@@ -5,6 +5,7 @@ JSON处理工具模块
|
||||
|
||||
import json
|
||||
import re
|
||||
|
||||
from astrbot.api import logger
|
||||
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ LLM API请求处理工具模块
|
||||
|
||||
import asyncio
|
||||
from typing import Any
|
||||
|
||||
from astrbot.api import logger
|
||||
|
||||
|
||||
|
||||
+27
-13
@@ -4,6 +4,7 @@ Bot实例管理模块
|
||||
"""
|
||||
|
||||
from typing import Any
|
||||
|
||||
from astrbot.api import logger
|
||||
|
||||
|
||||
@@ -48,19 +49,20 @@ class BotManager:
|
||||
"""获取指定平台的bot实例,如果不指定则返回第一个可用的实例"""
|
||||
if platform_id:
|
||||
# 如果指定了平台ID,尝试获取
|
||||
instance = self._bot_instances.get(platform_id)
|
||||
if instance:
|
||||
return instance
|
||||
return self._bot_instances.get(platform_id)
|
||||
|
||||
# 没有指定平台ID,返回第一个可用的实例
|
||||
# 没有指定平台ID
|
||||
if self._bot_instances:
|
||||
first_platform = list(self._bot_instances.keys())[0]
|
||||
if len(self._bot_instances) > 1:
|
||||
logger.debug(
|
||||
f"未指定平台,使用第一个可用平台 '{first_platform}' "
|
||||
f"(共有 {len(self._bot_instances)} 个平台: {list(self._bot_instances.keys())})"
|
||||
)
|
||||
return self._bot_instances[first_platform]
|
||||
# 如果只有一个实例,直接返回
|
||||
if len(self._bot_instances) == 1:
|
||||
return list(self._bot_instances.values())[0]
|
||||
|
||||
# 如果有多个实例,必须指定 platform_id
|
||||
logger.error(
|
||||
f"存在多个Bot实例 {list(self._bot_instances.keys())} 但未指定 platform_id,"
|
||||
"无法确定使用哪个实例。请明确指定 platform_id。"
|
||||
)
|
||||
return None
|
||||
|
||||
# 没有任何平台可用
|
||||
logger.error("没有任何可用的bot实例")
|
||||
@@ -85,14 +87,19 @@ class BotManager:
|
||||
return self._default_platform
|
||||
|
||||
async def auto_discover_bot_instances(self):
|
||||
"""自动发现所有可用的bot实例"""
|
||||
"""自动发现所有可用的bot实例 (仅限 QQ/Aiocqhttp)"""
|
||||
if not self._context or not hasattr(self._context, "platform_manager"):
|
||||
return {}
|
||||
|
||||
platforms = getattr(self._context.platform_manager, "platform_insts", [])
|
||||
# 使用新版 API 获取所有平台实例
|
||||
platforms = self._context.platform_manager.get_insts()
|
||||
discovered = {}
|
||||
|
||||
for platform in platforms:
|
||||
# 严格过滤:只处理 AiocqhttpAdapter (QQ)
|
||||
if platform.metadata.name != "aiocqhttp":
|
||||
continue
|
||||
|
||||
# 获取bot实例
|
||||
bot_client = None
|
||||
if hasattr(platform, "get_client"):
|
||||
@@ -138,6 +145,13 @@ class BotManager:
|
||||
|
||||
def update_from_event(self, event):
|
||||
"""从事件更新bot实例(用于手动命令)"""
|
||||
# 检查是否为 QQ 平台事件
|
||||
if (
|
||||
hasattr(event, "get_platform_name")
|
||||
and event.get_platform_name() != "aiocqhttp"
|
||||
):
|
||||
return False
|
||||
|
||||
if hasattr(event, "bot") and event.bot:
|
||||
# 从事件中获取平台ID
|
||||
platform_id = None
|
||||
|
||||
+2
-1
@@ -4,7 +4,8 @@
|
||||
"""
|
||||
|
||||
import sys
|
||||
from astrbot.api import logger, AstrBotConfig
|
||||
|
||||
from astrbot.api import AstrBotConfig, logger
|
||||
|
||||
|
||||
class ConfigManager:
|
||||
|
||||
@@ -3,10 +3,12 @@
|
||||
负责群聊消息的获取、过滤和预处理
|
||||
"""
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from collections import defaultdict
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from astrbot.api import logger
|
||||
from ...src.models.data_models import GroupStatistics, TokenUsage, EmojiStatistics
|
||||
|
||||
from ...src.models.data_models import EmojiStatistics, GroupStatistics, TokenUsage
|
||||
from ...src.visualization.activity_charts import ActivityVisualizer
|
||||
|
||||
|
||||
|
||||
@@ -3,11 +3,11 @@
|
||||
"""
|
||||
|
||||
from .data_models import (
|
||||
SummaryTopic,
|
||||
UserTitle,
|
||||
GoldenQuote,
|
||||
TokenUsage,
|
||||
GroupStatistics,
|
||||
SummaryTopic,
|
||||
TokenUsage,
|
||||
UserTitle,
|
||||
)
|
||||
|
||||
__all__ = ["SummaryTopic", "UserTitle", "GoldenQuote", "TokenUsage", "GroupStatistics"]
|
||||
|
||||
@@ -3,14 +3,17 @@
|
||||
负责生成各种格式的分析报告
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import base64
|
||||
import aiohttp
|
||||
from datetime import datetime
|
||||
from pathlib import Path
|
||||
|
||||
import aiohttp
|
||||
|
||||
from astrbot.api import logger
|
||||
from .templates import HTMLTemplates
|
||||
|
||||
from ..visualization.activity_charts import ActivityVisualizer
|
||||
import asyncio
|
||||
from .templates import HTMLTemplates
|
||||
|
||||
|
||||
class ReportGenerator:
|
||||
@@ -310,10 +313,11 @@ class ReportGenerator:
|
||||
return False
|
||||
|
||||
# 动态导入 pyppeteer
|
||||
import os
|
||||
import sys
|
||||
|
||||
import pyppeteer
|
||||
from pyppeteer import launch
|
||||
import sys
|
||||
import os
|
||||
|
||||
# 尝试启动浏览器,如果 Chromium 不存在会自动下载
|
||||
logger.info("启动浏览器进行 PDF 转换")
|
||||
|
||||
@@ -4,9 +4,11 @@ HTML模板模块
|
||||
"""
|
||||
|
||||
import os
|
||||
from astrbot.api import logger
|
||||
|
||||
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
||||
|
||||
from astrbot.api import logger
|
||||
|
||||
|
||||
class HTMLTemplates:
|
||||
"""HTML模板管理类"""
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import asyncio
|
||||
import weakref
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from astrbot.api import logger
|
||||
|
||||
|
||||
@@ -95,13 +96,11 @@ class AutoScheduler:
|
||||
)
|
||||
continue
|
||||
|
||||
# 如果所有适配器都尝试失败,记录警告并返回第一个
|
||||
logger.warning(
|
||||
f"⚠️ 无法确定群 {group_id} 属于哪个平台,使用第一个适配器"
|
||||
# 如果所有适配器都尝试失败,记录错误并返回 None
|
||||
logger.error(
|
||||
f"❌ 无法确定群 {group_id} 属于哪个平台 (已尝试: {list(self.bot_manager._bot_instances.keys())})"
|
||||
)
|
||||
first_platform = list(self.bot_manager._bot_instances.keys())[0]
|
||||
logger.warning(f"使用默认平台: {first_platform}")
|
||||
return first_platform
|
||||
return None
|
||||
|
||||
# 没有任何bot实例,返回None
|
||||
logger.error("❌ 没有注册的bot实例")
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
包含PDF处理和通用工具函数
|
||||
"""
|
||||
|
||||
from .pdf_utils import PDFInstaller
|
||||
from .helpers import MessageAnalyzer
|
||||
from .pdf_utils import PDFInstaller
|
||||
|
||||
__all__ = ["PDFInstaller", "MessageAnalyzer"]
|
||||
|
||||
@@ -3,11 +3,12 @@
|
||||
包含消息分析和其他通用功能
|
||||
"""
|
||||
|
||||
from ...src.models.data_models import TokenUsage
|
||||
from ...src.core.message_handler import MessageHandler
|
||||
from astrbot.api import logger
|
||||
|
||||
from ...src.analysis.llm_analyzer import LLMAnalyzer
|
||||
from ...src.analysis.statistics import UserAnalyzer
|
||||
from astrbot.api import logger
|
||||
from ...src.core.message_handler import MessageHandler
|
||||
from ...src.models.data_models import TokenUsage
|
||||
|
||||
|
||||
class MessageAnalyzer:
|
||||
|
||||
@@ -3,9 +3,10 @@ PDF工具模块
|
||||
负责PDF相关的安装和管理功能
|
||||
"""
|
||||
|
||||
import sys
|
||||
import asyncio
|
||||
import sys
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
from astrbot.api import logger
|
||||
|
||||
|
||||
|
||||
@@ -3,8 +3,9 @@
|
||||
参考 astrbot_plugin_github_analyzer 的实现方式
|
||||
"""
|
||||
|
||||
from datetime import datetime
|
||||
from collections import defaultdict
|
||||
from datetime import datetime
|
||||
|
||||
from ..models.data_models import ActivityVisualization
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user