|
8 | 8 |
|
9 | 9 | from fastapi import APIRouter, Depends, File, UploadFile |
10 | 10 | from fastapi.params import Query |
| 11 | +from starlette.responses import StreamingResponse |
11 | 12 |
|
12 | 13 | from backend.common.exception import errors |
13 | 14 | from backend.common.response.response_schema import ResponseModel, response_base |
@@ -68,5 +69,29 @@ async def install_plugin(file: Annotated[UploadFile, File()]) -> ResponseModel: |
68 | 69 | return response_base.success() |
69 | 70 |
|
70 | 71 |
|
71 | | -@router.post('/zip', summary='打包插件') |
72 | | -async def build_plugin_zip(plugin: Annotated[str, Query()]): ... |
| 72 | +@router.post( |
| 73 | + '/zip', |
| 74 | + summary='打包插件', |
| 75 | + dependencies=[ |
| 76 | + Depends(RequestPermission('sys:plugin:zip')), |
| 77 | + DependsRBAC, |
| 78 | + ], |
| 79 | +) |
| 80 | +async def build_plugin_zip(plugin: Annotated[str, Query()]): |
| 81 | + plugin_dir = os.path.join(PLUGIN_DIR, plugin) |
| 82 | + if not os.path.exists(plugin_dir): |
| 83 | + raise errors.ForbiddenError(msg='插件不存在') |
| 84 | + bio = io.BytesIO() |
| 85 | + with zipfile.ZipFile(bio, 'w') as zf: |
| 86 | + for root, dirs, files in os.walk(plugin_dir): |
| 87 | + dirs[:] = [d for d in dirs if d != '__pycache__'] |
| 88 | + for file in files: |
| 89 | + file_path = os.path.join(root, file) |
| 90 | + arcname = os.path.relpath(file_path, start=plugin_dir) |
| 91 | + zf.write(file_path, arcname) |
| 92 | + bio.seek(0) |
| 93 | + return StreamingResponse( |
| 94 | + bio, |
| 95 | + media_type='application/x-zip-compressed', |
| 96 | + headers={'Content-Disposition': f'attachment; filename={plugin}.zip'}, |
| 97 | + ) |
0 commit comments