"""Schlanke Gitea-API-Helfer (stdlib only). - PR-Diff holen - Kommentare IDEMPOTENT posten: ein versteckter HTML-Marker identifiziert den Bot-Kommentar; existiert er schon, wird er editiert statt neu angelegt (kein Zuspammen bei jedem Push). Env-Vars: GITEA_API Basis-URL der API, Default https://git.eulernest.eu/api/v1 GITEA_TOKEN Token fürs Kommentieren (Actions-Auto-Token ODER PAT). Fallback: GITEA_BOT_TOKEN. """ import json import os import urllib.error import urllib.request _BASE = os.environ.get("GITEA_API", "https://git.eulernest.eu/api/v1").rstrip("/") _TOKEN = os.environ.get("GITEA_TOKEN") or os.environ.get("GITEA_BOT_TOKEN", "") def _request(method: str, path: str, *, data=None, raw: bool = False): url = f"{_BASE}{path}" headers = {} if _TOKEN: headers["Authorization"] = f"token {_TOKEN}" body = None if data is not None: body = json.dumps(data).encode("utf-8") headers["Content-Type"] = "application/json" req = urllib.request.Request(url, data=body, headers=headers, method=method) try: with urllib.request.urlopen(req, timeout=60) as resp: content = resp.read().decode("utf-8", "replace") if raw: return content return json.loads(content) if content.strip() else None except urllib.error.HTTPError as exc: detail = exc.read().decode("utf-8", "replace") raise SystemExit(f"[gitea] {method} {path} -> HTTP {exc.code}: {detail[:400]}") except urllib.error.URLError as exc: raise SystemExit(f"[gitea] {method} {path} fehlgeschlagen: {exc.reason}") def get_pr_diff(owner: str, repo: str, index: int) -> str: """Unified Diff eines PRs (Gitea unterstützt den .diff-Suffix).""" return _request("GET", f"/repos/{owner}/{repo}/pulls/{index}.diff", raw=True) def upsert_comment(owner: str, repo: str, index: int, marker: str, body: str) -> int: """Legt einen Kommentar an ODER editiert den vorhandenen mit gleichem Marker. PR-Kommentare sind in Gitea Issue-Kommentare (gleicher Endpunkt). """ full = f"{body}\n\n{marker}" existing = _request("GET", f"/repos/{owner}/{repo}/issues/{index}/comments") or [] for comment in existing: if marker in (comment.get("body") or ""): _request( "PATCH", f"/repos/{owner}/{repo}/issues/comments/{comment['id']}", data={"body": full}, ) return comment["id"] created = _request( "POST", f"/repos/{owner}/{repo}/issues/{index}/comments", data={"body": full}, ) return created["id"]