Files
tg-admin-bot/services/gitea.py
2026-02-08 02:41:50 +03:00

89 lines
2.8 KiB
Python
Raw Permalink Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import json
import ssl
from typing import Any
from urllib.error import HTTPError, URLError
from urllib.request import Request, urlopen
def _request(url: str, headers: dict[str, str], verify_tls: bool) -> tuple[int, str]:
context = None
if not verify_tls:
context = ssl._create_unverified_context() # nosec - config-controlled
req = Request(url, headers=headers)
try:
with urlopen(req, timeout=10, context=context) as resp:
body = resp.read().decode("utf-8")
return int(resp.status), body
except HTTPError as e:
try:
body = e.read().decode("utf-8")
except Exception:
body = ""
return int(e.code), body
except URLError as e:
raise RuntimeError(str(e.reason)) from e
def _api_base(cfg: dict[str, Any]) -> str:
g_cfg = cfg.get("gitea", {})
base = (g_cfg.get("base_url") or "").rstrip("/")
return base
def get_gitea_health(cfg: dict[str, Any]) -> str:
g_cfg = cfg.get("gitea", {})
base = _api_base(cfg)
verify_tls = g_cfg.get("verify_tls", True)
if not base:
return "⚠️ Gitea base_url not configured"
token = (g_cfg.get("token") or "").strip()
headers = {"User-Agent": "tg-admin-bot"}
if token:
headers["Authorization"] = f"token {token}"
lines = ["🍵 Gitea\n"]
health_paths = ["/api/healthz", "/api/v1/healthz"]
health_status = None
health_payload = None
for path in health_paths:
status, body = _request(f"{base}{path}", headers, verify_tls)
if status == 200:
health_status = (status, path)
try:
health_payload = json.loads(body)
except json.JSONDecodeError:
health_payload = None
break
if status not in (404, 405):
health_status = (status, path)
break
if health_status:
status, path = health_status
icon = "🟢" if status == 200 else "🔴"
if status == 200 and isinstance(health_payload, dict):
state = health_payload.get("status") or "ok"
checks = health_payload.get("checks") or {}
checks_total = len(checks) if isinstance(checks, dict) else 0
lines.append(f"{icon} API health: {state} ({checks_total} checks)")
else:
lines.append(f"{icon} API health: {status} ({path})")
else:
lines.append("🟡 API health: endpoint not found")
ver_status, ver_body = _request(f"{base}/api/v1/version", headers, verify_tls)
if ver_status == 200:
try:
payload = json.loads(ver_body)
except json.JSONDecodeError:
payload = {}
version = payload.get("version") or "unknown"
lines.append(f" Version: {version}")
else:
lines.append(f"🟡 Version: HTTP {ver_status}")
return "\n".join(lines)