from sqlalchemy.orm import Session from db.utils import db_transaction from db.models import File, StagedFileProduct from schemas.file import FileMetadata, FileUploadResponse, GetPreparedFilesResponse, FileDeleteResponse import os from uuid import uuid4 as uuid import logging logger = logging.getLogger(__name__) class FileService: def __init__(self, db: Session): self.db = db def _format_response(self, file: File) -> FileUploadResponse: response = FileUploadResponse( id = file.id, filename = file.filename, type = file.type, source = file.source, status = file.status, service = file.service, file_size_kb = file.filesize_kb, date_created=file.date_created, date_modified=file.date_modified ) return response def upload_file(self, content: bytes, filename: str, metadata: FileMetadata) -> FileUploadResponse: # Save file to database with db_transaction(self.db): file = File( id = str(uuid()), filename = filename, filepath = os.getcwd() + '/temp/' + filename, # TODO: config variable type = metadata.type, source = metadata.source, filesize_kb = round(len(content) / 1024,2), status = 'pending', service = metadata.service ) self.db.add(file) # save file with open(file.filepath, 'wb') as f: f.write(content) response = self._format_response(file) return response def get_file(self, file_id: str) -> File: return self.db.query(File).filter(File.id == file_id).first() def get_prepared_files(self) -> list[FileUploadResponse]: files = self.db.query(File).filter(File.status == 'prepared').all() if len(files) == 0: raise Exception("No prepared files found") result = [self._format_response(file) for file in files] logger.debug(f"Prepared files: {result}") response = GetPreparedFilesResponse(files=result) return response def get_staged_products(self, file_id: str) -> list[StagedFileProduct]: return self.db.query(StagedFileProduct).filter(StagedFileProduct.file_id == file_id).all() def delete_file(self, file_id: str) -> FileDeleteResponse: file = self.get_file(file_id) staged_products = self.get_staged_products(file_id) if file: with db_transaction(self.db): self.db.delete(file) for staged_product in staged_products: self.db.delete(staged_product) return {"id": file_id, "status": "deleted"} else: raise Exception(f"File with id {file_id} not found")