giga_tcg/services/file.py

75 lines
2.8 KiB
Python

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")