table_fix_and_folder_management

This commit is contained in:
Mateusz Gruszczyński
2026-06-12 23:20:42 +02:00
parent 90989e81ad
commit a2cdc203c2
8 changed files with 344 additions and 22 deletions
+54
View File
@@ -78,6 +78,60 @@ def browse_path(profile: dict, path: str | None = None) -> dict:
"used_percent": disk_percent,
}
def _safe_directory_name(name: str) -> str:
value = str(name or "").strip()
if not value or value in {".", ".."} or "/" in value or "\x00" in value:
raise ValueError("Invalid directory name")
return value
def create_directory(profile: dict, parent: str, name: str) -> dict:
"""Create a remote directory without changing existing path-picker behavior."""
# Note: Directory creation is remote-side, so Add/Move sees the same filesystem as rTorrent.
c = client_for(profile)
clean_parent = _remote_clean_path(parent or default_download_path(profile))
clean_name = _safe_directory_name(name)
target = _remote_join(clean_parent, clean_name)
script = (
'parent=$1; target=$2; '
'if [ ! -d "$parent" ]; then printf "ERR\tParent directory does not exist"; exit 0; fi; '
'if [ -e "$target" ] || [ -L "$target" ]; then printf "ERR\tDirectory already exists"; exit 0; fi; '
'mkdir -- "$target" 2>/dev/null || { printf "ERR\tCannot create directory"; exit 0; }; '
'printf "OK\t%s" "$target"'
)
output = str(_rt_execute(c, "execute.capture", "sh", "-c", script, "pytorrent-mkdir", clean_parent, target) or "").strip()
if not output.startswith("OK\t"):
raise RuntimeError(output.split("\t", 1)[1] if "\t" in output else "Cannot create directory")
return {"path": output.split("\t", 1)[1], "name": clean_name}
def rename_empty_directory(profile: dict, path: str, new_name: str) -> dict:
"""Rename an empty remote directory in place."""
# Note: Rename is intentionally limited to empty folders to avoid invalidating active torrent paths.
c = client_for(profile)
source = _remote_clean_path(path or "")
clean_name = _safe_directory_name(new_name)
if not source or source == "/":
raise ValueError("Cannot rename this directory")
parent = posixpath.dirname(source.rstrip("/")) or "/"
target = _remote_join(parent, clean_name)
if source == target:
return {"path": target, "name": clean_name, "parent": parent}
script = (
'src=$1; dst=$2; '
'if [ ! -d "$src" ]; then printf "ERR\tDirectory does not exist"; exit 0; fi; '
'if [ -e "$dst" ] || [ -L "$dst" ]; then printf "ERR\tTarget directory already exists"; exit 0; fi; '
'if [ -n "$(find "$src" -mindepth 1 -maxdepth 1 -print -quit 2>/dev/null)" ]; then printf "ERR\tOnly empty directories can be renamed"; exit 0; fi; '
'mv -- "$src" "$dst" 2>/dev/null || { printf "ERR\tCannot rename directory"; exit 0; }; '
'printf "OK\t%s" "$dst"'
)
output = str(_rt_execute(c, "execute.capture", "sh", "-c", script, "pytorrent-rename-dir", source, target) or "").strip()
if not output.startswith("OK\t"):
raise RuntimeError(output.split("\t", 1)[1] if "\t" in output else "Cannot rename directory")
return {"path": output.split("\t", 1)[1], "name": clean_name, "parent": parent}
def remote_public_ip(profile: dict, force: bool = False) -> str:
profile_id = int(profile.get("id") or 0)
now = time.monotonic()