You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
155 lines
4.4 KiB
155 lines
4.4 KiB
from fastapi import APIRouter, Depends, HTTPException, UploadFile, File as FastAPIFile, status |
|
from fastapi.responses import FileResponse |
|
from sqlalchemy.orm import Session |
|
from typing import List |
|
import os |
|
import uuid |
|
import aiofiles |
|
|
|
from apiApp.database import get_db |
|
from apiApp.schemas import ( |
|
AudioCreate, |
|
AudioResponse, |
|
AudioListResponse, |
|
MessageResponse |
|
) |
|
from apiApp.services import AudioCRUD |
|
from apiApp.config import UPLOAD_FOLDER, ALLOWED_AUDIO_EXTENSIONS, MAX_UPLOAD_SIZE |
|
|
|
router = APIRouter() |
|
|
|
|
|
@router.post("/upload", response_model=AudioResponse, status_code=status.HTTP_201_CREATED) |
|
async def upload_audio_file( |
|
file: UploadFile = FastAPIFile(...), |
|
db: Session = Depends(get_db) |
|
): |
|
""" |
|
Загрузка аудиофайла на сервер |
|
""" |
|
# Проверка расширения файла |
|
file_ext = os.path.splitext(file.filename)[1].lower() |
|
if file_ext not in ALLOWED_AUDIO_EXTENSIONS: |
|
raise HTTPException( |
|
status_code=status.HTTP_422_UNPROCESSABLE_ENTITY, |
|
detail=f"File extension not allowed. Allowed: {', '.join(ALLOWED_AUDIO_EXTENSIONS)}" |
|
) |
|
|
|
# Чтение содержимого файла |
|
content = await file.read() |
|
|
|
# Проверка размера файла |
|
if len(content) > MAX_UPLOAD_SIZE: |
|
raise HTTPException( |
|
status_code=status.HTTP_413_REQUEST_ENTITY_TOO_LARGE, |
|
detail=f"File too large. Maximum size: {MAX_UPLOAD_SIZE / (1024*1024)}MB" |
|
) |
|
|
|
# Сохранение файла |
|
file_path = UPLOAD_FOLDER / f"{uuid.uuid4()}{file_ext}" |
|
|
|
try: |
|
async with aiofiles.open(file_path, 'wb') as f: |
|
await f.write(content) |
|
except Exception as e: |
|
raise HTTPException( |
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, |
|
detail=f"Error saving file: {str(e)}" |
|
) |
|
|
|
# Создание записи в БД |
|
try: |
|
audio_data = AudioCreate(filename=file.filename) |
|
audio = AudioCRUD.create( |
|
db=db, |
|
audio_data=audio_data, |
|
file_path=str(file_path), |
|
file_size=len(content) |
|
) |
|
return audio |
|
except Exception as e: |
|
# Удаление файла при ошибке записи в БД |
|
if os.path.exists(file_path): |
|
os.remove(file_path) |
|
raise HTTPException( |
|
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, |
|
detail=f"Error creating database record: {str(e)}" |
|
) |
|
|
|
|
|
@router.get("/audio/list", response_model=AudioListResponse) |
|
async def list_audio_files( |
|
skip: int = 0, |
|
limit: int = 100, |
|
db: Session = Depends(get_db) |
|
): |
|
""" |
|
Получить список всех аудиофайлов |
|
""" |
|
audios = AudioCRUD.get_all(db) |
|
return AudioListResponse( |
|
audios=audios[skip:skip+limit], |
|
count=len(audios) |
|
) |
|
|
|
|
|
@router.get("/audio/{audio_id}", response_model=AudioResponse) |
|
async def get_audio( |
|
audio_id: uuid.UUID, |
|
db: Session = Depends(get_db) |
|
): |
|
""" |
|
Получить информацию о аудиофайле по ID |
|
""" |
|
audio = AudioCRUD.get_by_id(db, audio_id) |
|
if not audio: |
|
raise HTTPException( |
|
status_code=status.HTTP_404_NOT_FOUND, |
|
detail="Audio not found" |
|
) |
|
return audio |
|
|
|
|
|
@router.get("/audio/file/{audio_id}") |
|
async def download_audio_file( |
|
audio_id: uuid.UUID, |
|
db: Session = Depends(get_db) |
|
): |
|
""" |
|
Скачать аудиофайл по ID |
|
""" |
|
audio = AudioCRUD.get_by_id(db, audio_id) |
|
if not audio: |
|
raise HTTPException( |
|
status_code=status.HTTP_404_NOT_FOUND, |
|
detail="Audio not found" |
|
) |
|
|
|
if not audio.file_path or not os.path.exists(audio.file_path): |
|
raise HTTPException( |
|
status_code=status.HTTP_404_NOT_FOUND, |
|
detail="Audio file not found on disk" |
|
) |
|
|
|
return FileResponse( |
|
path=audio.file_path, |
|
filename=audio.filename, |
|
media_type='audio/mpeg' |
|
) |
|
|
|
|
|
@router.delete("/audio/delete/{audio_id}", response_model=AudioResponse) |
|
async def delete_audio( |
|
audio_id: uuid.UUID, |
|
db: Session = Depends(get_db) |
|
): |
|
""" |
|
Удалить аудиофайл |
|
""" |
|
audio = AudioCRUD.delete(db, audio_id) |
|
if not audio: |
|
raise HTTPException( |
|
status_code=status.HTTP_404_NOT_FOUND, |
|
detail="Audio not found" |
|
) |
|
return audio
|
|
|