99 lines
3.4 KiB
Python
Executable File
99 lines
3.4 KiB
Python
Executable File
from typing import Optional
|
|
|
|
from fastapi import (
|
|
APIRouter,
|
|
Depends,
|
|
File,
|
|
Form,
|
|
HTTPException,
|
|
Response,
|
|
UploadFile,
|
|
status,
|
|
)
|
|
from fastapi.responses import StreamingResponse
|
|
|
|
from app.api.dependencies.auth import get_current_active_user
|
|
from app.api.dependencies.factory import Factory
|
|
from app.core.data_types import UUID7Field
|
|
from app.core.params import CommonParams
|
|
from app.models import UserModel
|
|
from app.schemas.base import PaginatedResponse
|
|
from app.schemas.file_schema import FileSchema
|
|
from app.services import FileService
|
|
|
|
router = APIRouter()
|
|
|
|
|
|
@router.get("/files", response_model=PaginatedResponse[FileSchema], dependencies=[Depends(get_current_active_user)])
|
|
async def get_files(params: CommonParams = Depends(), service: FileService = Depends(Factory().get_file_service)):
|
|
filter = params.filter
|
|
sort = params.sort
|
|
search = params.search
|
|
group_by = params.group_by
|
|
limit = params.limit
|
|
offset = params.offset
|
|
files, total = await service.find_all(filter, sort, search, group_by, limit, offset)
|
|
|
|
return PaginatedResponse(
|
|
items=[FileSchema.model_validate(file) for file in files],
|
|
total=total,
|
|
limit=limit,
|
|
offset=offset,
|
|
has_more=total > (offset + limit),
|
|
)
|
|
|
|
|
|
@router.get("/files/{id}", response_model=FileSchema)
|
|
async def get_file(id: UUID7Field, service: FileService = Depends(Factory().get_file_service)):
|
|
file = await service.find_by_id(id)
|
|
return file
|
|
|
|
|
|
@router.post("/files", response_model=FileSchema, status_code=status.HTTP_201_CREATED)
|
|
async def upload_file(
|
|
file: UploadFile = File(...),
|
|
description: Optional[str] = Form(None),
|
|
current_user: UserModel = Depends(get_current_active_user),
|
|
service: FileService = Depends(Factory().get_file_service),
|
|
):
|
|
result = await service.upload_file(file=file, description=description, user_id=current_user.id)
|
|
return result
|
|
|
|
|
|
@router.get("/files/{file_id}", response_model=FileSchema, summary="Dapatkan metadata file")
|
|
async def get_file_info(file_id: UUID7Field, service: FileService = Depends(Factory().get_file_service)):
|
|
file = await service.find_by_id(file_id)
|
|
if not file:
|
|
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND, detail="File tidak ditemukan")
|
|
return file
|
|
|
|
|
|
@router.get("/files/{file_id}/download", summary="Download file")
|
|
async def download_file(file_id: UUID7Field, service: FileService = Depends(Factory().get_file_service)):
|
|
file_content, object_info, file_model = await service.get_file_content(file_id)
|
|
|
|
async def iterfile():
|
|
try:
|
|
chunk = await file_content.content.read(8192)
|
|
while chunk:
|
|
yield chunk
|
|
chunk = await file_content.content.read(8192)
|
|
finally:
|
|
await file_content.release()
|
|
|
|
return StreamingResponse(
|
|
iterfile(),
|
|
media_type=file_model.content_type,
|
|
headers={"Content-Disposition": f'attachment; filename="{file_model.filename}"'},
|
|
)
|
|
|
|
|
|
@router.delete("/files/{file_id}", status_code=status.HTTP_204_NO_CONTENT, summary="Hapus file")
|
|
async def delete_file(
|
|
file_id: UUID7Field,
|
|
current_user: UserModel = Depends(get_current_active_user),
|
|
service: FileService = Depends(Factory().get_file_service),
|
|
):
|
|
await service.delete_file_with_content(file_id, str(current_user.id))
|
|
return Response(status_code=status.HTTP_204_NO_CONTENT)
|