81 lines
2.9 KiB
Python
81 lines
2.9 KiB
Python
from fastapi import APIRouter, HTTPException, Request, Depends
|
||
from fastapi.responses import FileResponse
|
||
from loguru import logger
|
||
|
||
from app.core.deps import get_current_user
|
||
from app.core.response import success_response
|
||
from app.modules.materials.schemas import RenameMaterialRequest
|
||
from app.modules.materials import service
|
||
from app.services.storage import storage_service
|
||
|
||
router = APIRouter()
|
||
|
||
|
||
@router.get("/stream/{material_id:path}")
|
||
async def stream_material(material_id: str, current_user: dict = Depends(get_current_user)):
|
||
"""直接流式返回素材文件(同源,避免 CORS canvas taint)"""
|
||
if ".." in material_id:
|
||
raise HTTPException(400, "非法素材ID")
|
||
user_id = current_user["id"]
|
||
if not material_id.startswith(f"{user_id}/"):
|
||
raise HTTPException(403, "无权访问此素材")
|
||
local_path = storage_service.get_local_file_path("materials", material_id)
|
||
if not local_path:
|
||
raise HTTPException(404, "素材文件不存在")
|
||
return FileResponse(local_path, media_type="video/mp4")
|
||
|
||
|
||
@router.post("")
|
||
async def upload_material(
|
||
request: Request,
|
||
current_user: dict = Depends(get_current_user)
|
||
):
|
||
user_id = current_user["id"]
|
||
logger.info(f"Upload material request from user {user_id}")
|
||
try:
|
||
result = await service.upload_material(request, user_id)
|
||
return success_response(result)
|
||
except ValueError as e:
|
||
raise HTTPException(400, str(e))
|
||
except Exception as e:
|
||
raise HTTPException(500, f"Upload failed. Error: {str(e)}")
|
||
|
||
|
||
@router.get("")
|
||
async def list_materials(current_user: dict = Depends(get_current_user)):
|
||
user_id = current_user["id"]
|
||
materials = await service.list_materials(user_id)
|
||
return success_response({"materials": materials})
|
||
|
||
|
||
@router.delete("/{material_id:path}")
|
||
async def delete_material(material_id: str, current_user: dict = Depends(get_current_user)):
|
||
user_id = current_user["id"]
|
||
try:
|
||
await service.delete_material(material_id, user_id)
|
||
return success_response(message="素材已删除")
|
||
except ValueError as e:
|
||
raise HTTPException(400, str(e))
|
||
except PermissionError as e:
|
||
raise HTTPException(403, str(e))
|
||
except Exception as e:
|
||
raise HTTPException(500, f"删除失败: {str(e)}")
|
||
|
||
|
||
@router.put("/{material_id:path}")
|
||
async def rename_material(
|
||
material_id: str,
|
||
payload: RenameMaterialRequest,
|
||
current_user: dict = Depends(get_current_user)
|
||
):
|
||
user_id = current_user["id"]
|
||
try:
|
||
result = await service.rename_material(material_id, payload.new_name, user_id)
|
||
return success_response(result, message="重命名成功")
|
||
except PermissionError as e:
|
||
raise HTTPException(403, str(e))
|
||
except ValueError as e:
|
||
raise HTTPException(400, str(e))
|
||
except Exception as e:
|
||
raise HTTPException(500, f"重命名失败: {str(e)}")
|