2018-09-23 17:04:51 +08:00
|
|
|
|
# -*- coding: utf-8 -*-
|
2018-09-24 14:51:53 +08:00
|
|
|
|
"""
|
|
|
|
|
管理插件的加载 , 卸载 , 监控文件的添加/删除.
|
|
|
|
|
"""
|
|
|
|
|
import os, time, sys , importlib, sip
|
|
|
|
|
# ==添加插件的搜索路径==
|
2018-09-23 17:04:51 +08:00
|
|
|
|
#__file__ 为此文件路径 , 在ipython里是测不出来的
|
|
|
|
|
pluginsManagerPath = os.path.dirname(os.path.abspath(__file__))
|
|
|
|
|
#主脚本目录
|
|
|
|
|
mainPath = os.path.dirname(pluginsManagerPath)
|
|
|
|
|
#自定义插件目录
|
|
|
|
|
pluginsPath = os.path.join( mainPath, "Plugins")
|
2018-09-24 14:51:53 +08:00
|
|
|
|
pluginsPath2 = os.path.join( os.path.dirname(sys.argv[0]), "Plugins")
|
2018-09-23 17:04:51 +08:00
|
|
|
|
#以后可能会有其他插件目录
|
2018-09-24 14:51:53 +08:00
|
|
|
|
AllPluginsPath = {"customer":pluginsPath,
|
|
|
|
|
"afterPacket":pluginsPath2}
|
2018-09-23 17:04:51 +08:00
|
|
|
|
#设置模块搜索路径
|
|
|
|
|
for key in AllPluginsPath :
|
|
|
|
|
if AllPluginsPath[key] not in sys.path:
|
|
|
|
|
sys.path.insert(0, AllPluginsPath[key])
|
2018-09-24 14:51:53 +08:00
|
|
|
|
# ==添加插件的搜索路径==
|
2018-09-18 18:53:34 +08:00
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
from copy import deepcopy
|
2018-09-18 18:53:34 +08:00
|
|
|
|
|
|
|
|
|
from PyQt5.QtCore import *
|
|
|
|
|
from PyQt5.QtGui import *
|
|
|
|
|
from PyQt5.QtWidgets import *
|
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
from PluginManager.PluginStore import PluginStore
|
|
|
|
|
from PluginManager.PluginStore.StoreModel import FileModel
|
2018-09-18 18:53:34 +08:00
|
|
|
|
|
|
|
|
|
from Tools.pmf_myjson import *
|
|
|
|
|
|
2018-09-20 18:15:34 +08:00
|
|
|
|
"setting_flie -> From Tools.pmf_myjson , json写入的位置"
|
|
|
|
|
|
2018-09-18 18:53:34 +08:00
|
|
|
|
class PluginManager(QObject):
|
2018-09-24 14:51:53 +08:00
|
|
|
|
"""
|
|
|
|
|
管理插件的加载 , 卸载 , 监控文件的添加/删除.
|
|
|
|
|
"""
|
2018-09-23 17:04:51 +08:00
|
|
|
|
def __init__(self, parent=None, *args, **kwargs):
|
|
|
|
|
super(PluginManager, self).__init__(parent, *args, **kwargs)
|
2018-09-18 18:53:34 +08:00
|
|
|
|
self.__mw = parent
|
|
|
|
|
self.__initUI()
|
2018-09-23 17:04:51 +08:00
|
|
|
|
|
|
|
|
|
self.pluginDirs = {"pluginFolder": os.path.join(
|
|
|
|
|
os.path.abspath("./"),
|
|
|
|
|
"Plugins"), }
|
|
|
|
|
|
|
|
|
|
self.header = ["PlugName",
|
|
|
|
|
"Allow", "CreateTime", "ModifyTime"]
|
|
|
|
|
|
|
|
|
|
self.pluginsInfo = {
|
|
|
|
|
"StartModule": {},
|
2018-09-24 14:51:53 +08:00
|
|
|
|
|
2018-09-20 18:15:34 +08:00
|
|
|
|
}
|
2018-09-23 17:04:51 +08:00
|
|
|
|
# self.jsonPlugin :{插件名:{header参数}}
|
2018-09-20 18:15:34 +08:00
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
self.jsonPlugin = None
|
|
|
|
|
|
|
|
|
|
def __initUI(self):
|
2018-09-24 14:51:53 +08:00
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
mw = self.__mw
|
|
|
|
|
if mw.findChild(QMenuBar, "menuBar"):
|
2018-09-24 14:51:53 +08:00
|
|
|
|
# 插入到mainwindow的menuBar下 , 点击查看弹出插件加载情况窗体===
|
2018-09-23 17:04:51 +08:00
|
|
|
|
mw.menuPlugin = QAction("Plugin", self.__mw.menuBar,
|
|
|
|
|
triggered=self.__createPluginStoreDialog)
|
|
|
|
|
|
|
|
|
|
mw.menuBar.addAction(self.__mw.menuPlugin)
|
2018-09-24 14:51:53 +08:00
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
else:
|
|
|
|
|
QMessageBox.information(mw, "", "主窗体没有菜单栏, 请先创建.")
|
2018-09-20 18:15:34 +08:00
|
|
|
|
|
2018-09-20 14:06:56 +08:00
|
|
|
|
# 文件监听器
|
2018-09-23 17:04:51 +08:00
|
|
|
|
self.model = FileModel(self)
|
|
|
|
|
self.model.setRootPath("./Plugins")
|
|
|
|
|
self.model.setFilter(QDir.Files)
|
|
|
|
|
self.model.setNameFilters(["Plugin*.py"])
|
|
|
|
|
self.model.setNameFilterDisables(False);
|
|
|
|
|
self.index = self.model.index("./Plugins")
|
2018-09-20 14:06:56 +08:00
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
self.model.directoryLoaded.connect(self.start)
|
2018-09-24 14:51:53 +08:00
|
|
|
|
|
2018-09-18 18:53:34 +08:00
|
|
|
|
def __createPluginStoreDialog(self):
|
2018-09-20 14:06:56 +08:00
|
|
|
|
"""
|
|
|
|
|
显示插件加载情况的 窗体.
|
|
|
|
|
"""
|
2018-09-24 14:51:53 +08:00
|
|
|
|
if not hasattr(self, "dia"):
|
|
|
|
|
self.dia = PluginStore.PluginStore(self, self.__mw)
|
2018-09-23 17:04:51 +08:00
|
|
|
|
|
2018-09-24 14:51:53 +08:00
|
|
|
|
self.dia.show()
|
|
|
|
|
|
|
|
|
|
def __m_rowsRemoved(self, index, first, last):
|
|
|
|
|
"""
|
|
|
|
|
文件被删除或重命名时候被调用.
|
|
|
|
|
"""
|
2018-09-23 17:04:51 +08:00
|
|
|
|
print("removeName:", self.model.index(first, 0, index).data(),first )
|
|
|
|
|
mod = (self.model.index(first, 0, index).data())[:-3]
|
|
|
|
|
|
|
|
|
|
self.unload(mod)
|
2018-09-24 14:51:53 +08:00
|
|
|
|
self.pluginsInfo["StartModule"].pop(mod)
|
|
|
|
|
self.delJson(self.jsonPlugin , self.pluginsInfo["StartModule"])
|
|
|
|
|
|
|
|
|
|
# pop的步骤u已经在deljson中执行
|
|
|
|
|
# self.jsonPlugin.pop(mod)
|
|
|
|
|
|
|
|
|
|
def __m_rowsInserted(self, index, first, last):
|
|
|
|
|
"""
|
|
|
|
|
文件增加或重命名时候被调用.
|
|
|
|
|
"""
|
2018-09-23 17:04:51 +08:00
|
|
|
|
print("insertName:", self.model.index(first, 0, index).data(), first)
|
|
|
|
|
f = self.model.index(first, 0, index).data()
|
|
|
|
|
mod = f[:-3]
|
2018-09-24 14:51:53 +08:00
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
fullPath = os.path.join(self.pluginDirs["pluginFolder"], f)
|
|
|
|
|
self.pluginsInfo["StartModule"][mod] = {"path": fullPath}
|
2018-09-24 14:51:53 +08:00
|
|
|
|
mod, data = self.addJson(fullPath, mod)
|
|
|
|
|
|
|
|
|
|
self.jsonPlugin[mod] = data
|
2018-09-20 18:15:34 +08:00
|
|
|
|
|
2018-09-24 14:51:53 +08:00
|
|
|
|
self.load(mod)
|
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
def start(self):
|
|
|
|
|
"""
|
|
|
|
|
self.model 异步加载完成之后开始调用 self.startGetPlugin.
|
2018-09-18 18:53:34 +08:00
|
|
|
|
"""
|
2018-09-23 17:04:51 +08:00
|
|
|
|
self.jsonPlugin = self.startGetPlugin(self.pluginDirs['pluginFolder'])
|
|
|
|
|
# print("jsonPlugin:", self.jsonPlugin,"\n",
|
|
|
|
|
# "pluginsModule:", self.pluginsInfo)
|
|
|
|
|
self.loadAll()
|
|
|
|
|
|
2018-09-24 14:51:53 +08:00
|
|
|
|
self.model.rowsAboutToBeRemoved.connect(self.__m_rowsRemoved)
|
|
|
|
|
self.model.rowsInserted.connect(self.__m_rowsInserted)
|
2018-09-23 17:04:51 +08:00
|
|
|
|
self.model.directoryLoaded.disconnect(self.start)
|
2018-09-24 14:51:53 +08:00
|
|
|
|
self.__createPluginStoreDialog()
|
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
def startGetPlugin(self, pluginFolder: "./Plugins", CHANGE=False) -> "FoJson":
|
|
|
|
|
"""
|
2018-09-24 14:51:53 +08:00
|
|
|
|
1 . 程序启动加载插件.
|
2018-09-18 18:53:34 +08:00
|
|
|
|
"""
|
|
|
|
|
try:
|
2018-09-23 17:04:51 +08:00
|
|
|
|
jsonPlugin = mfunc_readJson(setting_flie)
|
|
|
|
|
|
2018-09-18 18:53:34 +08:00
|
|
|
|
except:
|
2018-09-23 17:04:51 +08:00
|
|
|
|
jsonPlugin = {}
|
|
|
|
|
|
|
|
|
|
pluginInfo = {}
|
|
|
|
|
|
|
|
|
|
rowCount = self.model.rowCount(self.index)
|
|
|
|
|
|
|
|
|
|
for row in range(rowCount):
|
|
|
|
|
index = self.model.index(row, 0, self.index)
|
|
|
|
|
# 文件名
|
|
|
|
|
f = index.data()
|
|
|
|
|
# 去掉后缀 , 加入模块
|
|
|
|
|
module = f[:-3]
|
|
|
|
|
fullPath = os.path.join(pluginFolder, f)
|
|
|
|
|
|
|
|
|
|
pluginInfo[module] = {"path": fullPath}
|
|
|
|
|
try:
|
|
|
|
|
if module not in jsonPlugin:
|
2018-09-20 18:15:34 +08:00
|
|
|
|
self.addJson(fullPath, module)
|
2018-09-23 17:04:51 +08:00
|
|
|
|
except:
|
|
|
|
|
self.addJson(fullPath, module)
|
|
|
|
|
|
2018-09-20 18:15:34 +08:00
|
|
|
|
if CHANGE is False:
|
2018-09-23 17:04:51 +08:00
|
|
|
|
self.pluginsInfo["StartModule"] = deepcopy(pluginInfo)
|
|
|
|
|
|
|
|
|
|
jsonPlugin = self.delJson(jsonPlugin, pluginInfo)
|
2018-09-20 18:15:34 +08:00
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
# print("jsonPlugin",jsonPlugin, "\n", "pluginInfo",pluginInfo )
|
2018-09-20 18:15:34 +08:00
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
return jsonPlugin
|
|
|
|
|
|
|
|
|
|
def addJson(self, fullPath, module) -> "ToJson":
|
2018-09-24 14:51:53 +08:00
|
|
|
|
"""
|
|
|
|
|
1.1写入插件 的json配置.
|
|
|
|
|
"""
|
2018-09-20 18:15:34 +08:00
|
|
|
|
# 插件创建时间
|
2018-09-23 17:04:51 +08:00
|
|
|
|
_ctime = time.localtime(os.stat(fullPath).st_ctime)
|
|
|
|
|
ctime = time.strftime("%Y-%m-%d-%H:%M:%S", _ctime)
|
2018-09-20 18:15:34 +08:00
|
|
|
|
# 插件修改时间
|
|
|
|
|
_mtime = time.localtime(os.stat(fullPath).st_mtime)
|
2018-09-23 17:04:51 +08:00
|
|
|
|
mtime = time.strftime("%Y-%m-%d-%H:%M:%S", _mtime)
|
2018-09-20 18:15:34 +08:00
|
|
|
|
# 写入配置
|
2018-09-24 14:51:53 +08:00
|
|
|
|
data = {
|
|
|
|
|
self.header[1]: True, # allow
|
|
|
|
|
self.header[2]: ctime, # cteateTime
|
|
|
|
|
self.header[3]: mtime, # modifyTime
|
|
|
|
|
}
|
|
|
|
|
mfunc_AKrCVJson(module, data , self=self)
|
|
|
|
|
|
|
|
|
|
return module, data
|
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
def delJson(self, jsonPlugin, pluginInfo) -> "ToJson":
|
2018-09-20 14:06:56 +08:00
|
|
|
|
"""
|
2018-09-24 14:51:53 +08:00
|
|
|
|
1.2删除插件 的json配置.
|
2018-09-20 14:06:56 +08:00
|
|
|
|
"""
|
2018-09-20 18:15:34 +08:00
|
|
|
|
# 添加完重新加载一遍看是否有插件删除
|
2018-09-23 17:04:51 +08:00
|
|
|
|
if jsonPlugin == {}:
|
|
|
|
|
jsonPlugin = mfunc_readJson(setting_flie)
|
|
|
|
|
|
|
|
|
|
if len(jsonPlugin) - len(pluginInfo):
|
|
|
|
|
long, short = jsonPlugin, pluginInfo
|
|
|
|
|
else:
|
|
|
|
|
long, short = pluginInfo, jsonPlugin
|
|
|
|
|
|
|
|
|
|
with open(setting_flie, 'a+', encoding='utf-8') as f:
|
|
|
|
|
# 被删除的插件集合
|
|
|
|
|
delPlugin = set(long) - set(short)
|
|
|
|
|
for item in delPlugin:
|
|
|
|
|
jsonPlugin.pop(item)
|
|
|
|
|
# 写入配置
|
|
|
|
|
mfunc_reDumpJson(f, jsonPlugin)
|
2018-09-20 18:15:34 +08:00
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
return jsonPlugin
|
2018-09-24 14:51:53 +08:00
|
|
|
|
|
2018-09-18 18:53:34 +08:00
|
|
|
|
# 加载所有插件
|
|
|
|
|
def loadAll(self):
|
2018-09-24 14:51:53 +08:00
|
|
|
|
"""
|
|
|
|
|
2.加载所有模块.
|
|
|
|
|
"""
|
2018-09-23 17:04:51 +08:00
|
|
|
|
for mod in self.jsonPlugin:
|
|
|
|
|
if self.jsonPlugin[mod]["Allow"]:
|
2018-09-20 14:06:56 +08:00
|
|
|
|
try:
|
|
|
|
|
self.load(mod)
|
|
|
|
|
except:
|
|
|
|
|
continue
|
2018-09-23 17:04:51 +08:00
|
|
|
|
else:
|
|
|
|
|
self.pluginsInfo["StartModule"][mod]["active"] = False
|
|
|
|
|
|
2018-09-18 18:53:34 +08:00
|
|
|
|
# 加载插件
|
2018-09-23 17:04:51 +08:00
|
|
|
|
def load(self, mod: "str"):
|
2018-09-24 14:51:53 +08:00
|
|
|
|
"""
|
|
|
|
|
2.1 载入模块.
|
|
|
|
|
"""
|
2018-09-20 14:06:56 +08:00
|
|
|
|
try:
|
2018-09-23 17:04:51 +08:00
|
|
|
|
# 动态载入模块
|
|
|
|
|
_pluginModule = importlib.import_module(mod)
|
|
|
|
|
|
2018-09-20 14:06:56 +08:00
|
|
|
|
except:
|
2018-09-24 14:51:53 +08:00
|
|
|
|
import traceback
|
|
|
|
|
errmsg = traceback.format_exc()
|
|
|
|
|
|
|
|
|
|
QMessageBox.information(self.__mw,
|
|
|
|
|
"模块导入异常",
|
|
|
|
|
"%s,请在%s.py检查模块."%(errmsg,mod ))
|
2018-09-20 14:06:56 +08:00
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
self.pluginsInfo["StartModule"][mod]["active"] = False
|
2018-09-20 14:06:56 +08:00
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
return False
|
2018-09-24 14:51:53 +08:00
|
|
|
|
|
|
|
|
|
self.instantiation(mod, _pluginModule)
|
|
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
|
def instantiation(self , mod, moduleObj , NeedRplace = False):
|
|
|
|
|
"""
|
|
|
|
|
2.1.1 实例化类.
|
|
|
|
|
2.2.1.1
|
|
|
|
|
3.1.1
|
|
|
|
|
实例化新对象来替换旧对象.
|
|
|
|
|
"""
|
2018-09-20 14:06:56 +08:00
|
|
|
|
try:
|
2018-09-24 14:51:53 +08:00
|
|
|
|
className = getattr(moduleObj, "className")
|
|
|
|
|
pluginClass = getattr(moduleObj, className )
|
2018-09-20 14:06:56 +08:00
|
|
|
|
except:
|
2018-09-23 17:04:51 +08:00
|
|
|
|
self.pluginsInfo[mod]["active"] = False
|
|
|
|
|
QMessageBox.information(self.__mw,
|
|
|
|
|
"插件加载错误",
|
|
|
|
|
"请在%s.py全局指定className值." % mod)
|
2018-09-24 14:51:53 +08:00
|
|
|
|
return False
|
|
|
|
|
# 如果是替换对象需求 ,和初始化
|
|
|
|
|
|
2018-09-20 14:06:56 +08:00
|
|
|
|
# 实例化类
|
2018-09-23 17:04:51 +08:00
|
|
|
|
pluginObject = pluginClass(self.__mw)
|
2018-09-24 14:51:53 +08:00
|
|
|
|
pluginObject.setObjectName(mod)
|
2018-09-23 17:04:51 +08:00
|
|
|
|
|
2018-09-24 14:51:53 +08:00
|
|
|
|
self.pluginsInfo["StartModule"][mod]["active"] = True
|
|
|
|
|
self.pluginsInfo["StartModule"][mod]["pluginClass"] = pluginClass
|
|
|
|
|
self.pluginsInfo["StartModule"][mod]["parent"] = pluginObject.parent()
|
|
|
|
|
|
|
|
|
|
if not NeedRplace:
|
|
|
|
|
#TODO:其他接口
|
|
|
|
|
layout = pluginObject.getParentLayout()
|
|
|
|
|
layout.addWidget(pluginObject)
|
|
|
|
|
|
|
|
|
|
self.pluginsInfo["StartModule"][mod]["layout"] = layout
|
|
|
|
|
self.pluginsInfo["StartModule"][mod]["old"] = pluginObject
|
|
|
|
|
else:
|
|
|
|
|
self.pluginsInfo["StartModule"][mod]["new"] = pluginObject
|
|
|
|
|
return pluginObject
|
|
|
|
|
|
|
|
|
|
# 重载插件
|
2018-09-23 17:04:51 +08:00
|
|
|
|
def reload(self, mod):
|
2018-09-24 14:51:53 +08:00
|
|
|
|
"""
|
|
|
|
|
2.2 重载插件.
|
|
|
|
|
"""
|
2018-09-23 17:04:51 +08:00
|
|
|
|
if mod in sys.modules:
|
|
|
|
|
#TODO: 旧对象替换
|
2018-09-24 14:51:53 +08:00
|
|
|
|
print("reload")
|
2018-09-23 17:04:51 +08:00
|
|
|
|
importlib.reload(sys.modules[mod])
|
2018-09-24 14:51:53 +08:00
|
|
|
|
moduleObj = sys.modules[mod]
|
|
|
|
|
|
|
|
|
|
objInfo = self.findOldObj(mod, moduleObj , True)
|
|
|
|
|
oldObj, newObj, layout = objInfo["oldObj"],\
|
|
|
|
|
objInfo["newObj"],\
|
|
|
|
|
objInfo["layout"]
|
|
|
|
|
|
|
|
|
|
# 新对象替换旧对象 , 并把地址赋值给旧对象
|
|
|
|
|
layout.replaceWidget(oldObj, newObj )
|
|
|
|
|
self.pluginsInfo["StartModule"][mod]["old"] = newObj
|
|
|
|
|
|
|
|
|
|
sip.delete(oldObj)
|
2018-09-23 17:04:51 +08:00
|
|
|
|
else:
|
|
|
|
|
self.load(mod)
|
2018-09-24 14:51:53 +08:00
|
|
|
|
|
|
|
|
|
def findOldObj(self, mod, moduleObj=None, needRplace = False):
|
|
|
|
|
"""
|
|
|
|
|
3.1
|
|
|
|
|
2.2.1
|
|
|
|
|
找到需要删除或替换的对象.
|
|
|
|
|
"""
|
|
|
|
|
oldObj = self.pluginsInfo["StartModule"][mod]["old"]
|
|
|
|
|
parentWidget = self.pluginsInfo["StartModule"][mod]["parent"]
|
|
|
|
|
layout = self.pluginsInfo["StartModule"][mod]["layout"]
|
|
|
|
|
pluginClass = self.pluginsInfo["StartModule"][mod]["pluginClass"]
|
|
|
|
|
if needRplace:
|
|
|
|
|
if moduleObj==None:
|
|
|
|
|
QMessageBox.information(self.__mw,
|
|
|
|
|
"错误",
|
|
|
|
|
"请传入moduleObj值.")
|
|
|
|
|
else:
|
|
|
|
|
newObj = self.instantiation(mod, moduleObj, needRplace)
|
|
|
|
|
else:
|
|
|
|
|
newObj = None
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
"oldObj" :oldObj ,
|
|
|
|
|
"newObj" :newObj ,
|
|
|
|
|
"parentWidget":parentWidget,
|
|
|
|
|
"layout" :layout,
|
|
|
|
|
"pluginClass" :pluginClass,
|
|
|
|
|
}
|
|
|
|
|
|
2018-09-18 18:53:34 +08:00
|
|
|
|
# 卸载插件
|
2018-09-23 17:04:51 +08:00
|
|
|
|
def unload(self, mod: "str"):
|
2018-09-24 14:51:53 +08:00
|
|
|
|
"""
|
|
|
|
|
3. 卸载插件 , 移除模块.
|
|
|
|
|
"""
|
2018-09-23 17:04:51 +08:00
|
|
|
|
if mod in sys.modules:
|
|
|
|
|
self.pluginsInfo["StartModule"][mod]["active"] = False
|
2018-09-24 14:51:53 +08:00
|
|
|
|
#删除对象
|
|
|
|
|
objInfo = self.findOldObj(mod)
|
|
|
|
|
oldObj = objInfo["oldObj"]
|
|
|
|
|
|
|
|
|
|
sip.delete(oldObj)
|
2018-09-23 17:04:51 +08:00
|
|
|
|
|
2018-09-24 14:51:53 +08:00
|
|
|
|
self.pluginsInfo["StartModule"][mod]["old"] = None
|
|
|
|
|
sys.modules.pop(mod)
|
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
return True
|
2018-09-24 14:51:53 +08:00
|
|
|
|
|
2018-09-23 17:04:51 +08:00
|
|
|
|
# 卸载所有插件
|
2018-09-20 18:15:34 +08:00
|
|
|
|
def unloadAll(self):
|
|
|
|
|
pass
|
2018-09-23 17:04:51 +08:00
|
|
|
|
|
|
|
|
|
def PluginToInterFace(self):
|
|
|
|
|
pass
|