99 lines
3.4 KiB
Python
99 lines
3.4 KiB
Python
#!/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())
|