✨ EXTENDED: Deabonination, Berechtigungen, Sortierung der Projekte
docker-build-and-push / build (push) Successful in 18s
docker-build-and-push / build (push) Successful in 18s
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import subprocess
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
@@ -17,9 +18,40 @@ def clone_repo(repo_url: str, target_dir: Path, token: str = None):
|
||||
text=True
|
||||
)
|
||||
|
||||
# ✅ BERECHTIGUNGEN SETZEN NACH DEM KLOONEN!
|
||||
if result.returncode == 0:
|
||||
try:
|
||||
os.chmod(str(target_dir), 0o755)
|
||||
for root, dirs, files in os.walk(str(target_dir)):
|
||||
for d in dirs:
|
||||
os.chmod(os.path.join(root, d), 0o755)
|
||||
for f in files:
|
||||
os.chmod(os.path.join(root, f), 0o644)
|
||||
except Exception as e:
|
||||
print(f"Warnung bei Berechtigungen: {e}")
|
||||
|
||||
return {"success": result.returncode == 0, "output": result.stdout, "error": result.stderr}
|
||||
|
||||
|
||||
def unsubscribe_repo(target_dir: Path):
|
||||
"""Loescht ein abonniertes Projekt."""
|
||||
import shutil
|
||||
|
||||
if not target_dir.exists():
|
||||
return {"success": False, "error": "Projekt nicht gefunden"}
|
||||
|
||||
try:
|
||||
# ✅ ALLE CHANGES MARKIERUNG LÖSCHEN
|
||||
changes_marker = target_dir / ".gitea-changes.marker"
|
||||
if changes_marker.exists():
|
||||
changes_marker.unlink()
|
||||
|
||||
shutil.rmtree(str(target_dir))
|
||||
return {"success": True, "message": f"{target_dir.name} erfolgreich geloescht"}
|
||||
except Exception as e:
|
||||
return {"success": False, "error": str(e)}
|
||||
|
||||
|
||||
def push_changes(repo_path: Path, message: str = "Update 🧠"):
|
||||
"""Pusht lokale Änderungen ins Repository."""
|
||||
result = subprocess.run(
|
||||
|
||||
+1
-1
@@ -5,7 +5,7 @@ from fastapi.responses import HTMLResponse
|
||||
|
||||
# Umgebungsvariablen mit Fallback
|
||||
GITEE_URL = os.getenv("GITEE_URL", "https://git.carabella.ch/")
|
||||
ACCESS_TOKEN = os.getenv("ACCESS_TOKEN", "") # Leerlassen, falls nicht gesetzt
|
||||
ACCESS_TOKEN = os.getenv("ACCESS_TOKEN", "") # Leerlassen falls nicht gesetzt
|
||||
COMMIT_NAME = os.getenv("COMMIT_NAME", "KI-Sparringpartner")
|
||||
|
||||
# Projekt-Ordner (gemountet im Docker)
|
||||
|
||||
+69
-14
@@ -1,4 +1,5 @@
|
||||
import httpx
|
||||
import os
|
||||
from pathlib import Path
|
||||
from fastapi import APIRouter, HTTPException
|
||||
from pydantic import BaseModel
|
||||
@@ -13,39 +14,90 @@ class SubscribeRequest(BaseModel):
|
||||
token_provided: str | None = None
|
||||
|
||||
|
||||
@router.get("/projects") #✅ NEU: Listet abonierte Projekte!
|
||||
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, get_token, ACCESS_TOKEN
|
||||
from .main import PROJECTS_DIR, ACCESS_TOKEN
|
||||
|
||||
projects = []
|
||||
unsubscribed_markers = set() #Fuer Deabonination Marker
|
||||
|
||||
if PROJECTS_DIR.exists() and str(PROJECTS_DIR).strip():
|
||||
# Suche nach .gitea-unsubscribe marker Dateien (fuer Deabbonation)
|
||||
for marker_file in PROJECTS_DIR.glob(".*.unsubscribe"):
|
||||
project_name = marker_file.stem.replace(".gitea-unsubscribe", "")
|
||||
unsubscribed_markers.add(project_name)
|
||||
|
||||
if PROJECTS_DIR.exists() and str(PROJECTS_DIR).strip():
|
||||
# Sortiere: Abonnierte zuerst, dann alphabtsortiert
|
||||
all_projects = []
|
||||
for project_dir in sorted(PROJECTS_DIR.iterdir()):
|
||||
if project_dir.is_dir() and not project_dir.name.startswith('.'):
|
||||
# Prüfe ob es ein Git-Repo ist
|
||||
has_git = (project_dir / '.git').exists()
|
||||
|
||||
# Prüfe auf unentdeckte Changes
|
||||
changes_marker = project_dir /'.gitea-changes.marker'
|
||||
changes_marker = Path(project_dir / ".gitea-changes.marker")
|
||||
has_changes = changes_marker.exists()
|
||||
|
||||
projects.append({
|
||||
all_projects.append({
|
||||
"name": project_dir.name,
|
||||
"path": str(project_dir),
|
||||
"subscribed": True,
|
||||
"has_git": bool(has_git),
|
||||
"has_undiscovered_changes": has_changes
|
||||
"has_undiscovered_changes": has_changes,
|
||||
"_sort_priority": 0 if not has_changes else 1 # ohne changes = priority höher (kommt zuerst)
|
||||
})
|
||||
|
||||
# Sortiere nach Changes-Status zuerst, dann alphabetisch
|
||||
projects = sorted(all_projects, key=lambda x: (-x["_sort_priority"], x["name"]))
|
||||
|
||||
# Entferne Hilfsfeld für API-Ausgabe
|
||||
for p in projects:
|
||||
del p["_sort_priority"]
|
||||
|
||||
return {"projects": projects}
|
||||
|
||||
|
||||
@router.get("/repos") #✅ VORHANDEN: Listet Gitea-Repos!
|
||||
@router.post("/unsubscribe") #❌ NEU: 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"}
|
||||
|
||||
result = unsubscribe_repo(target_dir)
|
||||
return result
|
||||
|
||||
|
||||
def unsubscribe_repo(target_dir: Path):
|
||||
"""Loeschen eines abonnierten Projekts."""
|
||||
import shutil
|
||||
|
||||
if not target_dir.exists():
|
||||
return {"success": False, "error": "Projekt nicht gefunden"}
|
||||
|
||||
try:
|
||||
shutil.rmtree(str(target_dir))
|
||||
marker_file = Path(str(target_dir) + ".unsubscribe")
|
||||
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 "" #✅ Direkter Zugriff!
|
||||
token = ACCESS_TOKEN or ""
|
||||
|
||||
if not token:
|
||||
return {"error": "Kein Token vorhanden!", "hint": "Setze ACCESS_TOKEN Umgebungsvariable"}
|
||||
@@ -57,7 +109,7 @@ async def list_repos():
|
||||
return resp.json()
|
||||
|
||||
|
||||
@router.post("/subscribe") #✅ VORHANDEN: Clont Repo!
|
||||
@router.post("/subscribe") # Klont Repo!
|
||||
async def subscribe_repo(req: SubscribeRequest):
|
||||
"""Abonniert und klont ein Repository."""
|
||||
from .main import ACCESS_TOKEN
|
||||
@@ -74,11 +126,14 @@ async def subscribe_repo(req: SubscribeRequest):
|
||||
if not result["success"]:
|
||||
return {"error": result.get("error"), "success": False}
|
||||
|
||||
# Marker für Changes erstellen
|
||||
(target_dir / ".gitea-changes.marker").touch()
|
||||
|
||||
generate_changelog(target_dir)
|
||||
|
||||
# Loesche Deabonination-Marker wenn Projekt wieder abonniert wurde
|
||||
marker_file = Path(str(target_dir) + ".unsubscribe")
|
||||
if marker_file.exists():
|
||||
marker_file.unlink()
|
||||
|
||||
return {
|
||||
"message": f"✅ {req.target_name} geklont!",
|
||||
"path": str(target_dir),
|
||||
@@ -87,6 +142,6 @@ async def subscribe_repo(req: SubscribeRequest):
|
||||
}
|
||||
|
||||
|
||||
# Importiere hier damit die Funktionen verfügbar sind!
|
||||
# Importiere die Funktionen am Ende damit sie verfügbar sind!
|
||||
from .git_manager import clone_repo
|
||||
from .changelog_gen import generate_changelog
|
||||
Reference in New Issue
Block a user