#!/usr/bin/env python3 """Absolute Windows-Pfade in files.stored_path und projects.folder auf Linux umschreiben. Beispiel (Dry-Run): python scripts/pfade_umziehen.py \\ --database-url postgresql:///grotti?host=/var/run/postgresql \\ --from "D:/Projekte/3DP/Slice" --to /var/lib/grotti/slice Ohne --apply nur Anzeige. Mit --apply werden die Zeilen geschrieben. """ from __future__ import annotations import argparse import sys from pathlib import Path ROOT = Path(__file__).resolve().parents[1] if str(ROOT) not in sys.path: sys.path.insert(0, str(ROOT)) def normalize_slash(path: str) -> str: return (path or "").replace("\\", "/").rstrip("/") def rewrite(value: str, old: str, new: str) -> str | None: if not value: return None cur = value.replace("\\", "/") old_n = normalize_slash(old) new_n = normalize_slash(new) # case-insensitive für Windows-Laufwerke if cur.lower().startswith(old_n.lower()): rest = cur[len(old_n) :] if rest and not rest.startswith("/"): rest = "/" + rest return new_n + rest return None def main() -> int: parser = argparse.ArgumentParser(description="Slice-Pfade Windows → Linux umschreiben") parser.add_argument("--database-url", required=True) parser.add_argument("--from", dest="old", required=True, help="Alter Prefix (Windows)") parser.add_argument("--to", dest="new", required=True, help="Neuer Prefix (Linux)") parser.add_argument("--apply", action="store_true", help="Wirklich schreiben") args = parser.parse_args() import psycopg from psycopg.rows import dict_row old = args.old new = args.new changed_files = 0 changed_projects = 0 with psycopg.connect(args.database_url, row_factory=dict_row) as conn: files = conn.execute("SELECT id, stored_path FROM files ORDER BY id").fetchall() for row in files: nxt = rewrite(row["stored_path"] or "", old, new) if nxt is None or nxt == row["stored_path"]: continue changed_files += 1 print("file %s: %s → %s" % (row["id"], row["stored_path"], nxt)) if args.apply: conn.execute("UPDATE files SET stored_path = %s WHERE id = %s", (nxt, row["id"])) projects = conn.execute("SELECT id, folder FROM projects ORDER BY id").fetchall() for row in projects: folder = row["folder"] or "" # folder ist relativ — nur absolute Reste bereinigen nxt = rewrite(folder, old, new) if nxt is None: continue # relativ zum neuen Slice-Root speichern, falls möglich new_n = normalize_slash(new) if nxt.lower().startswith(new_n.lower()): rel = nxt[len(new_n) :].lstrip("/") nxt = rel changed_projects += 1 print("project %s: %s → %s" % (row["id"], folder, nxt)) if args.apply: conn.execute("UPDATE projects SET folder = %s WHERE id = %s", (nxt, row["id"])) if args.apply: conn.commit() print("Geschrieben: %s Dateien, %s Projekte." % (changed_files, changed_projects)) else: print( "Dry-Run: %s Dateien, %s Projekte würden sich ändern. Mit --apply ausführen." % (changed_files, changed_projects) ) return 0 if __name__ == "__main__": raise SystemExit(main())