save.py 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859
  1. #
  2. # Copyright (c) Daniel Sheffield 2023
  3. # All rights reserved
  4. #
  5. # THIS SOFTWARE IS PROVIDED AS IS WITHOUT WARRANTY
  6. from hashlib import blake2b
  7. from io import BufferedRandom
  8. import os
  9. from uuid import uuid4
  10. from .hash_util import DIGEST_SIZE_BYTES, blake, bytes_to_base32
  11. def save(content: bytes, root='app/rest/static') -> str:
  12. _bytes = blake(content, person='clip'.encode('utf-8'))
  13. _b32 = bytes_to_base32(_bytes)
  14. directory = f'{root}/{_b32}'
  15. try:
  16. os.mkdir(directory, mode=0o700, dir_fd=None)
  17. except FileExistsError:
  18. pass
  19. fd = os.open(f'{directory}/{_b32}.file', os.O_WRONLY | os.O_TRUNC | os.O_CREAT, 0o600)
  20. with open(fd, "wb") as f:
  21. f.write(content)
  22. return _b32
  23. def save_upload(content: BufferedRandom, root='app/rest/static') -> str:
  24. tmpdir = '/tmp/upload'
  25. try:
  26. os.mkdir(tmpdir, mode=0o700, dir_fd=None)
  27. except FileExistsError:
  28. pass
  29. unique = uuid4()
  30. fd = os.open(f'{tmpdir}/{unique.hex}', os.O_WRONLY | os.O_TRUNC | os.O_CREAT, 0o600)
  31. with open(fd, "wb") as f:
  32. while content.peek(1):
  33. seg = content.read(1024)
  34. f.write(seg)
  35. fd = os.open(f'{tmpdir}/{unique.hex}', os.O_RDONLY, 0o600)
  36. with open(fd, "rb") as f:
  37. f.seek(0)
  38. _blake = blake2b(usedforsecurity=False, digest_size=DIGEST_SIZE_BYTES, person='upload'.encode('utf-8'))
  39. while f.peek(1):
  40. _blake.update(f.read(1024))
  41. _bytes = _blake.digest()
  42. _b32 = bytes_to_base32(_bytes)
  43. directory = f'{root}/{_b32}'
  44. try:
  45. os.mkdir(directory, mode=0o700, dir_fd=None)
  46. except FileExistsError:
  47. pass
  48. os.replace(f'{tmpdir}/{unique.hex}', f'{directory}/{_b32}.file')
  49. return _b32