75 lines
2.8 KiB
Python
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") |