无hooks.py文件的扩展包作为模块包安装到jingrow里面,卸载扩展包时同时卸载package包含的本地模块
This commit is contained in:
parent
ad5129497e
commit
cba916ae28
@ -110,13 +110,12 @@ const uninstallPackage = async (packageName: string) => {
|
||||
try {
|
||||
uninstalling.value = true
|
||||
|
||||
const response = await axios.post('/api/action/jingrow.core.pagetype.package.package.uninstall_package', {
|
||||
package_name: packageName
|
||||
}, {
|
||||
// 调用本地API,它会先卸载数据库,再删除本地模块
|
||||
const response = await axios.post(`/jingrow/uninstall-extension/${packageName}`, {}, {
|
||||
headers: get_session_api_headers()
|
||||
})
|
||||
|
||||
if (response.data.message.status === 'success') {
|
||||
if (response.data.success) {
|
||||
message.success(props.context.t("Package '{0}' uninstalled successfully").replace('{0}', packageName))
|
||||
|
||||
// 卸载成功后跳转到Package列表页
|
||||
|
||||
@ -115,6 +115,10 @@ async def install_app_from_upload(
|
||||
backend_result = result.get('backend_result', {})
|
||||
app_dir = backend_result.get('app_dir')
|
||||
|
||||
# 扩展包不添加到 Local Installed Apps(返回时没有 app_dir)
|
||||
if not app_dir:
|
||||
return result
|
||||
|
||||
# 对齐扫描安装的执行链
|
||||
try:
|
||||
# 1. 添加到 Local Installed Apps PageType
|
||||
@ -437,6 +441,67 @@ async def get_installed_apps(request: Request):
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
|
||||
@router.post("/jingrow/uninstall-extension/{package_name}")
|
||||
async def uninstall_extension(request: Request, package_name: str):
|
||||
"""卸载扩展包 - 先获取模块列表,卸载数据库,再删除本地目录"""
|
||||
try:
|
||||
# 获取 jingrow 应用目录
|
||||
apps_dir, _ = get_app_directories()
|
||||
jingrow_backend_dir = apps_dir / "jingrow" / "jingrow"
|
||||
|
||||
if not jingrow_backend_dir.exists():
|
||||
return {'success': False, 'error': '找不到 jingrow 应用目录'}
|
||||
|
||||
# 1. 先从数据库获取模块列表
|
||||
modules = []
|
||||
try:
|
||||
deps_url = f"{Config.jingrow_server_url}/api/action/jingrow.core.pagetype.package.package.get_package_dependencies"
|
||||
response = requests.post(
|
||||
deps_url,
|
||||
json={'package_name': package_name},
|
||||
headers=get_jingrow_api_headers(),
|
||||
timeout=60
|
||||
)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
if result.get('message', {}).get('status') == 'success':
|
||||
modules = result['message'].get('modules', [])
|
||||
except Exception as e:
|
||||
pass
|
||||
|
||||
# 2. 调用云端API卸载数据库记录
|
||||
try:
|
||||
uninstall_url = f"{Config.jingrow_server_url}/api/action/jingrow.core.pagetype.package.package.uninstall_package"
|
||||
requests.post(
|
||||
uninstall_url,
|
||||
json={'package_name': package_name},
|
||||
headers=get_jingrow_api_headers(),
|
||||
timeout=60
|
||||
)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# 3. 删除本地模块目录
|
||||
removed_count = 0
|
||||
for module_name in modules:
|
||||
module_dir_name = module_name.lower().replace(" ", "_").replace("-", "_")
|
||||
module_dir = jingrow_backend_dir / module_dir_name
|
||||
|
||||
if module_dir.exists():
|
||||
shutil.rmtree(module_dir)
|
||||
removed_count += 1
|
||||
|
||||
return {
|
||||
'success': True,
|
||||
'message': f'扩展包卸载成功,删除了 {removed_count} 个本地模块目录',
|
||||
'removed_count': removed_count
|
||||
}
|
||||
|
||||
except Exception as e:
|
||||
raise HTTPException(status_code=500, detail=str(e))
|
||||
|
||||
|
||||
@router.post("/jingrow/uninstall/{app_name}")
|
||||
async def uninstall_app(request: Request, app_name: str):
|
||||
"""卸载应用 - 直接删除整个app目录"""
|
||||
|
||||
@ -102,6 +102,16 @@ def analyze_package(temp_dir: str) -> Dict[str, Any]:
|
||||
except:
|
||||
pass
|
||||
|
||||
# 检查是否有 hooks.py(判断是否为独立应用)
|
||||
hooks_path = os.path.join(root_dir, 'hooks.py')
|
||||
if not os.path.exists(hooks_path):
|
||||
# 在子目录中查找
|
||||
for root, dirs, files in os.walk(root_dir):
|
||||
if 'hooks.py' in files:
|
||||
hooks_path = os.path.join(root, 'hooks.py')
|
||||
break
|
||||
package_info['has_hooks'] = os.path.exists(hooks_path)
|
||||
|
||||
# 扫描文件
|
||||
for root, dirs, files in os.walk(root_dir):
|
||||
for file in files:
|
||||
@ -294,6 +304,16 @@ def install_app(uploaded_file_path: str, app_name: str = None) -> Dict[str, Any]
|
||||
|
||||
package_info = analyze_result['data']
|
||||
|
||||
# 检查是否有 hooks.py
|
||||
has_hooks = package_info.get('has_hooks', False)
|
||||
|
||||
if not has_hooks:
|
||||
# 作为扩展包安装到 jingrow 应用内部
|
||||
result = install_package(temp_dir, package_info)
|
||||
cleanup_temp_dir(temp_dir)
|
||||
return result
|
||||
|
||||
# 独立应用安装流程
|
||||
# 确定应用名称
|
||||
if not app_name:
|
||||
app_name = package_info.get('app_name')
|
||||
@ -457,3 +477,57 @@ def install_extension_package(package_path: str) -> Dict[str, Any]:
|
||||
|
||||
except Exception as e:
|
||||
return {'success': False, 'error': str(e)}
|
||||
|
||||
|
||||
@handle_errors
|
||||
def install_package(temp_dir: str, package_info: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""将扩展包安装到 jingrow 应用内部并同步到数据库"""
|
||||
root_dir = package_info.get('root_dir', temp_dir)
|
||||
app_name = package_info.get('app_name')
|
||||
|
||||
# 获取 jingrow 应用目录
|
||||
apps_dir, _ = get_app_directories()
|
||||
jingrow_backend_dir = apps_dir / "jingrow" / "jingrow"
|
||||
|
||||
if not jingrow_backend_dir.exists():
|
||||
return {'success': False, 'error': '找不到 jingrow 应用目录'}
|
||||
|
||||
# 检查是否有 app_name 子目录
|
||||
inner_app_dir = os.path.join(root_dir, app_name)
|
||||
source_dir = inner_app_dir if os.path.exists(inner_app_dir) and os.path.isdir(inner_app_dir) else root_dir
|
||||
|
||||
# 先同步到数据库
|
||||
try:
|
||||
from jingrow.utils.jingrow_api import get_jingrow_api_headers
|
||||
from jingrow.config import Config
|
||||
import requests
|
||||
|
||||
api_url = f"{Config.jingrow_server_url}/api/action/jingrow.ai.utils.jlocal.sync_app_files"
|
||||
response = requests.post(
|
||||
api_url,
|
||||
json={'app_name': app_name, 'app_path': source_dir, 'force': True},
|
||||
headers=get_jingrow_api_headers(),
|
||||
timeout=60
|
||||
)
|
||||
|
||||
if response.status_code != 200:
|
||||
return {'success': False, 'error': f'同步到数据库失败: HTTP {response.status_code}'}
|
||||
except Exception as e:
|
||||
return {'success': False, 'error': f'同步到数据库失败: {str(e)}'}
|
||||
|
||||
# 再复制文件到 jingrow(只复制模块目录,跳过配置和文档文件)
|
||||
for item in os.listdir(source_dir):
|
||||
if item in ['__pycache__', '.git', 'frontend'] or item.endswith('.json') or item in ['LICENSE.md', 'README.md', 'README']:
|
||||
continue
|
||||
|
||||
src = os.path.join(source_dir, item)
|
||||
dst = jingrow_backend_dir / item
|
||||
|
||||
if os.path.isdir(src):
|
||||
if dst.exists():
|
||||
shutil.rmtree(dst)
|
||||
shutil.copytree(src, dst)
|
||||
else:
|
||||
shutil.copy2(src, dst)
|
||||
|
||||
return {'success': True, 'message': '扩展包已安装到 jingrow 应用', 'app_name': app_name}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user