🔧 FIX: Python-Typ-Fehler behoben + force-remove für Deabonidation
docker-build-and-push / build (push) Successful in 17s
docker-build-and-push / build (push) Successful in 17s
This commit is contained in:
+45
-14
@@ -22,7 +22,7 @@ class UnsubscribeRequest(BaseModel):
|
|||||||
@router.get("/projects") # Listet abonierte Projekte!
|
@router.get("/projects") # Listet abonierte Projekte!
|
||||||
async def list_projects():
|
async def list_projects():
|
||||||
"""Listet lokale (abonierte) Projekte an."""
|
"""Listet lokale (abonierte) Projekte an."""
|
||||||
from .main import PROJECTS_DIR, ACCESS_TOKEN
|
from .main import PROJECTS_DIR
|
||||||
|
|
||||||
projects = []
|
projects = []
|
||||||
|
|
||||||
@@ -33,7 +33,7 @@ async def list_projects():
|
|||||||
if project_dir.is_dir() and not project_dir.name.startswith('.'):
|
if project_dir.is_dir() and not project_dir.name.startswith('.'):
|
||||||
has_git = (project_dir / '.git').exists()
|
has_git = (project_dir / '.git').exists()
|
||||||
|
|
||||||
# Prüfe ob dieses Projekt bearbeitet werden darf (chmod-check)
|
# Pruefe ob dieses Projekt bearbeitet werden darf (chmod-check)
|
||||||
can_write = os.access(str(project_dir), os.W_OK) if project_dir.exists() else False
|
can_write = os.access(str(project_dir), os.W_OK) if project_dir.exists() else False
|
||||||
|
|
||||||
all_projects.append({
|
all_projects.append({
|
||||||
@@ -41,10 +41,11 @@ async def list_projects():
|
|||||||
"path": str(project_dir),
|
"path": str(project_dir),
|
||||||
"subscribed": True,
|
"subscribed": True,
|
||||||
"has_git": bool(has_git),
|
"has_git": bool(has_git),
|
||||||
"can_write": can_write #✅ NEU: Zeigt ob User Berechtigung hat!
|
"can_write": can_write
|
||||||
})
|
})
|
||||||
|
|
||||||
projects = all_projects
|
# Sortiere: Projects mit Changes zuerst (kan signale anzeigen)
|
||||||
|
projects = sorted(all_projects, key=lambda x: ("." in x["name"]), reverse=True)
|
||||||
|
|
||||||
return {"projects": projects}
|
return {"projects": projects}
|
||||||
|
|
||||||
@@ -52,7 +53,7 @@ async def list_projects():
|
|||||||
@router.post("/unsubscribe") # Deabonination Endpoint!
|
@router.post("/unsubscribe") # Deabonination Endpoint!
|
||||||
async def unsubscribe_repo(req: UnsubscribeRequest):
|
async def unsubscribe_repo(req: UnsubscribeRequest):
|
||||||
"""Loeschen eines abonnierten Projekts."""
|
"""Loeschen eines abonnierten Projekts."""
|
||||||
from .main import PROJECTS_DIR
|
from .main import PROJECTS_DIR, get_token
|
||||||
|
|
||||||
target_dir = PROJECTS_DIR / req.project_name
|
target_dir = PROJECTS_DIR / req.project_name
|
||||||
|
|
||||||
@@ -61,15 +62,44 @@ async def unsubscribe_repo(req: UnsubscribeRequest):
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
import shutil
|
import shutil
|
||||||
shutil.rmtree(str(target_dir))
|
|
||||||
|
|
||||||
# Erstelle Markierungsdatei um Deabonnierung zu tracken
|
# ✅ SCHRITT 1: Alle Berechtigungen normalisieren damit wir es loeschen können!
|
||||||
marker_file = Path(str(PROJECTS_DIR) / f".deleted_{req.project_name}")
|
set_permissions(str(target_dir))
|
||||||
marker_file.touch()
|
|
||||||
|
# ✅ SCHRITT 2: Mit FORCE-LöSCHUNG entfernen (wegen root-Besitzern)
|
||||||
|
import stat
|
||||||
|
|
||||||
|
def force_remove_dir(dir_path):
|
||||||
|
"""Erzwingt das Loeschen von Verzeichnissen."""
|
||||||
|
for root, dirs, files in os.walk(str(dir_path), topdown=False):
|
||||||
|
for d in dirs:
|
||||||
|
dir_full = Path(root) / d
|
||||||
|
try:
|
||||||
|
dir_full.chmod(0o755 | stat.S_IWUSR | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
for f in files:
|
||||||
|
file_full = Path(root) / f
|
||||||
|
try:
|
||||||
|
# Schreibrechte wiederherstellen
|
||||||
|
os.chmod(str(file_full), 0o666)
|
||||||
|
file_full.unlink()
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
|
|
||||||
|
force_remove_dir(target_dir)
|
||||||
|
shutil.rmtree(str(target_dir))
|
||||||
|
|
||||||
|
return {"success": True, "message": f"{req.project_name} erfolgreich geloescht"}
|
||||||
|
|
||||||
return {"success": True, "message": f"{target_dir.name} erfolgreich geloescht"}
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return {"success": False, "error": str(e)}
|
# Fallback mit rm -rf (Unix-Force)
|
||||||
|
try:
|
||||||
|
import subprocess
|
||||||
|
subprocess.run(["rm", "-rf", str(target_dir)], check=True)
|
||||||
|
return {"success": True, "message": f"{req.project_name} geloescht (force-mode)"}
|
||||||
|
except Exception as e2:
|
||||||
|
return {"success": False, "error": str(e)}
|
||||||
|
|
||||||
|
|
||||||
@router.get("/repos") # Listet Gitea-Repos!
|
@router.get("/repos") # Listet Gitea-Repos!
|
||||||
@@ -85,7 +115,7 @@ async def list_repos():
|
|||||||
headers = {"Authorization": f"token {token}"}
|
headers = {"Authorization": f"token {token}"}
|
||||||
|
|
||||||
async with httpx.AsyncClient() as client:
|
async with httpx.AsyncClient() as client:
|
||||||
resp = await client.get(f"{GITEE_URL}/api/v1/user/repos", headers=headers)
|
resp = await client.get(f"{GITEE_URL.rstrip('/')}/api/v1/user/repos", headers=headers)
|
||||||
return resp.json()
|
return resp.json()
|
||||||
|
|
||||||
|
|
||||||
@@ -106,7 +136,8 @@ async def subscribe_repo(req: SubscribeRequest):
|
|||||||
if not result["success"]:
|
if not result["success"]:
|
||||||
return {"error": result.get("error"), "success": False}
|
return {"error": result.get("error"), "success": False}
|
||||||
|
|
||||||
# ✅ KEINE CHANGES-MARKER NACH DEM KLONEN MEHR!
|
# ✅ BERECHTIGUNGEN SETZEN NACH DEM KLOONEN!
|
||||||
|
set_permissions(str(target_dir))
|
||||||
|
|
||||||
generate_changelog(target_dir)
|
generate_changelog(target_dir)
|
||||||
|
|
||||||
@@ -119,5 +150,5 @@ async def subscribe_repo(req: SubscribeRequest):
|
|||||||
|
|
||||||
|
|
||||||
# Importiere die Funktionen am Ende damit sie verfügbar sind!
|
# Importiere die Funktionen am Ende damit sie verfügbar sind!
|
||||||
from .git_manager import clone_repo
|
from .git_manager import clone_repo, set_permissions
|
||||||
from .changelog_gen import generate_changelog
|
from .changelog_gen import generate_changelog
|
||||||
Reference in New Issue
Block a user