Files

113 lines
4.2 KiB
Python

from __future__ import annotations
from fastapi import HTTPException, UploadFile
from sqlalchemy.ext.asyncio import AsyncSession
from app.enums.private_portrait import (
PrivatePortraitEventSource,
PrivatePortraitEventStatus,
PrivatePortraitEventType,
PrivatePortraitLibraryType,
)
from app.enums.upload_resource import UploadResourceModuleEnum, UploadResourceTypeEnum
from app.models.user import User
from app.schemas.private_portrait import PrivatePortraitUploadOut
from app.services.operation_log_service import log_operation_error, log_operation_event
from app.services.upload_resource import upload_reference_file
DOMAIN = "private_portrait"
PRIVATE_PORTRAIT_IMAGE_MAX_BYTES = 10 * 1024 * 1024
PRIVATE_PORTRAIT_VIDEO_MAX_BYTES = 100 * 1024 * 1024
def private_portrait_upload_module(library_type: str) -> str:
if library_type == PrivatePortraitLibraryType.REAL_PERSON.value:
return UploadResourceModuleEnum.PRIVATE_PORTRAIT_REAL.value
if library_type == PrivatePortraitLibraryType.AIGC_VIRTUAL.value:
return UploadResourceModuleEnum.PRIVATE_PORTRAIT_VIRTUAL.value
raise HTTPException(status_code=400, detail="素材库类型不支持")
async def upload_private_portrait_asset_file(
db: AsyncSession,
*,
file: UploadFile,
current_user: User,
library_type: str,
resource_type: str,
duration_seconds: float | None = None,
) -> PrivatePortraitUploadOut:
if resource_type not in {UploadResourceTypeEnum.IMAGE.value, UploadResourceTypeEnum.VIDEO.value}:
raise HTTPException(status_code=400, detail="私域素材上传仅支持图片或视频")
module = private_portrait_upload_module(library_type)
max_bytes = PRIVATE_PORTRAIT_VIDEO_MAX_BYTES if resource_type == UploadResourceTypeEnum.VIDEO.value else PRIVATE_PORTRAIT_IMAGE_MAX_BYTES
log_operation_event(
domain=DOMAIN,
event_type=PrivatePortraitEventType.ASSET_UPLOAD_START.value,
event_status=PrivatePortraitEventStatus.PENDING.value,
source=PrivatePortraitEventSource.API.value,
user_id=current_user.id,
detail={
"module": module,
"library_type": library_type,
"resource_type": resource_type,
"filename": file.filename,
"content_type": file.content_type,
"duration_seconds": duration_seconds,
},
)
try:
result = await upload_reference_file(
db,
file=file,
current_user=current_user,
module=module,
resource_type=resource_type,
gen_type="private_portrait",
duration_seconds=duration_seconds,
max_bytes=max_bytes,
)
out = PrivatePortraitUploadOut(
url=result.url,
filename=result.filename,
type=result.resource_type,
module=result.module,
resource_id=result.resource_id,
file_size_bytes=result.file_size_bytes,
duration_seconds=result.duration_seconds,
)
log_operation_event(
domain=DOMAIN,
event_type=PrivatePortraitEventType.ASSET_UPLOAD_SUCCESS.value,
event_status=PrivatePortraitEventStatus.SUCCESS.value,
source=PrivatePortraitEventSource.API.value,
user_id=current_user.id,
detail={
"module": module,
"library_type": library_type,
"resource_type": resource_type,
"resource_id": result.resource_id,
"url": result.url,
"file_size_bytes": result.file_size_bytes,
"duration_seconds": result.duration_seconds,
},
)
return out
except Exception as exc: # noqa: BLE001
log_operation_error(
domain=DOMAIN,
event_type=PrivatePortraitEventType.ASSET_UPLOAD_FAILED.value,
source=PrivatePortraitEventSource.API.value,
user_id=current_user.id,
exc=exc,
detail={
"module": module,
"library_type": library_type,
"resource_type": resource_type,
"filename": file.filename,
},
)
raise