commit
3d5761157a
@ -1,7 +1,9 @@
|
|||||||
import concurrent
|
import concurrent
|
||||||
import concurrent.futures
|
import concurrent.futures
|
||||||
|
import os
|
||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
|
from pathlib import Path
|
||||||
from typing import List, Any, Dict, Tuple, Optional
|
from typing import List, Any, Dict, Tuple, Optional
|
||||||
|
|
||||||
from watchdog.events import FileSystemEventHandler
|
from watchdog.events import FileSystemEventHandler
|
||||||
@ -39,8 +41,9 @@ class PluginMonitorHandler(FileSystemEventHandler):
|
|||||||
self.__last_modified = current_time
|
self.__last_modified = current_time
|
||||||
# 读取插件根目录下的__init__.py文件,读取class XXXX(_PluginBase)的类名
|
# 读取插件根目录下的__init__.py文件,读取class XXXX(_PluginBase)的类名
|
||||||
try:
|
try:
|
||||||
plugin_dir = event.src_path.split("plugins/")[1].split("/")[0]
|
# 使用os.path和pathlib处理跨平台的路径问题
|
||||||
init_file = settings.ROOT_PATH / "app" / "plugins" / plugin_dir / "__init__.py"
|
plugin_dir = event.src_path.split("plugins" + os.sep)[1].split(os.sep)[0]
|
||||||
|
init_file = Path(settings.ROOT_PATH) / "app" / "plugins" / plugin_dir / "__init__.py"
|
||||||
with open(init_file, "r", encoding="utf-8") as f:
|
with open(init_file, "r", encoding="utf-8") as f:
|
||||||
lines = f.readlines()
|
lines = f.readlines()
|
||||||
pid = None
|
pid = None
|
||||||
@ -91,11 +94,16 @@ class PluginManager(metaclass=Singleton):
|
|||||||
# 扫描插件目录
|
# 扫描插件目录
|
||||||
plugin_package = "app.plugins"
|
plugin_package = "app.plugins"
|
||||||
if pid:
|
if pid:
|
||||||
plugin_package = f"{plugin_package}.{pid.lower()}"
|
plugins = ModuleHelper.load_with_pre_filter(
|
||||||
plugins = ModuleHelper.load(
|
"app.plugins",
|
||||||
plugin_package,
|
filter_func=lambda name, obj:
|
||||||
filter_func=lambda _, obj: hasattr(obj, 'init_plugin') and hasattr(obj, "plugin_name")
|
hasattr(obj, 'init_plugin') and hasattr(obj, "plugin_name") and name == pid
|
||||||
)
|
)
|
||||||
|
else:
|
||||||
|
plugins = ModuleHelper.load(
|
||||||
|
"app.plugins",
|
||||||
|
filter_func=lambda _, obj: hasattr(obj, 'init_plugin') and hasattr(obj, "plugin_name")
|
||||||
|
)
|
||||||
# 已安装插件
|
# 已安装插件
|
||||||
installed_plugins = self.systemconfig.get(SystemConfigKey.UserInstalledPlugins) or []
|
installed_plugins = self.systemconfig.get(SystemConfigKey.UserInstalledPlugins) or []
|
||||||
# 排序
|
# 排序
|
||||||
|
@ -40,6 +40,38 @@ class ModuleHelper:
|
|||||||
|
|
||||||
return submodules
|
return submodules
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_with_pre_filter(cls, package_path, filter_func=lambda name, obj: True):
|
||||||
|
"""
|
||||||
|
导入子模块
|
||||||
|
:param package_path: 父包名
|
||||||
|
:param filter_func: 子模块过滤函数,入参为模块名和模块对象,返回True则导入,否则不导入
|
||||||
|
:return:
|
||||||
|
"""
|
||||||
|
|
||||||
|
submodules: list = []
|
||||||
|
packages = importlib.import_module(package_path)
|
||||||
|
for importer, package_name, _ in pkgutil.iter_modules(packages.__path__):
|
||||||
|
try:
|
||||||
|
if package_name.startswith('_'):
|
||||||
|
continue
|
||||||
|
full_package_name = f'{package_path}.{package_name}'
|
||||||
|
module = importlib.import_module(full_package_name)
|
||||||
|
# 预检查模块中的对象
|
||||||
|
candidates = [(name, obj) for name, obj in module.__dict__.items() if
|
||||||
|
not name.startswith('_') and isinstance(obj, type)]
|
||||||
|
# 确定是否需要重新加载
|
||||||
|
if any(filter_func(name, obj) for name, obj in candidates):
|
||||||
|
importlib.reload(module)
|
||||||
|
# reload后,对象已经发生变更,重新过滤已经重新加载后的模块中的对象
|
||||||
|
for name, obj in module.__dict__.items():
|
||||||
|
if not name.startswith('_') and isinstance(obj, type) and filter_func(name, obj):
|
||||||
|
submodules.append(obj)
|
||||||
|
except Exception as err:
|
||||||
|
logger.debug(f'加载模块 {package_name} 失败:{str(err)} - {traceback.format_exc()}')
|
||||||
|
|
||||||
|
return submodules
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def dynamic_import_all_modules(base_path: Path, package_name: str):
|
def dynamic_import_all_modules(base_path: Path, package_name: str):
|
||||||
"""
|
"""
|
||||||
|
Loading…
x
Reference in New Issue
Block a user