Dev (#28)
* 滚木 * feat: 重构核心架构,增强类型安全与插件管理 本次提交对核心模块进行了深度重构,引入 Pydantic 增强配置管理的类型安全性,并全面优化了插件管理系统。 主要变更详情: 1. 核心架构与配置 - 重构配置加载模块:引入 Pydantic 模型 (`core/config_models.py`),提供严格的配置项类型检查、验证及默认值管理。 - 统一模块结构:规范化模块导入路径,移除冗余的 `__init__.py` 文件,提升项目结构的清晰度。 - 性能优化:集成 Redis 缓存支持 (`RedisManager`),有效降低高频 API 调用开销,提升响应速度。 2. 插件系统升级 - 实现热重载机制:新增插件文件变更监听功能,支持开发过程中自动重载插件,提升开发效率。 - 优化生命周期管理:改进插件加载与卸载逻辑,支持精确卸载指定插件及其关联的命令、事件处理器和定时任务。 3. 功能特性增强 - 新增媒体 API:引入 `MediaAPI` 模块,封装图片、语音等富媒体资源的获取与处理接口。 - 完善权限体系:重构权限管理系统,实现管理员与操作员的分级控制,支持更细粒度的命令权限校验。 4. 代码质量与稳定性 - 全面类型修复:解决 `mypy` 静态类型检查发现的大量类型错误(包括 `CommandManager`、`EventFactory` 及 `Bot` API 签名不匹配问题)。 - 增强错误处理:优化消息处理管道的异常捕获机制,完善关键路径的日志记录,提升系统运行稳定性。 * feat: 添加测试用例并优化代码结构 refactor(permission_manager): 调整初始化顺序和逻辑 fix(admin_manager): 修复初始化逻辑和目录创建问题 feat(ws): 优化Bot实例初始化条件 feat(message): 增强MessageSegment功能并添加测试 feat(events): 支持字符串格式的消息解析 test: 添加核心功能测试用例 refactor(plugin_manager): 改进插件路径处理 style: 清理无用导入和代码 chore: 更新依赖项
This commit is contained in:
37
main.py
37
main.py
@@ -15,7 +15,7 @@ from core.utils.logger import logger
|
||||
|
||||
from core.managers.admin_manager import admin_manager
|
||||
from core.ws import WS
|
||||
from core.managers.plugin_manager import load_all_plugins
|
||||
from core.managers import plugin_manager
|
||||
from core.managers.redis_manager import redis_manager
|
||||
from core.utils.executor import run_in_thread_pool, initialize_executor
|
||||
from core.config_loader import global_config as config
|
||||
@@ -25,6 +25,8 @@ ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, ROOT_DIR)
|
||||
|
||||
|
||||
# 获取插件目录的绝对路径
|
||||
PLUGIN_DIR = os.path.join(ROOT_DIR, "plugins")
|
||||
|
||||
|
||||
class PluginReloadHandler(FileSystemEventHandler):
|
||||
@@ -32,7 +34,7 @@ class PluginReloadHandler(FileSystemEventHandler):
|
||||
文件变更处理器,用于热重载插件
|
||||
|
||||
继承自 watchdog.events.FileSystemEventHandler,
|
||||
监听 base_plugins 目录下的文件变化,并触发插件重载。
|
||||
监听 plugins 目录下的文件变化,并触发插件重载。
|
||||
"""
|
||||
def __init__(self, loop: asyncio.AbstractEventLoop):
|
||||
"""
|
||||
@@ -53,12 +55,14 @@ class PluginReloadHandler(FileSystemEventHandler):
|
||||
if file_system_event.is_directory:
|
||||
return
|
||||
|
||||
src_path = file_system_event.src_path
|
||||
|
||||
# 只监控 py 文件
|
||||
if not file_system_event.src_path.endswith(".py"):
|
||||
if not src_path.endswith(".py"):
|
||||
return
|
||||
|
||||
# 过滤掉一些临时文件
|
||||
if "__pycache__" in file_system_event.src_path:
|
||||
if "__pycache__" in src_path or not src_path.startswith(PLUGIN_DIR):
|
||||
return
|
||||
|
||||
# 简单的防抖动
|
||||
@@ -68,13 +72,18 @@ class PluginReloadHandler(FileSystemEventHandler):
|
||||
|
||||
self.last_reload_time = current_time
|
||||
|
||||
logger.info(f"检测到文件变更: {file_system_event.src_path}")
|
||||
logger.info("正在重载插件...")
|
||||
# 从文件路径解析出模块名
|
||||
# 例如: C:\path\to\project\plugins\bili_parser.py -> plugins.bili_parser
|
||||
relative_path = os.path.relpath(src_path, ROOT_DIR)
|
||||
module_name = os.path.splitext(relative_path.replace(os.sep, '.'))[0]
|
||||
|
||||
logger.info(f"检测到文件变更: {src_path}")
|
||||
logger.info(f"准备重载插件: {module_name}...")
|
||||
|
||||
try:
|
||||
# 使用线程安全的方式在主事件循环中运行异步的插件加载函数
|
||||
asyncio.run_coroutine_threadsafe(run_in_thread_pool(load_all_plugins), self.loop)
|
||||
logger.success("插件重载完成")
|
||||
# 使用线程安全的方式在主事件循环中运行异步的插件重载函数
|
||||
asyncio.run_coroutine_threadsafe(run_in_thread_pool(plugin_manager.reload_plugin, module_name), self.loop)
|
||||
logger.success(f"插件 {module_name} 重载任务已提交")
|
||||
except Exception as e:
|
||||
logger.exception(f"重载失败: {e}")
|
||||
|
||||
@@ -88,8 +97,7 @@ async def main():
|
||||
2. 初始化 WebSocket 客户端
|
||||
3. 建立连接并保持运行
|
||||
"""
|
||||
# 首次加载插件
|
||||
await run_in_thread_pool(load_all_plugins)
|
||||
# 插件加载已移至 core.managers.__init__.py 中自动执行
|
||||
|
||||
# 初始化 Redis 连接
|
||||
await redis_manager.initialize()
|
||||
@@ -114,11 +122,10 @@ async def main():
|
||||
logger.warning(f"插件目录不存在 {plugin_path}")
|
||||
|
||||
try:
|
||||
websocket_client = WS()
|
||||
|
||||
# 初始化代码执行器
|
||||
code_executor = initialize_executor(websocket_client, config)
|
||||
websocket_client.bot.code_executor = code_executor # 将执行器实例附加到 bot.bot 对象上
|
||||
code_executor = initialize_executor(config)
|
||||
|
||||
websocket_client = WS(code_executor=code_executor)
|
||||
|
||||
# 启动代码执行器的后台 worker
|
||||
logger.debug("[Main] 检查是否需要启动代码执行 Worker...")
|
||||
|
||||
Reference in New Issue
Block a user