sio-2425/delivery2/server/services/files.py

102 lines
3.5 KiB
Python

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