fix(api): fallback weekly git stats to gitea
This commit is contained in:
@@ -20,13 +20,17 @@ Weekly Report Service - Phase 21.3 定期報告
|
||||
"""
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import subprocess
|
||||
from datetime import datetime, timedelta
|
||||
from urllib.parse import quote, urlencode
|
||||
from urllib.request import Request, urlopen
|
||||
from typing import Protocol, runtime_checkable
|
||||
|
||||
import structlog
|
||||
from zoneinfo import ZoneInfo
|
||||
|
||||
from src.core.config import settings
|
||||
from src.services.stats_service import StatsService, get_stats_service
|
||||
from src.services.k3s_monitor_service import K3sMonitorService, get_k3s_monitor_service
|
||||
from src.services.telegram_gateway import WeeklyReportMessage, get_telegram_gateway
|
||||
@@ -112,7 +116,7 @@ class WeeklyReportService:
|
||||
returncode=result.returncode,
|
||||
stderr=result.stderr[-300:],
|
||||
)
|
||||
return 0, 0, False
|
||||
return self._get_gitea_commit_stats(since)
|
||||
commits = len(result.stdout.strip().split("\n")) if result.stdout.strip() else 0
|
||||
|
||||
# 取得部署次數 (計算含 "deploy" 或 "CD" 的 commits)
|
||||
@@ -129,12 +133,56 @@ class WeeklyReportService:
|
||||
returncode=result_deploy.returncode,
|
||||
stderr=result_deploy.stderr[-300:],
|
||||
)
|
||||
return commits, 0, False
|
||||
return self._get_gitea_commit_stats(since)
|
||||
deploys = len(result_deploy.stdout.strip().split("\n")) if result_deploy.stdout.strip() else 0
|
||||
|
||||
return commits, deploys, True
|
||||
except Exception as e:
|
||||
logger.warning("git_stats_failed", error=str(e))
|
||||
return self._get_gitea_commit_stats(since)
|
||||
|
||||
def _get_gitea_commit_stats(self, since: datetime) -> tuple[int, int, bool]:
|
||||
"""從 Gitea commits API 讀取週報開發活動統計。"""
|
||||
api_url = settings.GITEA_API_URL.rstrip("/")
|
||||
owner = quote(str(settings.GITEA_REPO_OWNER), safe="")
|
||||
repo = quote(str(settings.GITEA_REPO_NAME), safe="")
|
||||
since_utc = since.astimezone(ZoneInfo("UTC")).isoformat().replace("+00:00", "Z")
|
||||
headers = {"Accept": "application/json", "User-Agent": "awoooi-weekly-report/1.0"}
|
||||
if settings.GITEA_API_TOKEN:
|
||||
headers["Authorization"] = f"token {settings.GITEA_API_TOKEN}"
|
||||
|
||||
commits = 0
|
||||
deploys = 0
|
||||
page = 1
|
||||
limit = 50
|
||||
try:
|
||||
while page <= 20:
|
||||
query = urlencode({
|
||||
"sha": "main",
|
||||
"since": since_utc,
|
||||
"page": page,
|
||||
"limit": limit,
|
||||
})
|
||||
url = f"{api_url}/api/v1/repos/{owner}/{repo}/commits?{query}"
|
||||
request = Request(url, headers=headers)
|
||||
with urlopen(request, timeout=8) as response:
|
||||
payload = json.loads(response.read().decode("utf-8"))
|
||||
if not isinstance(payload, list):
|
||||
logger.warning("gitea_git_stats_unexpected_payload", payload_type=type(payload).__name__)
|
||||
return 0, 0, False
|
||||
commits += len(payload)
|
||||
for item in payload:
|
||||
commit = item.get("commit") if isinstance(item, dict) else {}
|
||||
message = str((commit or {}).get("message") or "")
|
||||
subject = message.splitlines()[0].lower()
|
||||
if "deploy" in subject or subject.startswith("chore(cd):"):
|
||||
deploys += 1
|
||||
if len(payload) < limit:
|
||||
break
|
||||
page += 1
|
||||
return commits, deploys, True
|
||||
except Exception as exc:
|
||||
logger.warning("gitea_git_stats_failed", error=str(exc))
|
||||
return 0, 0, False
|
||||
|
||||
async def generate_report(self) -> WeeklyReportMessage:
|
||||
|
||||
Reference in New Issue
Block a user