aboutsummaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/src/meshbay_node/transport/webrtc/disk.py
diff options
context:
space:
mode:
authorChristophe Besson <cbesson@gmail.com>2026-09-24 09:03:06 +0200
committerChristophe Besson <cbesson@gmail.com>2026-09-24 16:45:38 +0200
commitffdb70784f11de0df8162cea5e9f5abfac91ea96 (patch)
tree70d7577aaef5e4b5b493444bb8d1d81d8e416ce0 /packages/meshbay-node/src/meshbay_node/transport/webrtc/disk.py
parentfd620dc2b61b5ef6fe72581321f488ebf8faf746 (diff)
downloadmeshbay-ffdb70784f11de0df8162cea5e9f5abfac91ea96.tar.gz
refactor(node): move file browsing and folder/file ops out of webrtc_server
FilesMixin in transport/webrtc/files.py; the blocking disk helpers join _locate in webrtc/disk.py, and the lease states go to webrtc/limits.py. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.py53
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)