mirror of
https://github.com/Genshin-bots/gsuid_core.git
synced 2025-05-08 21:15:46 +08:00
✨ 网页控制台新增插件管理
This commit is contained in:
parent
54bf5df9c1
commit
b26fe93a19
8
.gitignore
vendored
8
.gitignore
vendored
@ -665,10 +665,8 @@ FodyWeavers.xsd
|
||||
config.json
|
||||
res_data
|
||||
GsData.db
|
||||
GenshinUID
|
||||
StarRailUID
|
||||
data
|
||||
plugins/*
|
||||
!plugins/core_command
|
||||
!plugins/gs_test.py
|
||||
gsuid_core/plugins/*
|
||||
!gsuid_core/plugins/core_command
|
||||
!gsuid_core/plugins/gs_test.py
|
||||
logs
|
||||
|
@ -23,6 +23,14 @@ from gsuid_core.utils.plugins_config.models import ( # noqa: E402
|
||||
from gsuid_core.utils.plugins_config.gs_config import ( # noqa: E402
|
||||
all_config_list,
|
||||
)
|
||||
from gsuid_core.utils.plugins_update._plugins import ( # noqa: E402
|
||||
check_status,
|
||||
check_plugins,
|
||||
install_plugin,
|
||||
update_plugins,
|
||||
check_can_update,
|
||||
get_plugins_list,
|
||||
)
|
||||
|
||||
app = FastAPI()
|
||||
HOST = core_config.get_config('HOST')
|
||||
@ -95,6 +103,47 @@ def main():
|
||||
value = data[name]
|
||||
all_config_list[config_name].set_config(name, value)
|
||||
|
||||
@app.get('/genshinuid/api/getPlugins')
|
||||
@site.auth.requires('admin')
|
||||
async def _get_plugins(request: Request):
|
||||
tasks = []
|
||||
plugins_list = await get_plugins_list()
|
||||
for name in plugins_list:
|
||||
plugin = plugins_list[name]
|
||||
link = plugin['link']
|
||||
plugin_name = link.split('/')[-1]
|
||||
# git_path = f'{proxy_url}{link}.git'
|
||||
sample = {
|
||||
'label': plugin_name,
|
||||
'key': name,
|
||||
'status': check_status(plugin_name),
|
||||
'remark': plugin['info'],
|
||||
}
|
||||
tasks.append(sample)
|
||||
|
||||
return tasks
|
||||
|
||||
@app.post('/genshinuid/api/updatePlugins')
|
||||
@site.auth.requires('admin')
|
||||
async def _update_plugins(request: Request, data: Dict):
|
||||
repo = check_plugins(data['label'])
|
||||
if repo:
|
||||
if check_can_update(repo):
|
||||
try:
|
||||
update_plugins(data['label'])
|
||||
retcode = 0
|
||||
except: # noqa:E722
|
||||
retcode = -1
|
||||
else:
|
||||
retcode = 0
|
||||
else:
|
||||
try:
|
||||
retcode = await install_plugin(data['key'])
|
||||
retcode = 0
|
||||
except: # noqa:E722
|
||||
retcode = -1
|
||||
return {'status': retcode, 'msg': '', 'data': {}}
|
||||
|
||||
site.mount_app(app)
|
||||
|
||||
uvicorn.run(
|
||||
@ -102,23 +151,23 @@ def main():
|
||||
host=HOST,
|
||||
port=PORT,
|
||||
log_config={
|
||||
"version": 1,
|
||||
"disable_existing_loggers": False,
|
||||
"handlers": {
|
||||
"default": {
|
||||
"class": "gsuid_core.logger.LoguruHandler",
|
||||
'version': 1,
|
||||
'disable_existing_loggers': False,
|
||||
'handlers': {
|
||||
'default': {
|
||||
'class': 'gsuid_core.logger.LoguruHandler',
|
||||
},
|
||||
},
|
||||
"loggers": {
|
||||
"uvicorn.error": {"handlers": ["default"], "level": "INFO"},
|
||||
"uvicorn.access": {
|
||||
"handlers": ["default"],
|
||||
"level": "INFO",
|
||||
'loggers': {
|
||||
'uvicorn.error': {'handlers': ['default'], 'level': 'INFO'},
|
||||
'uvicorn.access': {
|
||||
'handlers': ['default'],
|
||||
'level': 'INFO',
|
||||
},
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
@ -1,8 +1,7 @@
|
||||
from gsuid_core.sv import SV
|
||||
from gsuid_core.bot import Bot
|
||||
from gsuid_core.models import Event
|
||||
|
||||
from ._plugins import (
|
||||
from gsuid_core.utils.plugins_update._plugins import (
|
||||
refresh_list,
|
||||
update_plugins,
|
||||
get_plugins_url,
|
||||
|
@ -231,6 +231,10 @@ async def _deal_ck(bot_id: str, mes: str, user_id: str) -> str:
|
||||
|
||||
if is_add_stoken:
|
||||
im_list.append(f'添加Stoken成功,stuid={account_id},stoken={stoken}')
|
||||
|
||||
if uid is None:
|
||||
uid = '0'
|
||||
|
||||
await sqla.insert_user_data(
|
||||
user_id, uid, sr_uid, account_cookie, app_cookie
|
||||
)
|
||||
|
@ -2,7 +2,7 @@ from typing import Dict, List, Union, Optional
|
||||
|
||||
import aiohttp
|
||||
from git.repo import Repo
|
||||
from git.exc import GitCommandError
|
||||
from git.exc import GitCommandError, InvalidGitRepositoryError
|
||||
|
||||
from gsuid_core.logger import logger
|
||||
|
||||
@ -27,6 +27,12 @@ async def refresh_list() -> List[str]:
|
||||
return refresh_list
|
||||
|
||||
|
||||
async def get_plugins_list() -> Dict[str, Dict[str, str]]:
|
||||
if not plugins_list:
|
||||
await refresh_list()
|
||||
return plugins_list
|
||||
|
||||
|
||||
async def get_plugins_url(name: str) -> Optional[Dict[str, str]]:
|
||||
if not plugins_list:
|
||||
await refresh_list()
|
||||
@ -50,9 +56,54 @@ def install_plugins(plugins: Dict[str, str]) -> str:
|
||||
if path.exists():
|
||||
return '该插件已经安装过了!'
|
||||
Repo.clone_from(git_path, path, single_branch=True, depth=1)
|
||||
logger.info(f'插件{plugin_name}安装成功!')
|
||||
return f'插件{plugin_name}安装成功!发送[gs重启]以应用!'
|
||||
|
||||
|
||||
async def install_plugin(plugin_name: str) -> int:
|
||||
url = await get_plugins_url(plugin_name)
|
||||
if url is None:
|
||||
return -1
|
||||
install_plugins(url)
|
||||
return 0
|
||||
|
||||
|
||||
def check_plugins(plugin_name: str) -> Optional[Repo]:
|
||||
path = PLUGINS_PATH / plugin_name
|
||||
if path.exists():
|
||||
try:
|
||||
repo = Repo(path)
|
||||
except InvalidGitRepositoryError:
|
||||
return None
|
||||
return repo
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def check_can_update(repo: Repo) -> bool:
|
||||
try:
|
||||
remote = repo.remote() # 获取远程仓库
|
||||
remote.fetch() # 从远程获取最新版本
|
||||
except GitCommandError as e:
|
||||
logger.error(f'发生Git命令错误{e}!')
|
||||
return False
|
||||
local_commit = repo.commit() # 获取本地最新提交
|
||||
remote_commit = remote.fetch()[0].commit # 获取远程最新提交
|
||||
if local_commit.hexsha == remote_commit.hexsha: # 比较本地和远程的提交哈希值
|
||||
return False
|
||||
return True
|
||||
|
||||
|
||||
def check_status(plugin_name: str) -> int:
|
||||
repo = check_plugins(plugin_name)
|
||||
if repo is None:
|
||||
return 3
|
||||
if check_can_update(repo):
|
||||
return 1
|
||||
else:
|
||||
return 4
|
||||
|
||||
|
||||
def update_plugins(
|
||||
plugin_name: str,
|
||||
level: int = 0,
|
||||
@ -66,10 +117,9 @@ def update_plugins(
|
||||
plugin_name = _name
|
||||
break
|
||||
|
||||
path = PLUGINS_PATH / plugin_name
|
||||
if not path.exists():
|
||||
repo = check_plugins(plugin_name)
|
||||
if not repo:
|
||||
return '更新失败, 不存在该插件!'
|
||||
repo = Repo(path) # type: ignore
|
||||
o = repo.remotes.origin
|
||||
|
||||
if level >= 2:
|
@ -7,4 +7,4 @@ plugins_lib = 'https://docs.gsuid.gbots.work/plugin_list.json'
|
||||
|
||||
proxy_url = 'https://ghproxy.com/'
|
||||
|
||||
PLUGINS_PATH = Path(__file__).parents[2]
|
||||
PLUGINS_PATH = Path(__file__).parents[2] / 'plugins'
|
20
gsuid_core/webconsole/create_task_panel.py
Normal file
20
gsuid_core/webconsole/create_task_panel.py
Normal file
@ -0,0 +1,20 @@
|
||||
def get_tasks_panel():
|
||||
return {
|
||||
'type': 'tasks',
|
||||
'name': 'tasks',
|
||||
'items': [{'label': '加载中, 请稍等...', 'key': 'wait', 'status': 2}],
|
||||
'id': 'u:571849ba0356',
|
||||
'initialStatusCode': 0,
|
||||
'readyStatusCode': 1,
|
||||
'loadingStatusCode': 2,
|
||||
'errorStatusCode': 3,
|
||||
'finishStatusCode': 4,
|
||||
'canRetryStatusCode': 5,
|
||||
'statusTextMap': ['未开始', '可更新', '安装中', '未安装', '已最新', '出错'],
|
||||
'taskNameLabel': '插件列表',
|
||||
'operationLabel': '操作',
|
||||
'remarkLabel': '备注说明',
|
||||
'btnText': '安装/更新',
|
||||
'submitApi': 'post:/genshinuid/api/updatePlugins',
|
||||
'checkApi': 'get:/genshinuid/api/getPlugins',
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
from typing import TypedDict
|
||||
|
||||
from fastapi_user_auth.auth.models import User
|
||||
from fastapi_amis_admin.models.fields import Field
|
||||
|
||||
@ -8,3 +10,10 @@ class WebUser(User, table=True):
|
||||
parent_id: int = Field(
|
||||
None, title='Superior', foreign_key='auth_user.id'
|
||||
) # type:ignore
|
||||
|
||||
|
||||
class Task(TypedDict):
|
||||
label: str
|
||||
key: str
|
||||
status: int
|
||||
remark: str
|
||||
|
@ -43,6 +43,7 @@ from gsuid_core.utils.cookie_manager.add_ck import _deal_ck
|
||||
from gsuid_core.webconsole.html import gsuid_webconsole_help
|
||||
from gsuid_core.webconsole.create_sv_panel import get_sv_page
|
||||
from gsuid_core.version import __version__ as GenshinUID_version
|
||||
from gsuid_core.webconsole.create_task_panel import get_tasks_panel
|
||||
from gsuid_core.webconsole.create_config_panel import get_config_page
|
||||
from gsuid_core.utils.database.models import GsBind, GsPush, GsUser, GsCache
|
||||
from gsuid_core.webconsole.login_page import ( # noqa # 不要删
|
||||
@ -395,7 +396,7 @@ class SVManagePage(GsAdminPage):
|
||||
class ConfigManagePage(GsAdminPage):
|
||||
page_schema = PageSchema(
|
||||
label=('修改设定'),
|
||||
icon='fa fa-sliders',
|
||||
icon='fa fa-cogs',
|
||||
url='/ConfigManage',
|
||||
isDefaultPage=True,
|
||||
sort=100,
|
||||
@ -403,5 +404,17 @@ class ConfigManagePage(GsAdminPage):
|
||||
page = Page.parse_obj(get_config_page())
|
||||
|
||||
|
||||
@site.register_admin
|
||||
class PluginsManagePage(GsAdminPage):
|
||||
page_schema = PageSchema(
|
||||
label=('插件管理'),
|
||||
icon='fa fa-puzzle-piece',
|
||||
url='/ConfigManage',
|
||||
isDefaultPage=True,
|
||||
sort=100,
|
||||
)
|
||||
page = Page.parse_obj(get_tasks_panel())
|
||||
|
||||
|
||||
# 取消注册默认管理类
|
||||
site.unregister_admin(admin.HomeAdmin, APIDocsApp)
|
||||
|
12
poetry.lock
generated
12
poetry.lock
generated
@ -667,14 +667,14 @@ reference = "mirrors"
|
||||
|
||||
[[package]]
|
||||
name = "fastapi-amis-admin"
|
||||
version = "0.5.5"
|
||||
version = "0.5.6"
|
||||
description = "FastAPI-Amis-Admin is a high-performance, efficient and easily extensible FastAPI admin framework. Inspired by Django-admin, and has as many powerful functions as Django-admin."
|
||||
category = "main"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "fastapi_amis_admin-0.5.5-py3-none-any.whl", hash = "sha256:8faeece0962a7db0f807e68c09fa45ed75e79ba55c9990e734de486ee6bbf4c1"},
|
||||
{file = "fastapi_amis_admin-0.5.5.tar.gz", hash = "sha256:b3c57f42fad800906cb39e0d1ea67d597747c09875ae74f20fda1d516e8b2580"},
|
||||
{file = "fastapi_amis_admin-0.5.6-py3-none-any.whl", hash = "sha256:df9160d4b28f2a2165c17ec678eddc2bfe7323c77c9dfdd8217a7e8b6895e99d"},
|
||||
{file = "fastapi_amis_admin-0.5.6.tar.gz", hash = "sha256:8bcb74d11d4e1b605b2d3eccecf308a6c5ffce65d4d8bef300de6764f0b64107"},
|
||||
]
|
||||
|
||||
[package.dependencies]
|
||||
@ -1054,14 +1054,14 @@ reference = "mirrors"
|
||||
|
||||
[[package]]
|
||||
name = "identify"
|
||||
version = "2.5.23"
|
||||
version = "2.5.24"
|
||||
description = "File identification library for Python"
|
||||
category = "dev"
|
||||
optional = false
|
||||
python-versions = ">=3.7"
|
||||
files = [
|
||||
{file = "identify-2.5.23-py2.py3-none-any.whl", hash = "sha256:17d9351c028a781456965e781ed2a435755cac655df1ebd930f7186b54399312"},
|
||||
{file = "identify-2.5.23.tar.gz", hash = "sha256:50b01b9d5f73c6b53e5fa2caf9f543d3e657a9d0bbdeb203ebb8d45960ba7433"},
|
||||
{file = "identify-2.5.24-py2.py3-none-any.whl", hash = "sha256:986dbfb38b1140e763e413e6feb44cd731faf72d1909543178aa79b0e258265d"},
|
||||
{file = "identify-2.5.24.tar.gz", hash = "sha256:0aac67d5b4812498056d28a9a512a483f5085cc28640b02b258a59dac34301d4"},
|
||||
]
|
||||
|
||||
[package.extras]
|
||||
|
@ -17,7 +17,7 @@ click==8.1.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
|
||||
colorama==0.4.6 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0" and platform_system == "Windows" or python_full_version >= "3.8.1" and python_full_version < "4.0.0" and sys_platform == "win32"
|
||||
dnspython==2.3.0 ; python_full_version >= "3.8.1" and python_version < "4.0"
|
||||
email-validator==2.0.0.post2 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
|
||||
fastapi-amis-admin==0.5.5 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
|
||||
fastapi-amis-admin==0.5.6 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
|
||||
fastapi-user-auth==0.5.0 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
|
||||
fastapi==0.95.1 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
|
||||
frozenlist==1.3.3 ; python_full_version >= "3.8.1" and python_full_version < "4.0.0"
|
||||
|
Loading…
x
Reference in New Issue
Block a user