forked from Class-Widgets/Class-Widgets
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathplugin.py
More file actions
124 lines (102 loc) · 5.24 KB
/
plugin.py
File metadata and controls
124 lines (102 loc) · 5.24 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
import importlib
import json
from pathlib import Path
import shutil
from loguru import logger
import conf
class PluginLoader: # 插件加载器
def __init__(self, p_mgr=None):
self.plugins_settings = {}
self.plugins_name = []
self.plugins_dict = {}
self.manager = p_mgr
def set_manager(self, p_mgr):
self.manager = p_mgr
def load_plugins(self):
for folder in Path(conf.PLUGINS_DIR).iterdir():
if folder.is_dir() and (folder / 'plugin.json').exists():
self.plugins_name.append(folder.name) # 检测所有插件
if folder.name not in conf.load_plugin_config()['enabled_plugins']:
continue
relative_path = conf.PLUGINS_DIR.name
module_name = f"{relative_path}.{folder.name}"
try:
module = importlib.import_module(module_name)
if hasattr(module, 'Settings'): # 设置页
plugin_class = getattr(module, "Settings") # 获取 Plugin 类
# 实例化插件
self.plugins_settings[folder.name] = plugin_class(f'{conf.PLUGINS_DIR}/{folder.name}')
if self.manager and hasattr(module, 'Plugin'): # 插件入口
plugin_class = getattr(module, "Plugin") # 获取 Plugin 类
# 实例化插件
self.plugins_dict[folder.name] = plugin_class(
self.manager.get_app_contexts(folder.name), self.manager.method
)
logger.success(f"加载插件成功:{module_name}")
except (ImportError, FileNotFoundError) as e:
logger.warning(f"加载插件 {folder.name} 失败: {e}. 可能缺少文件或依赖项。将禁用此插件。")
plugin_config = conf.load_plugin_config()
if folder.name in plugin_config['enabled_plugins']:
plugin_config['enabled_plugins'].remove(folder.name)
conf.save_plugin_config(plugin_config)
if folder.name in self.plugins_name:
self.plugins_name.remove(folder.name)
continue
except Exception as e:
logger.error(f"加载插件 {folder.name} 时发生未知错误: {e}")
# 大部分情况一般不会影响运行
continue
return self.plugins_name
def run_plugins(self):
for plugin in self.plugins_dict.values():
plugin.execute()
def update_plugins(self):
for plugin in self.plugins_dict.values():
if hasattr(plugin, 'update'):
plugin.update(self.manager.get_app_contexts())
def delete_plugin(self, plugin_name):
plugin_dir = Path(conf.PLUGINS_DIR) / plugin_name
if not plugin_dir.is_dir():
logger.warning(f"插件目录 {plugin_dir} 不存在,无法删除。")
return False
widgets_to_remove = []
if widgets_to_remove:
try:
widget_config_path = Path(conf.base_directory) / 'config' / 'widget.json'
if widget_config_path.exists():
with open(widget_config_path, 'r', encoding='utf-8') as f:
widget_config = json.load(f)
original_widgets = widget_config.get('widgets', [])
# 过滤掉要移除的组件
widget_config['widgets'] = [w for w in original_widgets if w not in widgets_to_remove]
with open(widget_config_path, 'w', encoding='utf-8') as f:
json.dump(widget_config, f, ensure_ascii=False, indent=4)
logger.info(f"已从 config/widget.json 中移除插件 {plugin_name} 的关联组件: {widgets_to_remove}")
else:
logger.warning(f"主配置文件 config/widget.json 不存在,无法移除插件组件。")
except Exception as e:
logger.error(f"更新 config/widget.json 失败: {e}")
if plugin_name in self.plugins_dict:
del self.plugins_dict[plugin_name]
logger.info(f"已移除正在运行的插件实例: {plugin_name}")
if plugin_name in self.plugins_settings:
del self.plugins_settings[plugin_name]
logger.info(f"已移除插件设置实例: {plugin_name}")
plugin_config = conf.load_plugin_config()
if plugin_name in plugin_config.get('enabled_plugins', []):
plugin_config['enabled_plugins'].remove(plugin_name)
conf.save_plugin_config(plugin_config)
logger.info(f"已从启用插件列表中移除: {plugin_name}")
if plugin_name in self.plugins_name:
self.plugins_name.remove(plugin_name)
try:
shutil.rmtree(plugin_dir)
logger.success(f"插件 {plugin_name} 已成功删除。")
return True
except Exception as e:
logger.error(f"删除插件目录 {plugin_dir} 失败: {e}")
return False
p_loader = PluginLoader()
if __name__ == '__main__':
p_loader.load_plugins()
p_loader.run_plugins()