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

View File

@@ -1,15 +1,16 @@
from pathlib import Path
from typing import Any, List
from fastapi import APIRouter, Depends
from starlette.responses import FileResponse
from fastapi import APIRouter, Depends, HTTPException
from starlette.responses import FileResponse, Response
from app import schemas
from app.chain.storage import StorageChain
from app.chain.transfer import TransferChain
from app.core.config import settings
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.helper.progress import ProgressHelper
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)
def save(name: str,
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])
def list(fileitem: schemas.FileItem,
sort: str = 'updated_at',
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any:
_: User = Depends(get_current_active_superuser)) -> Any:
"""
查询当前目录下所有目录和文件
:param fileitem: 文件项
@@ -76,7 +77,7 @@ def list(fileitem: schemas.FileItem,
@router.post("/mkdir", summary="创建目录", response_model=schemas.Response)
def mkdir(fileitem: schemas.FileItem,
name: str,
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any:
_: User = Depends(get_current_active_superuser)) -> Any:
"""
创建目录
:param fileitem: 文件项
@@ -93,7 +94,7 @@ def mkdir(fileitem: schemas.FileItem,
@router.post("/delete", summary="删除文件或目录", response_model=schemas.Response)
def delete(fileitem: schemas.FileItem,
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any:
_: User = Depends(get_current_active_superuser)) -> Any:
"""
删除文件或目录
:param fileitem: 文件项
@@ -107,25 +108,39 @@ def delete(fileitem: schemas.FileItem,
@router.post("/download", summary="下载文件")
def download(fileitem: schemas.FileItem,
_: schemas.TokenPayload = Depends(verify_uri_token)) -> Any:
_: User = Depends(get_current_active_superuser)) -> Any:
"""
下载文件或目录
:param fileitem: 文件项
:param _: token
"""
# 临时目录
tmp_file = settings.TEMP_PATH / fileitem.name
status = StorageChain().download_file(fileitem, tmp_file)
if status:
tmp_file = StorageChain().download_file(fileitem)
if tmp_file:
return FileResponse(path=tmp_file)
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)
def rename(fileitem: schemas.FileItem,
new_name: str,
recursive: bool = False,
_: schemas.TokenPayload = Depends(get_current_active_superuser)) -> Any:
_: User = Depends(get_current_active_superuser)) -> Any:
"""
重命名文件或目录
:param fileitem: 文件项
@@ -181,7 +196,7 @@ def rename(fileitem: schemas.FileItem,
@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:
"""
查询存储空间
"""

View File

@@ -40,11 +40,11 @@ class StorageChain(ChainBase):
"""
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]:
"""

View File

@@ -185,15 +185,15 @@ class FileManagerModule(_ModuleBase):
return False
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)
if not storage_oper:
logger.error(f"不支持 {fileitem.storage} 的下载处理")
return False
return storage_oper.download(fileitem, path)
return None
return storage_oper.download(fileitem)
def upload_file(self, fileitem: FileItem, path: Path) -> Optional[FileItem]:
"""
@@ -414,13 +414,19 @@ class FileManagerModule(_ModuleBase):
# 网盘到本地
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), ""
else:
return None, f"{fileitem.path} {fileitem.storage} 下载失败"
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)
return __get_targetitem(target_file), ""

View File

@@ -96,9 +96,9 @@ class StorageBase(metaclass=ABCMeta):
pass
@abstractmethod
def download(self, fileitm: schemas.FileItem, path: Path) -> bool:
def download(self, fileitm: schemas.FileItem) -> Path:
"""
下载文件,保存到本地
下载文件,保存到本地,返回本地临时文件地址
"""
pass

View File

@@ -587,13 +587,13 @@ class AliPan(StorageBase):
self.__handle_error(res, "重命名文件")
return False
def download(self, fileitem: schemas.FileItem, path: Path) -> bool:
def download(self, fileitem: schemas.FileItem) -> Optional[Path]:
"""
下载文件,保存到本地
"""
params = self.__access_params
if not params:
return False
return None
headers = self.__get_headers(params)
res = RequestUtils(headers=headers, timeout=10).post_res(self.download_url, json={
"drive_id": fileitem.drive_id,
@@ -602,15 +602,16 @@ class AliPan(StorageBase):
if res:
download_url = res.json().get("url")
if not download_url:
return False
return None
res = RequestUtils().get_res(download_url)
if res:
path = settings.TEMP_PATH / fileitem.name
with path.open("wb") as f:
f.write(res.content)
return True
return path
else:
self.__handle_error(res, "获取下载链接")
return False
return None
def upload(self, fileitem: schemas.FileItem, path: Path) -> Optional[schemas.FileItem]:
"""

View File

@@ -177,11 +177,11 @@ class LocalStorage(StorageBase):
return False
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]:
"""

View File

@@ -5,6 +5,7 @@ from pathlib import Path
from typing import Optional, List
from app import schemas
from app.core.config import settings
from app.log import logger
from app.modules.filemanager.storages import StorageBase
from app.schemas.types import StorageSchema
@@ -225,24 +226,25 @@ class Rclone(StorageBase):
logger.error(f"rclone重命名文件失败{err}")
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:
retcode = subprocess.run(
[
'rclone', 'copyto',
f'MP:{fileitm.path}',
f'MP:{fileitem.path}',
f'{path}'
],
startupinfo=self.__get_hidden_shell()
).returncode
if retcode == 0:
return True
return path
except Exception as err:
logger.error(f"rclone复制文件失败{err}")
return False
return None
def upload(self, fileitm: schemas.FileItem, path: Path) -> Optional[schemas.FileItem]:
"""

View File

@@ -8,6 +8,7 @@ from py115 import Cloud
from py115.types import LoginTarget, QrcodeSession, QrcodeStatus, Credential
from app import schemas
from app.core.config import settings
from app.log import logger
from app.modules.filemanager.storages import StorageBase
from app.schemas.types import StorageSchema
@@ -289,23 +290,24 @@ class U115Pan(StorageBase, metaclass=Singleton):
logger.error(f"115重命名文件失败{str(e)}")
return False
def download(self, fileitem: schemas.FileItem, path: Path) -> bool:
def download(self, fileitem: schemas.FileItem) -> Optional[Path]:
"""
获取下载链接
"""
if not self.__init_cloud():
return False
return None
try:
ticket = self.cloud.storage().request_download(fileitem.pickcode)
if ticket:
path = settings.TEMP_PATH / fileitem.name
res = RequestUtils(headers=ticket.headers).get_res(ticket.url)
if res:
with open(path, "wb") as f:
f.write(res.content)
return True
return path
except Exception as e:
logger.error(f"115下载失败{str(e)}")
return False
return None
def upload(self, fileitem: schemas.FileItem, path: Path) -> Optional[schemas.FileItem]:
"""