import os import io from datetime import datetime from typing import List, Type from flask import jsonify from database import db from models import File, Organization, User from utils import get_hash, Perm class FileService: def __init__(self): self.current_requests = {} def create_file(self, session_token: str, org: Organization, user: User, file_name: str, key: str, alg: str) -> File: from services import SessionService file = File( file_handle = None, document_handle = get_hash(file_name), name = file_name, created_at = int(datetime.now().timestamp()), acl = { "manager": Perm.get_int([ Perm.DOC_ACL, Perm.DOC_READ, Perm.DOC_DELETE, ]) } | {role: Perm.get_int([ Perm.DOC_ACL, Perm.DOC_READ, Perm.DOC_DELETE ]) for role in SessionService.list_roles(SessionService.get_session(session_token))}, key = key, alg = alg, org_id = org.id, creator_id = user.id, deleter_id = None, org = org, creator = user ) db.add(file) db.commit() db.refresh(file) self.current_requests[session_token] = file.id return file def write_file(self, session_token: str, file_handle: str, file_data: bytes) -> File | tuple: if session_token not in self.current_requests: return jsonify({"error": "No file upload request found"}), 400 file = db.query(File).filter(File.id == self.current_requests[session_token]).first() file_path = os.path.join(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "repository"), file.org.name, file.document_handle) with open(file_path, "wb") as f: f.write(file_data) file.file_handle = file_handle db.commit() db.refresh(file) del self.current_requests[session_token] return file @staticmethod def get_file(file_id: int) -> File | None: return db.query(File).filter(File.id == file_id).first() @staticmethod def get_file_by_document_handle(document_handle: str) -> File | None: return db.query(File).filter(File.document_handle == document_handle).first() @staticmethod def get_file_by_file_handle(file_handle: str) -> File | None: return db.query(File).filter(File.file_handle == file_handle).first() @staticmethod def get_file_content(file: File) -> io.BytesIO: file_path = os.path.join(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "repository"), file.org.name, file.document_handle) with open(file_path, "rb") as f: return io.BytesIO(f.read()) @staticmethod def list_files() -> list[Type[File]]: return db.query(File).all() @staticmethod def list_files_in_org(org: Organization) -> list[Type[File]]: return db.query(File).filter(File.org_id == org.id).all() @staticmethod def delete_file(file: File, deleter_id: int) -> File: file_path = os.path.join(os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), "repository"), file.org.name, file.document_handle) os.remove(file_path) file.file_handle = None file.deleter_id = deleter_id db.commit() db.refresh(file) return file