mirror of
https://github.com/Nezumi-2711/astrbot_plugin_qq_group_daily_analysis.git
synced 2026-09-22 13:38:43 +00:00
refactor: integrate PlatformAdapterFactory into BotManager
- BotManager now creates PlatformAdapter alongside bot instances - Added get_adapter(), has_adapter(), can_analyze() methods for DDD access - Added _detect_platform_name() for automatic platform detection - Fixed incorrect relative imports in message_handler.py and helpers.py - Updated get_status_info() to include adapter information
This commit is contained in:
+133
-7
@@ -1,19 +1,29 @@
|
||||
"""
|
||||
Bot实例管理模块
|
||||
统一管理bot实例的获取、设置和使用
|
||||
|
||||
Refactored to integrate with DDD PlatformAdapter architecture.
|
||||
"""
|
||||
|
||||
from typing import Any
|
||||
from typing import Any, Optional
|
||||
|
||||
from astrbot.api import logger
|
||||
|
||||
from ..infrastructure.platform import PlatformAdapter, PlatformAdapterFactory
|
||||
|
||||
|
||||
class BotManager:
|
||||
"""Bot实例管理器 - 统一管理所有bot相关操作"""
|
||||
"""
|
||||
Bot实例管理器 - 统一管理所有bot相关操作
|
||||
|
||||
Integrates with DDD architecture by creating PlatformAdapter instances
|
||||
alongside raw bot instances for cross-platform support.
|
||||
"""
|
||||
|
||||
def __init__(self, config_manager):
|
||||
self.config_manager = config_manager
|
||||
self._bot_instances = {} # 改为字典:{platform_id: bot_instance}
|
||||
self._bot_instances = {} # {platform_id: bot_instance}
|
||||
self._adapters = {} # {platform_id: PlatformAdapter} - DDD integration
|
||||
self._platforms = {} # 存储平台对象以访问配置
|
||||
self._bot_qq_ids = [] # 支持多个QQ号
|
||||
self._context = None
|
||||
@@ -24,13 +34,33 @@ class BotManager:
|
||||
"""设置AstrBot上下文"""
|
||||
self._context = context
|
||||
|
||||
def set_bot_instance(self, bot_instance, platform_id=None):
|
||||
"""设置bot实例,支持指定平台ID"""
|
||||
def set_bot_instance(self, bot_instance, platform_id=None, platform_name=None):
|
||||
"""
|
||||
设置bot实例,支持指定平台ID
|
||||
|
||||
Also creates a PlatformAdapter if the platform is supported.
|
||||
"""
|
||||
if not platform_id:
|
||||
platform_id = self._get_platform_id_from_instance(bot_instance)
|
||||
|
||||
if bot_instance and platform_id:
|
||||
self._bot_instances[platform_id] = bot_instance
|
||||
|
||||
# Create PlatformAdapter for DDD integration
|
||||
if platform_name is None:
|
||||
platform_name = self._detect_platform_name(bot_instance)
|
||||
|
||||
if platform_name and PlatformAdapterFactory.is_supported(platform_name):
|
||||
adapter_config = {
|
||||
"bot_qq_ids": self._bot_qq_ids.copy(),
|
||||
}
|
||||
adapter = PlatformAdapterFactory.create(
|
||||
platform_name, bot_instance, adapter_config
|
||||
)
|
||||
if adapter:
|
||||
self._adapters[platform_id] = adapter
|
||||
logger.debug(f"Created PlatformAdapter for {platform_id} ({platform_name})")
|
||||
|
||||
# 自动提取QQ号
|
||||
bot_qq_id = self._extract_bot_qq_id(bot_instance)
|
||||
if bot_qq_id and bot_qq_id not in self._bot_qq_ids:
|
||||
@@ -91,8 +121,79 @@ class BotManager:
|
||||
return bot_instance.platform
|
||||
return self._default_platform
|
||||
|
||||
def _detect_platform_name(self, bot_instance) -> Optional[str]:
|
||||
"""
|
||||
Detect platform name from bot instance for adapter creation.
|
||||
|
||||
Returns platform name like 'aiocqhttp', 'telegram', etc.
|
||||
"""
|
||||
# Check for aiocqhttp/OneBot
|
||||
if hasattr(bot_instance, "call_action"):
|
||||
return "aiocqhttp"
|
||||
|
||||
# Check for platform attribute
|
||||
if hasattr(bot_instance, "platform"):
|
||||
platform = bot_instance.platform
|
||||
if isinstance(platform, str):
|
||||
return platform
|
||||
|
||||
# Check class name patterns
|
||||
class_name = type(bot_instance).__name__.lower()
|
||||
if "cqhttp" in class_name or "onebot" in class_name:
|
||||
return "aiocqhttp"
|
||||
if "telegram" in class_name:
|
||||
return "telegram"
|
||||
if "discord" in class_name:
|
||||
return "discord"
|
||||
|
||||
return None
|
||||
|
||||
# ==================== DDD Integration Methods ====================
|
||||
|
||||
def get_adapter(self, platform_id: str = None) -> Optional[PlatformAdapter]:
|
||||
"""
|
||||
Get PlatformAdapter for the specified platform.
|
||||
|
||||
This is the primary method for DDD-based operations.
|
||||
"""
|
||||
if platform_id:
|
||||
return self._adapters.get(platform_id)
|
||||
|
||||
if self._adapters:
|
||||
if len(self._adapters) == 1:
|
||||
return list(self._adapters.values())[0]
|
||||
|
||||
logger.error(
|
||||
f"Multiple adapters exist {list(self._adapters.keys())} "
|
||||
"but no platform_id specified."
|
||||
)
|
||||
return None
|
||||
|
||||
return None
|
||||
|
||||
def get_all_adapters(self) -> dict:
|
||||
"""Get all PlatformAdapter instances {platform_id: adapter}"""
|
||||
return self._adapters.copy()
|
||||
|
||||
def has_adapter(self, platform_id: str = None) -> bool:
|
||||
"""Check if adapter exists for the platform"""
|
||||
if platform_id:
|
||||
return platform_id in self._adapters
|
||||
return bool(self._adapters)
|
||||
|
||||
def can_analyze(self, platform_id: str = None) -> bool:
|
||||
"""Check if the platform supports analysis using DDD capabilities"""
|
||||
adapter = self.get_adapter(platform_id)
|
||||
if adapter:
|
||||
return adapter.get_capabilities().can_analyze()
|
||||
return False
|
||||
|
||||
async def auto_discover_bot_instances(self):
|
||||
"""自动发现所有可用的bot实例"""
|
||||
"""
|
||||
自动发现所有可用的bot实例
|
||||
|
||||
Also creates PlatformAdapter for each discovered bot.
|
||||
"""
|
||||
if not self._context or not hasattr(self._context, "platform_manager"):
|
||||
return {}
|
||||
|
||||
@@ -114,10 +215,25 @@ class BotManager:
|
||||
and hasattr(platform.metadata, "id")
|
||||
):
|
||||
platform_id = platform.metadata.id
|
||||
self.set_bot_instance(bot_client, platform_id)
|
||||
|
||||
# Detect platform name from metadata
|
||||
platform_name = None
|
||||
if hasattr(platform.metadata, "name"):
|
||||
platform_name = platform.metadata.name
|
||||
elif hasattr(platform.metadata, "type"):
|
||||
platform_name = platform.metadata.type
|
||||
|
||||
self.set_bot_instance(bot_client, platform_id, platform_name)
|
||||
self._platforms[platform_id] = platform
|
||||
discovered[platform_id] = bot_client
|
||||
|
||||
# Log adapter creation results
|
||||
if self._adapters:
|
||||
logger.info(
|
||||
f"Created {len(self._adapters)} PlatformAdapter(s): "
|
||||
f"{list(self._adapters.keys())}"
|
||||
)
|
||||
|
||||
return discovered
|
||||
|
||||
async def initialize_from_config(self):
|
||||
@@ -136,12 +252,22 @@ class BotManager:
|
||||
|
||||
def get_status_info(self) -> dict[str, Any]:
|
||||
"""获取bot管理器状态信息"""
|
||||
adapter_info = {}
|
||||
for pid, adapter in self._adapters.items():
|
||||
caps = adapter.get_capabilities()
|
||||
adapter_info[pid] = {
|
||||
"platform_name": caps.platform_name,
|
||||
"can_analyze": caps.can_analyze(),
|
||||
"supports_image": caps.supports_image_message,
|
||||
}
|
||||
|
||||
return {
|
||||
"has_bot_instance": self.has_bot_instance(),
|
||||
"has_bot_qq_id": self.has_bot_qq_id(),
|
||||
"bot_qq_ids": self._bot_qq_ids,
|
||||
"platform_count": len(self._bot_instances),
|
||||
"platforms": list(self._bot_instances.keys()),
|
||||
"adapters": adapter_info, # DDD integration info
|
||||
"ready_for_auto_analysis": self.is_ready_for_auto_analysis(),
|
||||
}
|
||||
|
||||
|
||||
@@ -8,8 +8,8 @@ from datetime import datetime, timedelta
|
||||
|
||||
from astrbot.api import logger
|
||||
|
||||
from ...src.models.data_models import EmojiStatistics, GroupStatistics, TokenUsage
|
||||
from ...src.visualization.activity_charts import ActivityVisualizer
|
||||
from ..models.data_models import EmojiStatistics, GroupStatistics, TokenUsage
|
||||
from ..visualization.activity_charts import ActivityVisualizer
|
||||
|
||||
|
||||
class MessageHandler:
|
||||
|
||||
@@ -7,10 +7,10 @@ import asyncio
|
||||
|
||||
from astrbot.api import logger
|
||||
|
||||
from ...src.analysis.llm_analyzer import LLMAnalyzer
|
||||
from ...src.analysis.statistics import UserAnalyzer
|
||||
from ...src.core.message_handler import MessageHandler
|
||||
from ...src.models.data_models import TokenUsage
|
||||
from ..analysis.llm_analyzer import LLMAnalyzer
|
||||
from ..analysis.statistics import UserAnalyzer
|
||||
from ..core.message_handler import MessageHandler
|
||||
from ..models.data_models import TokenUsage
|
||||
|
||||
|
||||
class MessageAnalyzer:
|
||||
|
||||
Reference in New Issue
Block a user