refactor: 重构插件系统

This commit is contained in:
RockChinQ
2024-01-29 21:22:27 +08:00
parent b730f17eb6
commit 6cc4688660
53 changed files with 1307 additions and 1993 deletions

View File

@@ -1,17 +1,20 @@
from __future__ import annotations
from .. import apigroup
from ... import context
from ....core import app
class V2MainDataAPI(apigroup.APIGroup):
"""主程序相关 数据API"""
def __init__(self, prefix: str):
super().__init__(prefix+"/main")
ap: app.Application
def __init__(self, prefix: str, ap: app.Application):
self.ap = ap
super().__init__(prefix+"/usage")
def do(self, *args, **kwargs):
config = context.get_config_manager().data
config = self.ap.cfg_mgr.data
if not config['report_usage']:
return None
return super().do(*args, **kwargs)

View File

@@ -1,17 +1,20 @@
from __future__ import annotations
from ....core import app
from .. import apigroup
from ... import context
class V2PluginDataAPI(apigroup.APIGroup):
"""插件数据相关 API"""
def __init__(self, prefix: str):
super().__init__(prefix+"/plugin")
ap: app.Application
def __init__(self, prefix: str, ap: app.Application):
self.ap = ap
super().__init__(prefix+"/usage")
def do(self, *args, **kwargs):
config = context.get_config_manager().data
config = self.ap.cfg_mgr.data
if not config['report_usage']:
return None
return super().do(*args, **kwargs)

View File

@@ -1,17 +1,20 @@
from __future__ import annotations
from .. import apigroup
from ... import context
from ....core import app
class V2UsageDataAPI(apigroup.APIGroup):
"""使用量数据相关 API"""
def __init__(self, prefix: str):
ap: app.Application
def __init__(self, prefix: str, ap: app.Application):
self.ap = ap
super().__init__(prefix+"/usage")
def do(self, *args, **kwargs):
config = context.get_config_manager().data
config = self.ap.cfg_mgr.data
if not config['report_usage']:
return None
return super().do(*args, **kwargs)

View File

@@ -6,7 +6,7 @@ from . import apigroup
from .groups import main
from .groups import usage
from .groups import plugin
from ...utils import context
from ...core import app
BACKEND_URL = "https://api.qchatgpt.rockchin.top/api/v2"
@@ -23,7 +23,7 @@ class V2CenterAPI:
plugin: plugin.V2PluginDataAPI = None
"""插件 API 组"""
def __init__(self, basic_info: dict = None, runtime_info: dict = None):
def __init__(self, ap: app.Application, basic_info: dict = None, runtime_info: dict = None):
"""初始化"""
logging.debug("basic_info: %s, runtime_info: %s", basic_info, runtime_info)
@@ -31,8 +31,7 @@ class V2CenterAPI:
apigroup.APIGroup._basic_info = basic_info
apigroup.APIGroup._runtime_info = runtime_info
self.main = main.V2MainDataAPI(BACKEND_URL)
self.usage = usage.V2UsageDataAPI(BACKEND_URL)
self.plugin = plugin.V2PluginDataAPI(BACKEND_URL)
context.set_center_v2_api(self)
self.main = main.V2MainDataAPI(BACKEND_URL, ap)
self.usage = usage.V2UsageDataAPI(BACKEND_URL, ap)
self.plugin = plugin.V2PluginDataAPI(BACKEND_URL, ap)

View File

@@ -1,11 +0,0 @@
from . import context
def wrapper_proxies() -> dict:
"""获取代理"""
config = context.get_config_manager().data
return {
"http": config['openai_config']['proxy'],
"https": config['openai_config']['proxy']
} if 'proxy' in config['openai_config'] and (config['openai_config']['proxy'] is not None) else None

View File

@@ -1,27 +1,27 @@
from pip._internal import main as pipmain
from . import log
# from . import log
def install(package):
pipmain(['install', package])
log.reset_logging()
# log.reset_logging()
def install_upgrade(package):
pipmain(['install', '--upgrade', package, "-i", "https://pypi.tuna.tsinghua.edu.cn/simple",
"--trusted-host", "pypi.tuna.tsinghua.edu.cn"])
log.reset_logging()
# log.reset_logging()
def run_pip(params: list):
pipmain(params)
log.reset_logging()
# log.reset_logging()
def install_requirements(file):
pipmain(['install', '-r', file, "-i", "https://pypi.tuna.tsinghua.edu.cn/simple",
"--trusted-host", "pypi.tuna.tsinghua.edu.cn"])
log.reset_logging()
# log.reset_logging()
def ensure_dulwich():

30
pkg/utils/proxy.py Normal file
View File

@@ -0,0 +1,30 @@
from __future__ import annotations
from ..core import app
class ProxyManager:
ap: app.Application
forward_proxies: dict[str, str]
def __init__(self, ap: app.Application):
self.ap = ap
self.forward_proxies = {}
async def initialize(self):
config = self.ap.cfg_mgr.data
return (
{
"http": config["openai_config"]["proxy"],
"https": config["openai_config"]["proxy"],
}
if "proxy" in config["openai_config"]
and (config["openai_config"]["proxy"] is not None)
else None
)
def get_forward_proxies(self) -> str:
return self.forward_proxies

View File

@@ -8,21 +8,6 @@ import time
import requests
from . import constants
from . import network
from . import context
def check_dulwich_closure():
try:
import pkg.utils.pkgmgr
pkg.utils.pkgmgr.ensure_dulwich()
except:
pass
try:
import dulwich
except ModuleNotFoundError:
raise Exception("dulwich模块未安装,请查看 https://github.com/RockChinQ/QChatGPT/issues/77")
def is_newer(new_tag: str, old_tag: str):
@@ -47,28 +32,6 @@ def is_newer(new_tag: str, old_tag: str):
return new_tag != old_tag
def get_release_list() -> list:
"""获取发行列表"""
rls_list_resp = requests.get(
url="https://api.github.com/repos/RockChinQ/QChatGPT/releases",
proxies=network.wrapper_proxies()
)
rls_list = rls_list_resp.json()
return rls_list
def get_current_tag() -> str:
"""获取当前tag"""
current_tag = constants.semantic_version
if os.path.exists("current_tag"):
with open("current_tag", "r") as f:
current_tag = f.read()
return current_tag
def compare_version_str(v0: str, v1: str) -> int:
"""比较两个版本号"""
@@ -209,79 +172,3 @@ def update_all(cli: bool = False) -> bool:
else:
print("已更新到最新版本: {}\n更新日志:\n{}\n完整的更新日志请前往 https://github.com/RockChinQ/QChatGPT/releases 查看。请手动重启程序以使用新版本。".format(current_tag, "\n".join(rls_notes[:-1])))
return True
def is_repo(path: str) -> bool:
"""检查是否是git仓库"""
check_dulwich_closure()
from dulwich import porcelain
try:
porcelain.open_repo(path)
return True
except:
return False
def get_remote_url(repo_path: str) -> str:
"""获取远程仓库地址"""
check_dulwich_closure()
from dulwich import porcelain
repo = porcelain.open_repo(repo_path)
return str(porcelain.get_remote_repo(repo, "origin")[1])
def get_current_version_info() -> str:
"""获取当前版本信息"""
rls_list = get_release_list()
current_tag = get_current_tag()
for rls in rls_list:
if rls['tag_name'] == current_tag:
return rls['name'] + "\n" + rls['body']
return "未知版本"
def is_new_version_available() -> bool:
"""检查是否有新版本"""
# 从github获取release列表
rls_list = get_release_list()
if rls_list is None:
return False
# 获取当前版本
current_tag = get_current_tag()
# 检查是否有新版本
latest_tag_name = ""
for rls in rls_list:
if latest_tag_name == "":
latest_tag_name = rls['tag_name']
break
return is_newer(latest_tag_name, current_tag)
def get_rls_notes() -> list:
"""获取更新日志"""
# 从github获取release列表
rls_list = get_release_list()
if rls_list is None:
return None
# 获取当前版本
current_tag = get_current_tag()
# 检查是否有新版本
rls_notes = []
for rls in rls_list:
if rls['tag_name'] == current_tag:
break
rls_notes.append(rls['name'])
return rls_notes
if __name__ == "__main__":
update_all()

130
pkg/utils/version.py Normal file
View File

@@ -0,0 +1,130 @@
from __future__ import annotations
import os
import requests
from ..core import app
from . import constants
class VersionManager:
ap: app.Application
def __init__(
self,
ap: app.Application
):
self.ap = ap
async def initialize(
self
):
pass
def get_current_version(
self
) -> str:
current_tag = constants.semantic_version
if os.path.exists("current_tag"):
with open("current_tag", "r") as f:
current_tag = f.read()
return current_tag
async def get_current_version_info(
self
) -> str:
"""获取当前版本信息"""
rls_list = await self.get_release_list()
current_tag = self.get_current_version()
for rls in rls_list:
if rls['tag_name'] == current_tag:
return rls['name'] + "\n" + rls['body']
return "未知版本"
async def get_release_list(self) -> list:
"""获取发行列表"""
rls_list_resp = requests.get(
url="https://api.github.com/repos/RockChinQ/QChatGPT/releases",
proxies=self.ap.proxy_mgr.get_forward_proxies()
)
rls_list = rls_list_resp.json()
return rls_list
async def update_all(self):
pass
async def is_new_version_available(self) -> bool:
"""检查是否有新版本"""
# 从github获取release列表
rls_list = await self.get_release_list()
if rls_list is None:
return False
# 获取当前版本
current_tag = self.get_current_version()
# 检查是否有新版本
latest_tag_name = ""
for rls in rls_list:
if latest_tag_name == "":
latest_tag_name = rls['tag_name']
break
return self.is_newer(latest_tag_name, current_tag)
def is_newer(self, new_tag: str, old_tag: str):
"""判断版本是否更新,忽略第四位版本和第一位版本"""
if new_tag == old_tag:
return False
new_tag = new_tag.split(".")
old_tag = old_tag.split(".")
# 判断主版本是否相同
if new_tag[0] != old_tag[0]:
return False
if len(new_tag) < 4:
return True
# 合成前三段,判断是否相同
new_tag = ".".join(new_tag[:3])
old_tag = ".".join(old_tag[:3])
return new_tag != old_tag
def compare_version_str(v0: str, v1: str) -> int:
"""比较两个版本号"""
# 删除版本号前的v
if v0.startswith("v"):
v0 = v0[1:]
if v1.startswith("v"):
v1 = v1[1:]
v0:list = v0.split(".")
v1:list = v1.split(".")
# 如果两个版本号节数不同把短的后面用0补齐
if len(v0) < len(v1):
v0.extend(["0"]*(len(v1)-len(v0)))
elif len(v0) > len(v1):
v1.extend(["0"]*(len(v0)-len(v1)))
# 从高位向低位比较
for i in range(len(v0)):
if int(v0[i]) > int(v1[i]):
return 1
elif int(v0[i]) < int(v1[i]):
return -1
return 0