# Importações de bibliotecas padrão from typing import Annotated # Importações de bibliotecas de terceiros from fastapi import APIRouter, Depends, UploadFile, File, HTTPException from starlette import status # Importações do seu próprio projeto from app.routers.dependencies import get_repository from app.s3.RepositoryS3 import RepositoryS3 from app.rbac.permissions import verify_permissions from app.database.models import RbacUser, S3Arquivo from app.s3 import schema_s3 db_model = S3Arquivo rota_prefix = "/api/s3/arquivos" rota_tags = "S3 Arquivos" repository_base = Annotated[ RepositoryS3[db_model], Depends(get_repository(db_model, RepositoryS3)), ] router = APIRouter( prefix=rota_prefix, tags=[rota_tags], responses={404: {"description": "Not found"}}, ) @router.post("/upload", status_code=status.HTTP_200_OK, response_model=schema_s3.ArquivoRetorno) async def upload_to_s3( repository: repository_base, file: UploadFile = File(...), # repository: S3Repository[db_model] = Depends(get_repository_simple_table(S3Arquivo)), user: RbacUser = Depends(verify_permissions([1, 2, 33, 401]))): """ Faz upload de uma imagem para o bucket restrito e registra no banco de dados. """ try: # Chamar a função do repositório para realizar o upload e salvar no banco resultado = await repository.upload_to_s3( conteudo=file.file, nome_original=file.filename, tipo_conteudo=file.content_type, inquilino=user.fk_inquilino_uuid ) return resultado except HTTPException as e: raise e # Relevanta a exceção HTTP já tratada no repositório except Exception as e: raise HTTPException(status_code=500, detail=f"Erro inesperado: {str(e)}") @router.post("/url/") async def get_presigned_url( request: schema_s3.FileNameRequest, repository: repository_base, user: RbacUser = Depends(verify_permissions([1, 2, 33, 401])), # Permissões necessárias ): """ Gera uma URL pré-assinada para download do arquivo, com o nome original configurado. """ try: # Chamar a função do repositório para gerar a URL pré-assinada presigned_url = await repository.get_presigned_url( uuid=request.uuid, inquilino=user.fk_inquilino_uuid ) return {"url": presigned_url} except HTTPException as e: raise e # Relança exceções HTTP já tratadas no repositório except Exception as e: raise HTTPException(status_code=500, detail=f"Erro inesperado: {str(e)}") @router.post("/url/simple/") async def generate_presigned_url( request: schema_s3.FileNameRequest, repository: repository_base, user: RbacUser = Depends(verify_permissions([1, 2, 33, 401])), # Permissões necessárias ): """ Gera uma URL pré-assinada para acessar o arquivo no MinIO (sem download automático). """ try: # Chamar a função do repositório para gerar a URL pré-assinada presigned_url = await repository.generate_presigned_url( uuid=request.uuid, inquilino=user.fk_inquilino_uuid # Passa diretamente o UUID do inquilino ) return {"url": presigned_url} except HTTPException as e: raise e # Relança exceções HTTP já tratadas no repositório except Exception as e: raise HTTPException(status_code=500, detail=f"Erro inesperado: {str(e)}") @router.post("/") async def get_file( request: schema_s3.FileNameRequest, repository: repository_base, user: RbacUser = Depends(verify_permissions([1, 2, 33, 401])), # Permissões necessárias ): """ Retorna uma imagem específica para download. O usuário precisa estar autenticado para acessar. """ try: # Chamar a função do repositório para obter a imagem como streaming response = await repository.get_file( uuid=request.uuid, inquilino=user.fk_inquilino_uuid # Passa diretamente o UUID do inquilino ) return response except HTTPException as e: raise e # Relança exceções HTTP já tratadas no repositório except Exception as e: raise HTTPException(status_code=500, detail=f"Erro inesperado: {str(e)}") @router.post("/inline/") async def get_file_inline( request: schema_s3.FileNameRequest, repository: repository_base, user: RbacUser = Depends(verify_permissions([1, 2, 33, 401])), # Permissões necessárias ): """ Retorna uma imagem ou arquivo específico para exibição inline (sem download automático). O usuário precisa estar autenticado para acessar. """ try: # Chamar a função do repositório para obter o streaming da imagem response = await repository.get_file_inline( uuid=request.uuid, inquilino=user.fk_inquilino_uuid # Passa diretamente o UUID do inquilino ) return response except HTTPException as e: raise e # Relança exceções HTTP já tratadas no repositório except Exception as e: raise HTTPException(status_code=500, detail=f"Erro inesperado: {str(e)}") @router.delete("/") async def delete_file( request: schema_s3.FileNameRequest, repository: repository_base, user: RbacUser = Depends(verify_permissions([1, 2, 33, 401])), # Permissões necessárias ): """ Exclui um arquivo do S3 e remove seu registro do banco de dados. """ try: # Chamar a função do repositório para excluir o arquivo result = await repository.delete_file_from_s3( uuid=request.uuid, inquilino=user.fk_inquilino_uuid # Passa diretamente o UUID do inquilino ) return result except HTTPException as e: raise e # Relança exceções HTTP já tratadas no repositório except Exception as e: raise HTTPException(status_code=500, detail=f"Erro inesperado: {str(e)}")