Files

79 lines
2.6 KiB
Python

# -*- coding = utf-8 -*-
# @Time : 2025/2/13 下午4:50
# @File : routes.py
# @Software : PyCharm
# @Author : xingc
# @Desc :
import hashlib
import logging
from io import BytesIO
from pathlib import Path
from typing import Literal
from urllib.parse import urljoin
from fastapi import APIRouter, UploadFile, File, status, HTTPException, Depends
from PIL import Image
from config import settings
from core.base.schema import BaseResponse
from core.routers.auth.schema import LoginUser
from core.routers.auth.services import get_current_user_form_http
from . import schema
logger = logging.getLogger(__name__)
file_router = APIRouter(prefix='/file', tags=['文件存储模块'])
@file_router.post('/{upload_type}/upload', summary='图片上传', response_model=BaseResponse[schema.FileOut])
async def upload_file(
upload_type: Literal['card', 'chat', 'avatar'],
file: UploadFile = File(...),
login_user: LoginUser = Depends(get_current_user_form_http)
):
# 验证文件类型
if file.content_type not in settings.UPLOADED_ALLOWED_MIME_TYPES:
raise HTTPException(
status_code=status.HTTP_415_UNSUPPORTED_MEDIA_TYPE,
detail=f'Unsupported media type: {file.content_type}'
)
# 验证文件大小
if file.size > settings.UPLOADED_MAX_FILE_SIZE:
raise HTTPException(
status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE,
detail=f'File exceeds maximum size'
)
try:
file_chunks = await file.read()
file_hash = hashlib.sha256(file_chunks).hexdigest()
file_name = f'{file_hash}.jpg'
dirname_args = [upload_type.lower(), str(login_user.user_id), file_name]
save_file_path: Path = settings.UPLOADED_FILES_DIR.joinpath(*dirname_args)
if save_file_path.exists() is False:
# 创建目录
save_file_path.parent.mkdir(parents=True, exist_ok=True)
img = Image.open(BytesIO(file_chunks))
img = img.convert("RGB")
img.save(save_file_path, format="JPEG")
file_info = {
'filename': file_name,
'content_type': file.content_type,
'size': file.size,
'hash': file_hash,
'url': urljoin(settings.ASSETS_BASE_URL, '/'.join([settings.UPLOADED_FILES_DIR.name, *dirname_args])),
}
return {'data': file_info}
except Exception as e:
logger.error(f'Upload failed: {e}')
logger.exception(e)
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail='Internal server error'
)