diff --git a/gitea.py b/gitea.py index 916a681..dd29057 100644 --- a/gitea.py +++ b/gitea.py @@ -114,13 +114,13 @@ class GiteaClient: return downloaded - async def list_user_repos(self, owner: str) -> list[dict]: + async def list_org_repos(self, org: str) -> list[dict]: repos = [] page = 1 async with httpx.AsyncClient() as c: while True: r = await c.get( - f"{self.base}/users/{owner}/repos?page={page}&limit=50", + f"{self.base}/orgs/{org}/repos?page={page}&limit=50", headers=self.headers, ) r.raise_for_status() diff --git a/main.py b/main.py index 39a0432..662ecd6 100644 --- a/main.py +++ b/main.py @@ -4,8 +4,6 @@ import hmac import logging import os -from contextlib import asynccontextmanager - from fastapi import FastAPI, Request, HTTPException import config @@ -15,16 +13,16 @@ from workspace import ensure_repo, repo_path, attachments_path logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s") log = logging.getLogger("gitea-bot") -app = FastAPI(lifespan=lifespan) gitea = GiteaClient() -ALLOWED_OWNER = "fam" +ALLOWED_OWNER = "euphon" MAX_RESPONSE_LEN = 60000 CLAUDE_TIMEOUT = 600 # 10 minutes -WEBHOOK_SYNC_INTERVAL = 300 # 5 minutes -WEBHOOK_URL = "http://100.65.168.42:9880/webhook" +app = FastAPI() +# --- Helpers --- + def verify_signature(payload: bytes, signature: str) -> bool: if not config.WEBHOOK_SECRET: return True @@ -167,7 +165,6 @@ async def process_mention( pr_info = None pull_request = issue.get("pull_request") if pull_request and pull_request.get("merged") is not None: - # It's a PR - fetch full PR info pr_info = await gitea.get_pull_request(owner, repo, issue_number) head_branch = pr_info.get("head", {}).get("ref") if head_branch: @@ -204,6 +201,8 @@ async def process_mention( log.exception("Failed to post error comment") +# --- Routes --- + @app.post("/webhook") async def webhook(request: Request): body = await request.body() @@ -220,7 +219,6 @@ async def webhook(request: Request): owner = repo_data.get("owner", {}).get("login", "") repo = repo_data.get("name", "") - # Only process repos owned by fam if owner != ALLOWED_OWNER: return {"status": "skip", "reason": f"owner {owner} not allowed"} @@ -255,33 +253,6 @@ async def webhook(request: Request): return {"status": "skip", "reason": f"unhandled {event}/{action}"} -async def sync_webhooks(): - """Ensure all repos under ALLOWED_OWNER have our webhook.""" - try: - repos = await gitea.list_user_repos(ALLOWED_OWNER) - for r in repos: - name = r["name"] - created = await gitea.ensure_webhook(ALLOWED_OWNER, name, WEBHOOK_URL) - if created: - log.info(f"Added webhook to {ALLOWED_OWNER}/{name}") - except Exception: - log.exception("Failed to sync webhooks") - - -async def webhook_sync_loop(): - """Periodically sync webhooks for new repos.""" - while True: - await sync_webhooks() - await asyncio.sleep(WEBHOOK_SYNC_INTERVAL) - - -@asynccontextmanager -async def lifespan(app): - task = asyncio.create_task(webhook_sync_loop()) - yield - task.cancel() - - @app.get("/health") async def health(): return {"status": "ok"}