2018-09-18 18:53:34 +08:00
|
|
|
# -*- coding: utf-8 -*-
|
|
|
|
|
2018-09-20 14:06:56 +08:00
|
|
|
import os , time , imp
|
|
|
|
from importlib.machinery import SourceFileLoader
|
2018-09-18 18:53:34 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from PyQt5 import QtGui, QtWidgets, QtCore
|
|
|
|
from PyQt5.QtCore import *
|
|
|
|
from PyQt5.QtGui import *
|
|
|
|
from PyQt5.QtWidgets import *
|
|
|
|
|
|
|
|
from PluginManager import PluginStore
|
|
|
|
|
|
|
|
from Tools.pmf_myjson import *
|
|
|
|
|
2018-09-20 14:06:56 +08:00
|
|
|
|
2018-09-18 18:53:34 +08:00
|
|
|
class PluginManager(QObject):
|
|
|
|
|
|
|
|
def __init__(self, parent = None , *args, **kwargs):
|
|
|
|
super(PluginManager, self).__init__(parent , *args, **kwargs)
|
|
|
|
self.__mw = parent
|
|
|
|
self.__initUI()
|
|
|
|
|
|
|
|
self.pluginDirs = {"pluginPath": os.path.join("./", "Plugins"),}
|
2018-09-20 14:06:56 +08:00
|
|
|
self.existPlugin = {}
|
2018-09-18 18:53:34 +08:00
|
|
|
self.header = ["PlugName","Allow" , "CreateTime", "ModifyTime"]
|
|
|
|
|
|
|
|
# print("pluginDirs:", os.path.abspath(self.pluginDirs['pluginPath']))
|
2018-09-20 14:06:56 +08:00
|
|
|
|
|
|
|
# 获取插件模块名 及 路径
|
|
|
|
self.pluginsModule = self.getPluginModules(
|
|
|
|
self.pluginDirs['pluginPath'])
|
|
|
|
|
|
|
|
# print(self.pluginsModule)
|
|
|
|
#载入模块
|
|
|
|
self.loadAll()
|
|
|
|
|
|
|
|
# 文件监听器
|
|
|
|
self.watcher = QFileSystemWatcher(["./Plugins"],
|
|
|
|
directoryChanged = self.m_directoryChanged )
|
2018-09-18 18:53:34 +08:00
|
|
|
|
2018-09-20 14:06:56 +08:00
|
|
|
def m_directoryChanged(self):
|
|
|
|
self.pluginsModule = self.getPluginModules(
|
|
|
|
self.pluginDirs['pluginPath'])
|
|
|
|
|
2018-09-18 18:53:34 +08:00
|
|
|
def __initUI(self):
|
|
|
|
if self.__mw.findChild(QMenuBar, "menuBar"):
|
|
|
|
|
|
|
|
self.__mw.menuPlugin = QAction("Plugin", self.__mw.menuBar,
|
|
|
|
triggered = self.__createPluginStoreDialog)
|
|
|
|
self.__mw.menuBar.addAction(self.__mw.menuPlugin)
|
|
|
|
|
|
|
|
else:
|
|
|
|
QMessageBox.information(self.__mw, "", "主窗体没有菜单栏, 请先创建.")
|
|
|
|
|
|
|
|
def __createPluginStoreDialog(self):
|
2018-09-20 14:06:56 +08:00
|
|
|
"""
|
|
|
|
显示插件加载情况的 窗体.
|
|
|
|
"""
|
|
|
|
dia = PluginStore.PluginStore(self, self.__mw)
|
2018-09-18 18:53:34 +08:00
|
|
|
|
|
|
|
dia.exec_()
|
|
|
|
|
|
|
|
def getPluginModules(self, pluginPath:"./Plugins")->"module list":
|
|
|
|
"""
|
|
|
|
Public method to get a list of plugin modules.
|
|
|
|
"""
|
|
|
|
try:
|
|
|
|
existPlugin = mfunc_readJson(setting_flie)
|
|
|
|
except:
|
|
|
|
existPlugin=[]
|
|
|
|
|
2018-09-20 14:06:56 +08:00
|
|
|
pluginFiles = {}
|
2018-09-18 18:53:34 +08:00
|
|
|
|
|
|
|
for f in os.listdir(pluginPath):
|
|
|
|
# 插件名称的有效性检查
|
|
|
|
if f.endswith(".py") and f.startswith("Plugin"):
|
|
|
|
# 去掉后缀 , 加入模块
|
|
|
|
module = f[:-3]
|
2018-09-20 14:06:56 +08:00
|
|
|
|
|
|
|
fullPath = os.path.join( pluginPath , f)
|
|
|
|
pluginFiles[module] = {"path":fullPath}
|
|
|
|
|
2018-09-18 18:53:34 +08:00
|
|
|
# 判断是否存在配置信息中
|
|
|
|
if module not in existPlugin:
|
2018-09-20 14:06:56 +08:00
|
|
|
|
2018-09-18 18:53:34 +08:00
|
|
|
# 插件创建时间
|
2018-09-20 14:06:56 +08:00
|
|
|
_ctime = time.localtime(os.stat(fullPath).st_ctime)
|
2018-09-18 18:53:34 +08:00
|
|
|
ctime = time.strftime("%Y-%m-%d-%H:%M:%S",_ctime)
|
|
|
|
# 插件修改时间
|
2018-09-20 14:06:56 +08:00
|
|
|
_mtime = time.localtime(os.stat(fullPath).st_mtime)
|
2018-09-18 18:53:34 +08:00
|
|
|
mtime = time.strftime("%Y-%m-%d-%H:%M:%S",_mtime)
|
2018-09-20 14:06:56 +08:00
|
|
|
|
2018-09-18 18:53:34 +08:00
|
|
|
# 写入配置
|
|
|
|
mfunc_writeJson( module ,
|
|
|
|
{
|
|
|
|
self.header[1]: True, #allow
|
|
|
|
self.header[2]: ctime,#cteateTime
|
|
|
|
self.header[3]: mtime,#modifyTime
|
|
|
|
} ,
|
|
|
|
self = self)
|
|
|
|
|
|
|
|
# 添加完重新加载一遍看是否有插件删除
|
|
|
|
self.delJson(pluginFiles)
|
|
|
|
|
|
|
|
return pluginFiles
|
|
|
|
|
2018-09-20 14:06:56 +08:00
|
|
|
def delJson(self , pluginFiles)->"json":
|
|
|
|
"""
|
|
|
|
删除插件 的json配置.
|
|
|
|
"""
|
|
|
|
# 获取最终json配置
|
2018-09-18 18:53:34 +08:00
|
|
|
self.existPlugin = mfunc_readJson(setting_flie)
|
|
|
|
|
|
|
|
if len(self.existPlugin)>len(pluginFiles):
|
|
|
|
with open( setting_flie ,'a+' , encoding='utf-8') as f:
|
|
|
|
# 被删除的插件集合
|
|
|
|
delPlugin = set(self.existPlugin)-set(pluginFiles)
|
|
|
|
for item in delPlugin:
|
|
|
|
self.existPlugin.pop(item)
|
2018-09-20 14:06:56 +08:00
|
|
|
# 写入配置
|
2018-09-18 18:53:34 +08:00
|
|
|
mfunc_afterDelJson(f, self.existPlugin)
|
|
|
|
|
|
|
|
# 加载所有插件
|
|
|
|
def loadAll(self):
|
2018-09-20 14:06:56 +08:00
|
|
|
for mod in self.existPlugin:
|
|
|
|
if self.existPlugin[mod]["Allow"]:
|
|
|
|
try:
|
|
|
|
self.load(mod)
|
|
|
|
except:
|
|
|
|
continue
|
|
|
|
|
2018-09-18 18:53:34 +08:00
|
|
|
# 加载插件
|
2018-09-20 14:06:56 +08:00
|
|
|
def load(self , mod:"str"):
|
|
|
|
|
|
|
|
try:
|
|
|
|
print(self.pluginsModule[mod]["path"])
|
|
|
|
# python内置函数, 把.py 当做模块载入
|
|
|
|
_pluginModule = SourceFileLoader( mod ,
|
|
|
|
self.pluginsModule[mod]["path"]).load_module()
|
|
|
|
# _pluginModule=imp.load_source(mod, self.pluginsModule[mod]["path"])
|
|
|
|
except:
|
|
|
|
# QMessageBox.information(self.__mw,
|
|
|
|
# "模块导入异常",
|
|
|
|
# "请在%s.py检查模块."%mod)
|
|
|
|
|
|
|
|
self.pluginsModule[mod]["active"] = False
|
|
|
|
return
|
|
|
|
|
|
|
|
try:
|
|
|
|
className = getattr(_pluginModule, "className")
|
|
|
|
pluginClass = getattr(_pluginModule, className )
|
|
|
|
except:
|
|
|
|
self.pluginsModule[mod]["active"] = False
|
|
|
|
QMessageBox.information(self.__mw,
|
|
|
|
"插件加载错误",
|
|
|
|
"请在%s.py全局指定className值."%mod)
|
|
|
|
return
|
|
|
|
# 实例化类
|
|
|
|
pluginObject = pluginClass()
|
|
|
|
pluginObject.setObjectName(className)
|
|
|
|
|
|
|
|
self.__mw.verticalLayout.addWidget(pluginObject)
|
|
|
|
self.pluginsModule[mod]["active"] = True
|
|
|
|
|
|
|
|
return True
|
2018-09-18 18:53:34 +08:00
|
|
|
# 卸载所有插件
|
|
|
|
def unloadAll(self):
|
|
|
|
pass
|
|
|
|
|
|
|
|
# 卸载插件
|
2018-09-20 14:06:56 +08:00
|
|
|
def unload(self, mod:"str"):
|
|
|
|
# self.__mw.findchild()
|
|
|
|
print(sys.modules[mod], mod)
|
|
|
|
print(self.__mw.findChild(QWidget, mod))
|
|
|
|
#TODO:
|
|
|
|
|
|
|
|
return True
|
|
|
|
|
2018-09-18 18:53:34 +08:00
|
|
|
|
|
|
|
|