diff options
Diffstat (limited to 'packages/meshbay-node/src/meshbay_node/transport/webrtc/disk.py')
| -rw-r--r-- | packages/meshbay-node/src/meshbay_node/transport/webrtc/disk.py | 53 |
1 files changed, 53 insertions, 0 deletions
diff --git a/packages/meshbay-node/src/meshbay_node/transport/webrtc/disk.py b/packages/meshbay-node/src/meshbay_node/transport/webrtc/disk.py index fd3184c..bc8d33f 100644 --- a/packages/meshbay-node/src/meshbay_node/transport/webrtc/disk.py +++ b/packages/meshbay-node/src/meshbay_node/transport/webrtc/disk.py @@ -2,7 +2,10 @@ from pathlib import Path +from meshbay_common.protocol import file_chunk_wire + from meshbay_node.roots import ROOT_NOT_SERVED, RootSet, entry_abs_path +from meshbay_node.transport.webrtc.limits import CHUNK_SIZE def _locate(roots: RootSet, entry) -> tuple[Path | None, str | None]: @@ -21,3 +24,53 @@ def _locate(roots: RootSet, entry) -> tuple[Path | None, str | None]: if not path.exists(): return None, "File not on disk" return path, None + + +def _mkdir_if_absent(target: Path) -> str | None: + """ + Create a directory unless it is already there, or say why not. + + Both in one call, not a check awaited and then an act: the disk thread is + one worker, so nothing can slip between them. Split across two awaits, two + members creating the same name would both find nothing there and the second + `mkdir` would raise where a refusal was meant. Blocking; called through + `off_disk`. + """ + if target.exists(): + return "Already exists" + target.mkdir(parents=False) + return None + + +def _is_empty_dir(target: Path) -> bool: + """Blocking; called through `off_disk`.""" + return not any(target.iterdir()) + + +def _rmdir_if_empty(target: Path) -> bool: + """ + Remove a directory if nothing is in it. False if something is. + + The emptiness test and the removal are one call for the reason the caller + re-tests at all: the first test happened before a round trip to the + operator's browser, and a file can land in between. Two awaits here would + reopen the same window one size smaller. Blocking; called through `off_disk`. + """ + if any(target.iterdir()): + return False + target.rmdir() + return True + + +def _read_and_encrypt( + gek: bytes, + file_path: Path, + chunk_index: int, + file_hash: bytes, + file_id: str = "", +) -> dict: + """Read one chunk off disk and encrypt it. Blocking; called through `off_disk`.""" + with open(file_path, "rb") as f: + f.seek(chunk_index * CHUNK_SIZE) + plaintext = f.read(CHUNK_SIZE) + return file_chunk_wire(gek, plaintext, chunk_index, file_hash, file_id) |