fix storage api

This commit is contained in:
jxxghp
2024-09-14 14:43:14 +08:00
parent 8bb25afcdc
commit e86bf61579
8 changed files with 63 additions and 37 deletions
+28 -13
View File
@@ -1,15 +1,16 @@
from pathlib import Path from pathlib import Path
from typing import Any, List from typing import Any, List
from fastapi import APIRouter, Depends from fastapi import APIRouter, Depends, HTTPException
from starlette.responses import FileResponse from starlette.responses import FileResponse, Response
from app import schemas from app import schemas
from app.chain.storage import StorageChain from app.chain.storage import StorageChain
from app.chain.transfer import TransferChain from app.chain.transfer import TransferChain
from app.core.config import settings from app.core.config import settings
from app.core.metainfo import MetaInfoPath from app.core.metainfo import MetaInfoPath
from app.core.security import verify_token, verify_uri_token from app.core.security import verify_token
from app.db.models import User
from app.db.user_oper import get_current_active_superuser from app.db.user_oper import get_current_active_superuser
from app.helper.progress import ProgressHelper from app.helper.progress import ProgressHelper
from app.schemas.types import ProgressKey from app.schemas.types import ProgressKey
@@ -45,7 +46,7 @@ def check(name: str, ck: str = None, t: str = None, _: schemas.TokenPayload = De
@router.post("/save/{name}", summary="保存存储配置", response_model=schemas.Response) @router.post("/save/{name}", summary="保存存储配置", response_model=schemas.Response)
def save(name: str, def save(name: str,
conf: dict, conf: dict,
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: _: User = Depends(get_current_active_superuser)) -> Any:
""" """
保存存储配置 保存存储配置
""" """
@@ -56,7 +57,7 @@ def save(name: str,
@router.post("/list", summary="所有目录和文件", response_model=List[schemas.FileItem]) @router.post("/list", summary="所有目录和文件", response_model=List[schemas.FileItem])
def list(fileitem: schemas.FileItem, def list(fileitem: schemas.FileItem,
sort: str = 'updated_at', sort: str = 'updated_at',
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: _: User = Depends(get_current_active_superuser)) -> Any:
""" """
查询当前目录下所有目录和文件 查询当前目录下所有目录和文件
:param fileitem: 文件项 :param fileitem: 文件项
@@ -76,7 +77,7 @@ def list(fileitem: schemas.FileItem,
@router.post("/mkdir", summary="创建目录", response_model=schemas.Response) @router.post("/mkdir", summary="创建目录", response_model=schemas.Response)
def mkdir(fileitem: schemas.FileItem, def mkdir(fileitem: schemas.FileItem,
name: str, name: str,
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: _: User = Depends(get_current_active_superuser)) -> Any:
""" """
创建目录 创建目录
:param fileitem: 文件项 :param fileitem: 文件项
@@ -93,7 +94,7 @@ def mkdir(fileitem: schemas.FileItem,
@router.post("/delete", summary="删除文件或目录", response_model=schemas.Response) @router.post("/delete", summary="删除文件或目录", response_model=schemas.Response)
def delete(fileitem: schemas.FileItem, def delete(fileitem: schemas.FileItem,
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: _: User = Depends(get_current_active_superuser)) -> Any:
""" """
删除文件或目录 删除文件或目录
:param fileitem: 文件项 :param fileitem: 文件项
@@ -107,25 +108,39 @@ def delete(fileitem: schemas.FileItem,
@router.post("/download", summary="下载文件") @router.post("/download", summary="下载文件")
def download(fileitem: schemas.FileItem, def download(fileitem: schemas.FileItem,
_: schemas.TokenPayload = Depends(verify_uri_token)) -> Any: _: User = Depends(get_current_active_superuser)) -> Any:
""" """
下载文件或目录 下载文件或目录
:param fileitem: 文件项 :param fileitem: 文件项
:param _: token :param _: token
""" """
# 临时目录 # 临时目录
tmp_file = settings.TEMP_PATH / fileitem.name tmp_file = StorageChain().download_file(fileitem)
status = StorageChain().download_file(fileitem, tmp_file) if tmp_file:
if status:
return FileResponse(path=tmp_file) return FileResponse(path=tmp_file)
return schemas.Response(success=False) return schemas.Response(success=False)
@router.post("/image", summary="预览图片")
def image(fileitem: schemas.FileItem,
_: User = Depends(get_current_active_superuser)) -> Any:
"""
下载文件或目录
:param fileitem: 文件项
:param _: token
"""
# 临时目录
tmp_file = StorageChain().download_file(fileitem)
if not tmp_file:
raise HTTPException(status_code=500, detail="图片读取出错")
return Response(content=tmp_file.read_bytes(), media_type="image/jpeg")
@router.post("/rename", summary="重命名文件或目录", response_model=schemas.Response) @router.post("/rename", summary="重命名文件或目录", response_model=schemas.Response)
def rename(fileitem: schemas.FileItem, def rename(fileitem: schemas.FileItem,
new_name: str, new_name: str,
recursive: bool = False, recursive: bool = False,
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: _: User = Depends(get_current_active_superuser)) -> Any:
""" """
重命名文件或目录 重命名文件或目录
:param fileitem: 文件项 :param fileitem: 文件项
@@ -181,7 +196,7 @@ def rename(fileitem: schemas.FileItem,
@router.get("/usage/{name}", summary="存储空间信息", response_model=schemas.StorageUsage) @router.get("/usage/{name}", summary="存储空间信息", response_model=schemas.StorageUsage)
def usage(name: str, _: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any: def usage(name: str, _: User = Depends(get_current_active_superuser)) -> Any:
""" """
查询存储空间 查询存储空间
""" """
+2 -2
View File
@@ -40,11 +40,11 @@ class StorageChain(ChainBase):
""" """
return self.run_module("create_folder", fileitem=fileitem, name=name) return self.run_module("create_folder", fileitem=fileitem, name=name)
def download_file(self, fileitem: schemas.FileItem, path: str) -> Optional[bool]: def download_file(self, fileitem: schemas.FileItem) -> Optional[Path]:
""" """
下载文件 下载文件
""" """
return self.run_module("download_file", fileitem=fileitem, path=path) return self.run_module("download_file", fileitem=fileitem)
def upload_file(self, fileitem: schemas.FileItem, path: Path) -> Optional[bool]: def upload_file(self, fileitem: schemas.FileItem, path: Path) -> Optional[bool]:
""" """
+11 -5
View File
@@ -185,15 +185,15 @@ class FileManagerModule(_ModuleBase):
return False return False
return storage_oper.rename(fileitem, name) return storage_oper.rename(fileitem, name)
def download_file(self, fileitem: FileItem, path: Path) -> bool: def download_file(self, fileitem: FileItem) -> Optional[Path]:
""" """
下载文件 下载文件
""" """
storage_oper = self.__get_storage_oper(fileitem.storage) storage_oper = self.__get_storage_oper(fileitem.storage)
if not storage_oper: if not storage_oper:
logger.error(f"不支持 {fileitem.storage} 的下载处理") logger.error(f"不支持 {fileitem.storage} 的下载处理")
return False return None
return storage_oper.download(fileitem, path) return storage_oper.download(fileitem)
def upload_file(self, fileitem: FileItem, path: Path) -> Optional[FileItem]: def upload_file(self, fileitem: FileItem, path: Path) -> Optional[FileItem]:
""" """
@@ -414,13 +414,19 @@ class FileManagerModule(_ModuleBase):
# 网盘到本地 # 网盘到本地
if transfer_type == "copy": if transfer_type == "copy":
# 下载 # 下载
if source_oper.download(fileitem, target_file): tmp_file = source_oper.download(fileitem)
if tmp_file:
# 将tmp_file移动后target_file
tmp_file.rename(target_file)
return __get_targetitem(target_file), "" return __get_targetitem(target_file), ""
else: else:
return None, f"{fileitem.path} {fileitem.storage} 下载失败" return None, f"{fileitem.path} {fileitem.storage} 下载失败"
elif transfer_type == "move": elif transfer_type == "move":
# 下载 # 下载
if source_oper.download(fileitem, target_file): tmp_file = source_oper.download(fileitem)
if tmp_file:
# 将tmp_file移动后target_file
tmp_file.rename(target_file)
# 删除源文件 # 删除源文件
source_oper.delete(fileitem) source_oper.delete(fileitem)
return __get_targetitem(target_file), "" return __get_targetitem(target_file), ""
+2 -2
View File
@@ -96,9 +96,9 @@ class StorageBase(metaclass=ABCMeta):
pass pass
@abstractmethod @abstractmethod
def download(self, fileitm: schemas.FileItem, path: Path) -> bool: def download(self, fileitm: schemas.FileItem) -> Path:
""" """
下载文件,保存到本地 下载文件,保存到本地,返回本地临时文件地址
""" """
pass pass
+6 -5
View File
@@ -587,13 +587,13 @@ class AliPan(StorageBase):
self.__handle_error(res, "重命名文件") self.__handle_error(res, "重命名文件")
return False return False
def download(self, fileitem: schemas.FileItem, path: Path) -> bool: def download(self, fileitem: schemas.FileItem) -> Optional[Path]:
""" """
下载文件,保存到本地 下载文件,保存到本地
""" """
params = self.__access_params params = self.__access_params
if not params: if not params:
return False return None
headers = self.__get_headers(params) headers = self.__get_headers(params)
res = RequestUtils(headers=headers, timeout=10).post_res(self.download_url, json={ res = RequestUtils(headers=headers, timeout=10).post_res(self.download_url, json={
"drive_id": fileitem.drive_id, "drive_id": fileitem.drive_id,
@@ -602,15 +602,16 @@ class AliPan(StorageBase):
if res: if res:
download_url = res.json().get("url") download_url = res.json().get("url")
if not download_url: if not download_url:
return False return None
res = RequestUtils().get_res(download_url) res = RequestUtils().get_res(download_url)
if res: if res:
path = settings.TEMP_PATH / fileitem.name
with path.open("wb") as f: with path.open("wb") as f:
f.write(res.content) f.write(res.content)
return True return path
else: else:
self.__handle_error(res, "获取下载链接") self.__handle_error(res, "获取下载链接")
return False return None
def upload(self, fileitem: schemas.FileItem, path: Path) -> Optional[schemas.FileItem]: def upload(self, fileitem: schemas.FileItem, path: Path) -> Optional[schemas.FileItem]:
""" """
+2 -2
View File
@@ -177,11 +177,11 @@ class LocalStorage(StorageBase):
return False return False
return True return True
def download(self, fileitem: schemas.FileItem, path: Path) -> bool: def download(self, fileitem: schemas.FileItem) -> Optional[Path]:
""" """
下载文件 下载文件
""" """
pass return Path(fileitem.path)
def upload(self, fileitem: schemas.FileItem, path: Path) -> Optional[schemas.FileItem]: def upload(self, fileitem: schemas.FileItem, path: Path) -> Optional[schemas.FileItem]:
""" """
+6 -4
View File
@@ -5,6 +5,7 @@ from pathlib import Path
from typing import Optional, List from typing import Optional, List
from app import schemas from app import schemas
from app.core.config import settings
from app.log import logger from app.log import logger
from app.modules.filemanager.storages import StorageBase from app.modules.filemanager.storages import StorageBase
from app.schemas.types import StorageSchema from app.schemas.types import StorageSchema
@@ -225,24 +226,25 @@ class Rclone(StorageBase):
logger.error(f"rclone重命名文件失败:{err}") logger.error(f"rclone重命名文件失败:{err}")
return False return False
def download(self, fileitm: schemas.FileItem, path: Path) -> bool: def download(self, fileitem: schemas.FileItem) -> Optional[Path]:
""" """
下载文件 下载文件
""" """
path = settings.TEMP_PATH / fileitem.name
try: try:
retcode = subprocess.run( retcode = subprocess.run(
[ [
'rclone', 'copyto', 'rclone', 'copyto',
f'MP:{fileitm.path}', f'MP:{fileitem.path}',
f'{path}' f'{path}'
], ],
startupinfo=self.__get_hidden_shell() startupinfo=self.__get_hidden_shell()
).returncode ).returncode
if retcode == 0: if retcode == 0:
return True return path
except Exception as err: except Exception as err:
logger.error(f"rclone复制文件失败:{err}") logger.error(f"rclone复制文件失败:{err}")
return False return None
def upload(self, fileitm: schemas.FileItem, path: Path) -> Optional[schemas.FileItem]: def upload(self, fileitm: schemas.FileItem, path: Path) -> Optional[schemas.FileItem]:
""" """
+6 -4
View File
@@ -8,6 +8,7 @@ from py115 import Cloud
from py115.types import LoginTarget, QrcodeSession, QrcodeStatus, Credential from py115.types import LoginTarget, QrcodeSession, QrcodeStatus, Credential
from app import schemas from app import schemas
from app.core.config import settings
from app.log import logger from app.log import logger
from app.modules.filemanager.storages import StorageBase from app.modules.filemanager.storages import StorageBase
from app.schemas.types import StorageSchema from app.schemas.types import StorageSchema
@@ -289,23 +290,24 @@ class U115Pan(StorageBase, metaclass=Singleton):
logger.error(f"115重命名文件失败:{str(e)}") logger.error(f"115重命名文件失败:{str(e)}")
return False return False
def download(self, fileitem: schemas.FileItem, path: Path) -> bool: def download(self, fileitem: schemas.FileItem) -> Optional[Path]:
""" """
获取下载链接 获取下载链接
""" """
if not self.__init_cloud(): if not self.__init_cloud():
return False return None
try: try:
ticket = self.cloud.storage().request_download(fileitem.pickcode) ticket = self.cloud.storage().request_download(fileitem.pickcode)
if ticket: if ticket:
path = settings.TEMP_PATH / fileitem.name
res = RequestUtils(headers=ticket.headers).get_res(ticket.url) res = RequestUtils(headers=ticket.headers).get_res(ticket.url)
if res: if res:
with open(path, "wb") as f: with open(path, "wb") as f:
f.write(res.content) f.write(res.content)
return True return path
except Exception as e: except Exception as e:
logger.error(f"115下载失败:{str(e)}") logger.error(f"115下载失败:{str(e)}")
return False return None
def upload(self, fileitem: schemas.FileItem, path: Path) -> Optional[schemas.FileItem]: def upload(self, fileitem: schemas.FileItem, path: Path) -> Optional[schemas.FileItem]:
""" """