init: new structure + fix lint errors

This commit is contained in:
Daniil
2026-02-03 02:15:07 +03:00
commit 67e0f22b4f
89 changed files with 7654 additions and 0 deletions
+232
View File
@@ -0,0 +1,232 @@
from __future__ import annotations
import uuid
from fastapi import APIRouter, Depends, HTTPException, Query, Response, status
from sqlalchemy.ext.asyncio import AsyncSession
from cpv3.infrastructure.auth import get_current_user
from cpv3.infrastructure.deps import get_storage
from cpv3.infrastructure.storage.base import StorageService
from cpv3.db.session import get_db
from cpv3.modules.media.schemas import (
ArtifactMediaFileCreate,
ArtifactMediaFileRead,
ArtifactMediaFileUpdate,
MediaConverterParams,
MediaFileCreate,
MediaFileRead,
MediaFileUpdate,
MediaProbeSchema,
MediaSilencerParams,
)
from cpv3.modules.media.service import convert_to_mp4, probe_media, remove_silence
from cpv3.modules.media.repository import ArtifactRepository, MediaFileRepository
from cpv3.modules.files.schemas import FileInfoResponse
from cpv3.modules.users.models import User
media_router = APIRouter(prefix="/api/media", tags=["media"])
mediafiles_router = APIRouter(prefix="/api/media", tags=["mediafiles"])
artifacts_router = APIRouter(prefix="/api/media", tags=["artifacts"])
@media_router.get("/get_meta/", response_model=MediaProbeSchema)
async def get_meta(
file_path: str = Query(...),
current_user: User = Depends(get_current_user),
storage: StorageService = Depends(get_storage),
) -> MediaProbeSchema:
_ = current_user
return await probe_media(storage, file_key=file_path)
@media_router.post("/silence_remove", response_model=FileInfoResponse)
async def silence_remove(
body: MediaSilencerParams,
current_user: User = Depends(get_current_user),
storage: StorageService = Depends(get_storage),
) -> FileInfoResponse:
_ = current_user
info = await remove_silence(
storage,
file_key=body.file_path,
out_folder=body.folder,
min_silence_duration_ms=body.min_silence_duration_ms,
silence_threshold_db=body.silence_threshold_db,
padding_ms=body.padding_ms,
)
return FileInfoResponse(
file_path=info.file_path,
file_url=info.file_url,
file_size=info.file_size,
filename=info.filename,
)
@media_router.post("/convert", response_model=FileInfoResponse)
async def convert(
body: MediaConverterParams,
current_user: User = Depends(get_current_user),
storage: StorageService = Depends(get_storage),
) -> FileInfoResponse:
_ = current_user
info = await convert_to_mp4(storage, file_key=body.file_path, out_folder=body.folder)
return FileInfoResponse(
file_path=info.file_path,
file_url=info.file_url,
file_size=info.file_size,
filename=info.filename,
)
@mediafiles_router.get("/mediafiles/", response_model=list[MediaFileRead])
async def list_mediafiles(
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> list[MediaFileRead]:
repo = MediaFileRepository(db)
items = await repo.list_all(requester=current_user)
return [MediaFileRead.model_validate(m) for m in items]
@mediafiles_router.post(
"/mediafiles/", response_model=MediaFileRead, status_code=status.HTTP_201_CREATED
)
async def create_mediafile(
body: MediaFileCreate,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> MediaFileRead:
repo = MediaFileRepository(db)
media_file = await repo.create(requester=current_user, data=body)
return MediaFileRead.model_validate(media_file)
@mediafiles_router.get("/mediafiles/{media_file_id}/", response_model=MediaFileRead)
async def retrieve_mediafile(
media_file_id: uuid.UUID,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> MediaFileRead:
repo = MediaFileRepository(db)
media_file = await repo.get_by_id(media_file_id)
if media_file is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
if not current_user.is_staff and media_file.owner_id != current_user.id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Forbidden")
return MediaFileRead.model_validate(media_file)
@mediafiles_router.patch("/mediafiles/{media_file_id}/", response_model=MediaFileRead)
async def patch_mediafile(
media_file_id: uuid.UUID,
body: MediaFileUpdate,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> MediaFileRead:
repo = MediaFileRepository(db)
media_file = await repo.get_by_id(media_file_id)
if media_file is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
if not current_user.is_staff and media_file.owner_id != current_user.id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Forbidden")
media_file = await repo.update(media_file, body)
return MediaFileRead.model_validate(media_file)
@mediafiles_router.delete("/mediafiles/{media_file_id}/", status_code=status.HTTP_204_NO_CONTENT)
async def delete_mediafile(
media_file_id: uuid.UUID,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> Response:
repo = MediaFileRepository(db)
media_file = await repo.get_by_id(media_file_id)
if media_file is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
if not current_user.is_staff and media_file.owner_id != current_user.id:
raise HTTPException(status_code=status.HTTP_403_FORBIDDEN, detail="Forbidden")
await repo.mark_deleted(media_file)
return Response(status_code=status.HTTP_204_NO_CONTENT)
@artifacts_router.get("/artifacts/", response_model=list[ArtifactMediaFileRead])
async def list_artifact_mediafiles(
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> list[ArtifactMediaFileRead]:
_ = current_user
repo = ArtifactRepository(db)
items = await repo.list_all()
return [ArtifactMediaFileRead.model_validate(a) for a in items]
@artifacts_router.post(
"/artifacts/", response_model=ArtifactMediaFileRead, status_code=status.HTTP_201_CREATED
)
async def create_artifact_mediafile(
body: ArtifactMediaFileCreate,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> ArtifactMediaFileRead:
_ = current_user
repo = ArtifactRepository(db)
artifact = await repo.create(body)
return ArtifactMediaFileRead.model_validate(artifact)
@artifacts_router.get("/artifacts/{artifact_id}/", response_model=ArtifactMediaFileRead)
async def retrieve_artifact_mediafile(
artifact_id: uuid.UUID,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> ArtifactMediaFileRead:
_ = current_user
repo = ArtifactRepository(db)
artifact = await repo.get_by_id(artifact_id)
if artifact is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
return ArtifactMediaFileRead.model_validate(artifact)
@artifacts_router.patch("/artifacts/{artifact_id}/", response_model=ArtifactMediaFileRead)
async def patch_artifact_mediafile(
artifact_id: uuid.UUID,
body: ArtifactMediaFileUpdate,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> ArtifactMediaFileRead:
_ = current_user
repo = ArtifactRepository(db)
artifact = await repo.get_by_id(artifact_id)
if artifact is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
artifact = await repo.update(artifact, body)
return ArtifactMediaFileRead.model_validate(artifact)
@artifacts_router.delete("/artifacts/{artifact_id}/", status_code=status.HTTP_204_NO_CONTENT)
async def delete_artifact_mediafile(
artifact_id: uuid.UUID,
current_user: User = Depends(get_current_user),
db: AsyncSession = Depends(get_db),
) -> Response:
_ = current_user
repo = ArtifactRepository(db)
artifact = await repo.get_by_id(artifact_id)
if artifact is None:
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="Not found")
await repo.mark_deleted(artifact)
return Response(status_code=status.HTTP_204_NO_CONTENT)