From 9962b7058bdd28350bda8e26a4a7421bebd6dab6 Mon Sep 17 00:00:00 2001 From: Light Beacon <2682645990@qq.com> Date: Thu, 26 Jan 2023 15:31:13 +0800 Subject: [PATCH] module reload --- core/loader/__init__.py | 32 ++++++++++++++++++++++++++++++++ modules/core/modules.py | 28 ++++++++++++++++++++++++++-- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/core/loader/__init__.py b/core/loader/__init__.py index 6b4854e7..4fc5b0d0 100644 --- a/core/loader/__init__.py +++ b/core/loader/__init__.py @@ -2,6 +2,7 @@ import importlib import os import re import traceback +import sys from typing import Dict, Union from core.elements import Command, Schedule, RegexCommand, StartUp, PrivateAssets @@ -54,6 +55,13 @@ class ModulesManager: else: raise ValueError(f'Duplicate bind prefix "{module.bind_prefix}"') + @staticmethod + def remove_module(module_name): + if module_name in ModulesManager.modules: + ModulesManager.modules.pop(module_name) + else: + raise ValueError(f'Moudule "{module_name}" is not exist') + @staticmethod def bind_to_module(bind_prefix: str, meta): if bind_prefix in ModulesManager.modules: @@ -125,3 +133,27 @@ class ModulesManager: else: d.update({module.bind_prefix: module}) return d + + @staticmethod + def reload_module(module_name:str): + """ + 重载该模块 + """ + try: + module = sys.modules['modules.' + module_name] + if module_name in ModulesManager.modules: + ModulesManager.remove_module(module_name) + cnt = 0 + loadedModList = list(sys.modules.keys()) + for mod in loadedModList: + if mod.startswith(f'modules.{module_name}.'): + importlib.reload(sys.modules[mod]) + cnt += 1 + importlib.reload(module) + Logger.info(f'Succeeded reloaded modules.{module_name}!') + return cnt + except: + tb = traceback.format_exc() + errmsg = f'Failed to reload {module_name}: \n{tb}' + Logger.error(errmsg) + return -1 \ No newline at end of file diff --git a/modules/core/modules.py b/modules/core/modules.py index 76716ab3..ed37de7f 100644 --- a/modules/core/modules.py +++ b/modules/core/modules.py @@ -11,8 +11,8 @@ from database import BotDBUtil module = on_command('module', base=True, - alias={'enable': 'module enable', 'disable': 'module disable'}, - developers=['OasisAkari'], + alias={'enable': 'module enable', 'disable': 'module disable','reload':'module reload'}, + developers=['OasisAkari','Light-Beacon'], required_admin=True ) @@ -21,6 +21,7 @@ module = on_command('module', 'enable all {开启所有模块}', 'disable ... {关闭一个/多个模块}', 'disable all {关闭所有模块。}', + 'reload ... {重载一个/多个模块。}', 'list {查看所有可用模块}'], exclude_from=['QQ|Guild']) async def _(msg: MessageSession): if msg.parsed_msg.get('list', False): @@ -32,6 +33,7 @@ async def _(msg: MessageSession): 'enable all [-g] {开启所有模块}', 'disable [-g] ... {关闭一个/多个模块}', 'disable all [-g] {关闭所有模块。}', + 'reload [-f] {重载一个/多个模块。}', 'list {查看所有可用模块}'], options_desc={'-g': '对频道进行全局操作'}, available_for=['QQ|Guild']) async def _(msg: MessageSession): @@ -143,6 +145,19 @@ async def config_modules(msg: MessageSession): msglist.append(f'失败:“{x}”模块已经关闭') else: msglist.append(f'成功:关闭模块“{x}”') + elif msg.parsed_msg.get('reload', False): + if '-f' in msg.parsed_msg and msg.parsed_msg['-f']: + msglist.append(module_reload(module_)) + else: + if module_ not in modules_: + msglist.append(f'失败:“{module_}”模块尚未绑定') + else: + if not msg.checkSuperUser(): + msglist.append(f'失败:你没有重载模块的权限。') + elif isinstance(modules_[module_], Command) and modules_[module_].base: + msglist.append(f'失败:“{module_}”为基础模块,无法重载。') + else: + msglist.append(module_reload(module_)) if msglist is not None: if not recommend_modules_help_doc_list: await msg.finish('\n'.join(msglist)) @@ -350,3 +365,12 @@ async def modules_help(msg: MessageSession): send = await msg.sendMessage('\n'.join(help_msg)) await msg.sleep(60) await send.delete() + +def module_reload(module_): + reloadCnt = ModulesManager.reload_module(module_) + if reloadCnt > 0: + return f'成功:重载模块“{module_}”以及该模块下的{reloadCnt}个文件。' + elif reloadCnt == 0: + return f'成功:重载模块“{module_}”,未发现已加载的其余文件' + else: + return f'重载模块“{module_}”失败。' \ No newline at end of file