# # Copyright (c) Daniel Sheffield 2023 # All rights reserved # # THIS SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY from hashlib import blake2b from io import BufferedRandom import os from uuid import uuid4 from .hash_util import DIGEST_SIZE_BYTES, blake, bytes_to_base32 def save(content: bytes, root='app/rest/static') -> str: _bytes = blake(content, person='clip'.encode('utf-8')) _b32 = bytes_to_base32(_bytes) directory = f'{root}/{_b32}' try: os.mkdir(directory, mode=0o700, dir_fd=None) except FileExistsError: pass fd = os.open(f'{directory}/{_b32}.file', os.O_WRONLY | os.O_TRUNC | os.O_CREAT, 0o600) with open(fd, "wb") as f: f.write(content) return _b32 def save_upload(content: BufferedRandom, root='app/rest/static') -> str: tmpdir = '/tmp/upload' try: os.mkdir(tmpdir, mode=0o700, dir_fd=None) except FileExistsError: pass unique = uuid4() fd = os.open(f'{tmpdir}/{unique.hex}', os.O_WRONLY | os.O_TRUNC | os.O_CREAT, 0o600) with open(fd, "wb") as f: while content.peek(1): seg = content.read(1024) f.write(seg) fd = os.open(f'{tmpdir}/{unique.hex}', os.O_RDONLY, 0o600) with open(fd, "rb") as f: f.seek(0) _blake = blake2b(usedforsecurity=False, digest_size=DIGEST_SIZE_BYTES, person='upload'.encode('utf-8')) while f.peek(1): _blake.update(f.read(1024)) _bytes = _blake.digest() _b32 = bytes_to_base32(_bytes) directory = f'{root}/{_b32}' try: os.mkdir(directory, mode=0o700, dir_fd=None) except FileExistsError: pass os.replace(f'{tmpdir}/{unique.hex}', f'{directory}/{_b32}.file') return _b32