113 lines
4.2 KiB
Python
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
|