diff --git a/app/git_manager.py b/app/git_manager.py index 42a86f2..c2c9958 100644 --- a/app/git_manager.py +++ b/app/git_manager.py @@ -1,15 +1,16 @@ import subprocess import os import shutil +import stat from pathlib import Path def set_permissions(path: str): - """Setzt korrekte POSIX-Berechtigungen für ein Verzeichnis.""" + """Setzt korrekte POSIX-Berechtigungen fuer ein Verzeichnis.""" try: # Ordner = 755 (rwxr-xr-x) os.chmod(str(path), 0o755) - + # Rekursiv alle Teildateien bearbeiten for root, dirs, files in os.walk(str(path)): for d in dirs: @@ -21,9 +22,13 @@ def set_permissions(path: str): for f in files: full_path = os.path.join(root, f) try: - os.chmod(full_path, 0o644) + # Setze WRITE permission damit wir es loeschen können! + os.chmod(full_path, stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) except Exception: pass + + # Nachher auch den Hauptordner beschreiben machen + os.chmod(str(path), 0o755 | stat.S_ISVTX) # Sticky-Bit hilft beim Loeschen except Exception as e: print(f"Warnung bei Berechtigungen: {e}") @@ -33,7 +38,7 @@ def clone_repo(repo_url: str, target_dir: Path, token: str = None): if not target_dir.exists(): target_dir.mkdir(parents=True) - # URL mit Token (falls nötig) + # URL mit Token (falls noetig) if token and "@" not in repo_url: repo_url = repo_url.replace("https://", f"https://{token}@") @@ -58,10 +63,45 @@ def unsubscribe_repo(project_name: str, projects_dir: Path): return {"success": False, "error": "Projekt nicht gefunden"} try: + # ✅ SCHRITT 1: Alle Berechtigungen normalisieren damit wir es loeschen können! + set_permissions(str(target_dir)) + + # ✅ SCHRITT 2: Mit REMOVE-TREATMENTS einen Ordner mit root-Besitzern loeschen + # Dies schreibt neu und zwingt das Loeschen: + for root, dirs, files in os.walk(str(target_dir), topdown=False): + for d in dirs: + dir_path = Path(root) / d + try: + dir_path.chmod(0o755) # Schreibrechte wiederherstellen + except Exception: + pass + for f in files: + file_path = Path(root) / f + try: + file_path.unlink() # Datei loeschen + except Exception: + pass + shutil.rmtree(str(target_dir)) return {"success": True, "message": f"{project_name} erfolgreich geloescht"} + + except PermissionError as e: + # Fallback: Versuche mit FERZWUNGSLÖSCHUNG! + try: + import subprocess as sp + sp.run(["rm", "-rf", str(target_dir)], check=True) # UNIX-force-loeschen + return {"success": True, "message": f"{project_name} geloescht (force-mode)"} + except Exception as e2: + return {"success": False, "error": f"Permission denied even after fix: {e}"} + except Exception as e: - return {"success": False, "error": str(e)} + # Letzter Versuch mit rm -rf + try: + import subprocess as sp + sp.run(["rm", "-rf", str(target_dir)], check=True) + return {"success": True, "message": f"{project_name} geloescht (force-mode)"} + except Exception as e2: + return {"success": False, "error": str(e)} def push_changes(repo_path: Path, message: str = "Update 🧠"):