import httpx import os from pathlib import Path from fastapi import APIRouter, HTTPException from pydantic import BaseModel router = APIRouter() class SubscribeRequest(BaseModel): """Schema für Subscription Request""" repo_url: str target_name: str = "imported-repo" token_provided: str | None = None class UnsubscribeRequest(BaseModel): """Schema fuer Deabonination""" project_name: str @router.get("/projects") # Listet abonierte Projekte! async def list_projects(): """Listet lokale (abonierte) Projekte an.""" from .main import PROJECTS_DIR, ACCESS_TOKEN projects = [] if PROJECTS_DIR.exists() and str(PROJECTS_DIR).strip(): # Sortiere nach dem Status der Changes zuerst all_projects = [] for project_dir in sorted(PROJECTS_DIR.iterdir()): if project_dir.is_dir() and not project_dir.name.startswith('.'): has_git = (project_dir / '.git').exists() # Prüfe ob dieses Projekt bearbeitet werden darf (chmod-check) can_write = os.access(str(project_dir), os.W_OK) if project_dir.exists() else False all_projects.append({ "name": project_dir.name, "path": str(project_dir), "subscribed": True, "has_git": bool(has_git), "can_write": can_write #✅ NEU: Zeigt ob User Berechtigung hat! }) projects = all_projects return {"projects": projects} @router.post("/unsubscribe") # Deabonination Endpoint! async def unsubscribe_repo(req: UnsubscribeRequest): """Loeschen eines abonnierten Projekts.""" from .main import PROJECTS_DIR target_dir = PROJECTS_DIR / req.project_name if not target_dir.exists(): return {"success": False, "error": f"Projekt '{req.project_name}' nicht gefunden"} try: import shutil shutil.rmtree(str(target_dir)) # Erstelle Markierungsdatei um Deabonnierung zu tracken marker_file = Path(str(PROJECTS_DIR) / f".deleted_{req.project_name}") marker_file.touch() return {"success": True, "message": f"{target_dir.name} erfolgreich geloescht"} except Exception as e: return {"success": False, "error": str(e)} @router.get("/repos") # Listet Gitea-Repos! async def list_repos(): """Listet Repositories von Gitea auf.""" from .main import GITEE_URL, ACCESS_TOKEN token = ACCESS_TOKEN or "" if not token: return {"error": "Kein Token vorhanden!", "hint": "Setze ACCESS_TOKEN Umgebungsvariable"} headers = {"Authorization": f"token {token}"} async with httpx.AsyncClient() as client: resp = await client.get(f"{GITEE_URL}/api/v1/user/repos", headers=headers) return resp.json() @router.post("/subscribe") # Klont Repo! async def subscribe_repo(req: SubscribeRequest): """Abonniert und klont ein Repository.""" from .main import ACCESS_TOKEN effective_token = req.token_provided or ACCESS_TOKEN or "" if not effective_token: raise HTTPException(status_code=401, detail="Kein TOKEN vorhanden!") target_dir = Path("/projects") / req.target_name result = clone_repo(req.repo_url, target_dir, token=effective_token) if not result["success"]: return {"error": result.get("error"), "success": False} # ✅ KEINE CHANGES-MARKER NACH DEM KLONEN MEHR! generate_changelog(target_dir) return { "message": f"✅ {req.target_name} geklont!", "path": str(target_dir), "success": True, "can_write": os.access(str(target_dir), os.W_OK) if target_dir.exists() else False } # Importiere die Funktionen am Ende damit sie verfügbar sind! from .git_manager import clone_repo from .changelog_gen import generate_changelog