mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-07-20 21:57:14 +08:00
fix: bug when reinstall plugin
This commit is contained in:
@@ -41,7 +41,7 @@ class WechatMPChannel(ChatChannel):
|
|||||||
urls = (
|
urls = (
|
||||||
'/wx', 'SubsribeAccountQuery',
|
'/wx', 'SubsribeAccountQuery',
|
||||||
)
|
)
|
||||||
app = web.application(urls, globals())
|
app = web.application(urls, globals(), autoreload=False)
|
||||||
port = conf().get('wechatmp_port', 8080)
|
port = conf().get('wechatmp_port', 8080)
|
||||||
web.httpserver.runsimple(app.wsgifunc(), ('0.0.0.0', port))
|
web.httpserver.runsimple(app.wsgifunc(), ('0.0.0.0', port))
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import time
|
||||||
import pip
|
import pip
|
||||||
|
|
||||||
def install(package):
|
def install(package):
|
||||||
@@ -7,9 +8,20 @@ def install_requirements(file):
|
|||||||
pip.main(['install', '-r', file, "--upgrade"])
|
pip.main(['install', '-r', file, "--upgrade"])
|
||||||
|
|
||||||
def check_dulwich():
|
def check_dulwich():
|
||||||
|
needwait = False
|
||||||
|
for i in range(2):
|
||||||
|
if needwait:
|
||||||
|
time.sleep(3)
|
||||||
|
needwait = False
|
||||||
|
try:
|
||||||
|
import dulwich
|
||||||
|
return
|
||||||
|
except ImportError:
|
||||||
|
try:
|
||||||
|
install('dulwich')
|
||||||
|
except:
|
||||||
|
needwait = True
|
||||||
try:
|
try:
|
||||||
import dulwich
|
import dulwich
|
||||||
return
|
|
||||||
except ImportError:
|
except ImportError:
|
||||||
install('dulwich')
|
raise ImportError("Unable to import dulwich")
|
||||||
raise ImportError("Unable to import dulwich")
|
|
||||||
@@ -310,11 +310,7 @@ class Godcmd(Plugin):
|
|||||||
if len(args) != 1:
|
if len(args) != 1:
|
||||||
ok, result = False, "请提供插件名"
|
ok, result = False, "请提供插件名"
|
||||||
else:
|
else:
|
||||||
ok = PluginManager().enable_plugin(args[0])
|
ok, result = PluginManager().enable_plugin(args[0])
|
||||||
if ok:
|
|
||||||
result = "插件已启用"
|
|
||||||
else:
|
|
||||||
result = "插件不存在"
|
|
||||||
elif cmd == "disablep":
|
elif cmd == "disablep":
|
||||||
if len(args) != 1:
|
if len(args) != 1:
|
||||||
ok, result = False, "请提供插件名"
|
ok, result = False, "请提供插件名"
|
||||||
|
|||||||
@@ -1,8 +1,10 @@
|
|||||||
# encoding:utf-8
|
# encoding:utf-8
|
||||||
|
|
||||||
import importlib
|
import importlib
|
||||||
|
import importlib.util
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
from common.singleton import singleton
|
from common.singleton import singleton
|
||||||
from common.sorted_dict import SortedDict
|
from common.sorted_dict import SortedDict
|
||||||
from .event import *
|
from .event import *
|
||||||
@@ -18,6 +20,7 @@ class PluginManager:
|
|||||||
self.instances = {}
|
self.instances = {}
|
||||||
self.pconf = {}
|
self.pconf = {}
|
||||||
self.current_plugin_path = None
|
self.current_plugin_path = None
|
||||||
|
self.loaded = {}
|
||||||
|
|
||||||
def register(self, name: str, desire_priority: int = 0, **kwargs):
|
def register(self, name: str, desire_priority: int = 0, **kwargs):
|
||||||
def wrapper(plugincls):
|
def wrapper(plugincls):
|
||||||
@@ -30,9 +33,10 @@ class PluginManager:
|
|||||||
plugincls.namecn = kwargs.get('namecn') if kwargs.get('namecn') != None else name
|
plugincls.namecn = kwargs.get('namecn') if kwargs.get('namecn') != None else name
|
||||||
plugincls.hidden = kwargs.get('hidden') if kwargs.get('hidden') != None else False
|
plugincls.hidden = kwargs.get('hidden') if kwargs.get('hidden') != None else False
|
||||||
plugincls.enabled = True
|
plugincls.enabled = True
|
||||||
|
if self.current_plugin_path == None:
|
||||||
|
raise Exception("Plugin path not set")
|
||||||
self.plugins[name.upper()] = plugincls
|
self.plugins[name.upper()] = plugincls
|
||||||
logger.info("Plugin %s_v%s registered, path=%s" % (name, plugincls.version, plugincls.path))
|
logger.info("Plugin %s_v%s registered, path=%s" % (name, plugincls.version, plugincls.path))
|
||||||
return plugincls
|
|
||||||
return wrapper
|
return wrapper
|
||||||
|
|
||||||
def save_config(self):
|
def save_config(self):
|
||||||
@@ -58,6 +62,7 @@ class PluginManager:
|
|||||||
def scan_plugins(self):
|
def scan_plugins(self):
|
||||||
logger.info("Scaning plugins ...")
|
logger.info("Scaning plugins ...")
|
||||||
plugins_dir = "./plugins"
|
plugins_dir = "./plugins"
|
||||||
|
raws = [self.plugins[name] for name in self.plugins]
|
||||||
for plugin_name in os.listdir(plugins_dir):
|
for plugin_name in os.listdir(plugins_dir):
|
||||||
plugin_path = os.path.join(plugins_dir, plugin_name)
|
plugin_path = os.path.join(plugins_dir, plugin_name)
|
||||||
if os.path.isdir(plugin_path):
|
if os.path.isdir(plugin_path):
|
||||||
@@ -68,17 +73,27 @@ class PluginManager:
|
|||||||
import_path = "plugins.{}".format(plugin_name)
|
import_path = "plugins.{}".format(plugin_name)
|
||||||
try:
|
try:
|
||||||
self.current_plugin_path = plugin_path
|
self.current_plugin_path = plugin_path
|
||||||
main_module = importlib.import_module(import_path)
|
if plugin_path in self.loaded:
|
||||||
|
if self.loaded[plugin_path] == None:
|
||||||
|
logger.info("reload module %s" % plugin_name)
|
||||||
|
self.loaded[plugin_path] = importlib.reload(sys.modules[import_path])
|
||||||
|
dependent_module_names = [name for name in sys.modules.keys() if name.startswith( import_path+ '.')]
|
||||||
|
for name in dependent_module_names:
|
||||||
|
logger.info("reload module %s" % name)
|
||||||
|
importlib.reload(sys.modules[name])
|
||||||
|
else:
|
||||||
|
self.loaded[plugin_path] = importlib.import_module(import_path)
|
||||||
|
self.current_plugin_path = None
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warn("Failed to import plugin %s: %s" % (plugin_name, e))
|
logger.exception("Failed to import plugin %s: %s" % (plugin_name, e))
|
||||||
continue
|
continue
|
||||||
pconf = self.pconf
|
pconf = self.pconf
|
||||||
new_plugins = []
|
news = [self.plugins[name] for name in self.plugins]
|
||||||
|
new_plugins = list(set(news) - set(raws))
|
||||||
modified = False
|
modified = False
|
||||||
for name, plugincls in self.plugins.items():
|
for name, plugincls in self.plugins.items():
|
||||||
rawname = plugincls.name
|
rawname = plugincls.name
|
||||||
if rawname not in pconf["plugins"]:
|
if rawname not in pconf["plugins"]:
|
||||||
new_plugins.append(plugincls)
|
|
||||||
modified = True
|
modified = True
|
||||||
logger.info("Plugin %s not found in pconfig, adding to pconfig..." % name)
|
logger.info("Plugin %s not found in pconfig, adding to pconfig..." % name)
|
||||||
pconf["plugins"][rawname] = {"enabled": plugincls.enabled, "priority": plugincls.priority}
|
pconf["plugins"][rawname] = {"enabled": plugincls.enabled, "priority": plugincls.priority}
|
||||||
@@ -95,14 +110,16 @@ class PluginManager:
|
|||||||
self.listening_plugins[event].sort(key=lambda name: self.plugins[name].priority, reverse=True)
|
self.listening_plugins[event].sort(key=lambda name: self.plugins[name].priority, reverse=True)
|
||||||
|
|
||||||
def activate_plugins(self): # 生成新开启的插件实例
|
def activate_plugins(self): # 生成新开启的插件实例
|
||||||
|
failed_plugins = []
|
||||||
for name, plugincls in self.plugins.items():
|
for name, plugincls in self.plugins.items():
|
||||||
if plugincls.enabled:
|
if plugincls.enabled:
|
||||||
if name not in self.instances:
|
if name not in self.instances:
|
||||||
try:
|
try:
|
||||||
instance = plugincls()
|
instance = plugincls()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warn("Failed to create init %s, diabled. %s" % (name, e))
|
logger.warn("Failed to init %s, diabled. %s" % (name, e))
|
||||||
self.disable_plugin(name)
|
self.disable_plugin(name)
|
||||||
|
failed_plugins.append(name)
|
||||||
continue
|
continue
|
||||||
self.instances[name] = instance
|
self.instances[name] = instance
|
||||||
for event in instance.handlers:
|
for event in instance.handlers:
|
||||||
@@ -110,6 +127,7 @@ class PluginManager:
|
|||||||
self.listening_plugins[event] = []
|
self.listening_plugins[event] = []
|
||||||
self.listening_plugins[event].append(name)
|
self.listening_plugins[event].append(name)
|
||||||
self.refresh_order()
|
self.refresh_order()
|
||||||
|
return failed_plugins
|
||||||
|
|
||||||
def reload_plugin(self, name:str):
|
def reload_plugin(self, name:str):
|
||||||
name = name.upper()
|
name = name.upper()
|
||||||
@@ -159,15 +177,17 @@ class PluginManager:
|
|||||||
def enable_plugin(self, name:str):
|
def enable_plugin(self, name:str):
|
||||||
name = name.upper()
|
name = name.upper()
|
||||||
if name not in self.plugins:
|
if name not in self.plugins:
|
||||||
return False
|
return False, "插件不存在"
|
||||||
if not self.plugins[name].enabled :
|
if not self.plugins[name].enabled :
|
||||||
self.plugins[name].enabled = True
|
self.plugins[name].enabled = True
|
||||||
rawname = self.plugins[name].name
|
rawname = self.plugins[name].name
|
||||||
self.pconf["plugins"][rawname]["enabled"] = True
|
self.pconf["plugins"][rawname]["enabled"] = True
|
||||||
self.save_config()
|
self.save_config()
|
||||||
self.activate_plugins()
|
failed_plugins = self.activate_plugins()
|
||||||
return True
|
if name in failed_plugins:
|
||||||
return True
|
return False, "插件开启失败"
|
||||||
|
return True, "插件已开启"
|
||||||
|
return True, "插件已开启"
|
||||||
|
|
||||||
def disable_plugin(self, name:str):
|
def disable_plugin(self, name:str):
|
||||||
name = name.upper()
|
name = name.upper()
|
||||||
@@ -206,12 +226,12 @@ class PluginManager:
|
|||||||
repo = source["repo"][repo]["url"]
|
repo = source["repo"][repo]["url"]
|
||||||
match = re.match(r"^(https?:\/\/|git@)([^\/:]+)[\/:]([^\/:]+)\/(.+).git$", repo)
|
match = re.match(r"^(https?:\/\/|git@)([^\/:]+)[\/:]([^\/:]+)\/(.+).git$", repo)
|
||||||
if not match:
|
if not match:
|
||||||
return False, "source中的仓库地址不合法"
|
return False, "安装插件失败,source中的仓库地址不合法"
|
||||||
else:
|
else:
|
||||||
return False, "仓库地址不合法"
|
return False, "安装插件失败,仓库地址不合法"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Failed to install plugin, {}".format(e))
|
logger.error("Failed to install plugin, {}".format(e))
|
||||||
return False, "安装插件失败"
|
return False, "安装插件失败,请检查仓库地址是否正确"
|
||||||
dirname = os.path.join("./plugins",match.group(4))
|
dirname = os.path.join("./plugins",match.group(4))
|
||||||
try:
|
try:
|
||||||
repo = porcelain.clone(repo, dirname, checkout=True)
|
repo = porcelain.clone(repo, dirname, checkout=True)
|
||||||
@@ -221,7 +241,7 @@ class PluginManager:
|
|||||||
return True, "安装插件成功,请扫描插件或重启程序"
|
return True, "安装插件成功,请扫描插件或重启程序"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Failed to install plugin, {}".format(e))
|
logger.error("Failed to install plugin, {}".format(e))
|
||||||
return False, "安装插件失败"
|
return False, "安装插件失败,"+str(e)
|
||||||
|
|
||||||
def uninstall_plugin(self, name:str):
|
def uninstall_plugin(self, name:str):
|
||||||
name = name.upper()
|
name = name.upper()
|
||||||
@@ -233,8 +253,12 @@ class PluginManager:
|
|||||||
try:
|
try:
|
||||||
import shutil
|
import shutil
|
||||||
shutil.rmtree(dirname)
|
shutil.rmtree(dirname)
|
||||||
|
rawname = self.plugins[name].name
|
||||||
del self.plugins[name]
|
del self.plugins[name]
|
||||||
|
del self.pconf["plugins"][rawname]
|
||||||
|
self.loaded[dirname] = None
|
||||||
|
self.save_config()
|
||||||
return True, "卸载插件成功"
|
return True, "卸载插件成功"
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error("Failed to uninstall plugin, {}".format(e))
|
logger.error("Failed to uninstall plugin, {}".format(e))
|
||||||
return False, "卸载插件失败"
|
return False, "卸载插件失败,请手动删除文件夹完成卸载,"+str(e)
|
||||||
Reference in New Issue
Block a user