SeaCogs/issuecards/api/forgejo.py
cswimr d615acdcdd
Some checks failed
Actions / Build Documentation (MkDocs) (pull_request) Successful in 37s
Actions / Lint Code (Ruff & Pylint) (pull_request) Failing after 43s
feat(issuecards): init
2025-03-28 10:37:58 -05:00

70 lines
2.9 KiB
Python

import aiohttp
from ..logger import logger
from ..models import Issue, Repository
async def fetch_forgejo_issue(repository: Repository, issue_number: int) -> Issue:
"""
Fetch an issue from a Forgejo instance.
Args:
repository (Repository): The repository to fetch the issue from.
issue_number (int): The issue number.
Returns:
Issue: An Issue object containing the issue details.
Raises:
aiohttp.ClientResponseError: If the request to the Forgejo API fails.
ValueError: If the response from the Forgejo API is empty
"""
headers: dict[str, str] = {"User-Agent": repository.user_agent}
if repository.provider.token is not None:
headers["Authorization"] = f"token {repository.provider.token}"
else:
logger.info("Forgejo API key is not set for provider '%s'. Using unauthenticated request.", repository.provider.url)
url = f"{repository.provider.api_url}/repos/{repository.owner}/{repository.name}/issues/{issue_number}"
async with aiohttp.ClientSession() as session:
async with session.get(url, headers=headers) as response:
if response.status != 200:
raise aiohttp.ClientResponseError(
request_info=response.request_info,
history=response.history,
status=response.status,
message=f"Failed to fetch issue '{issue_number}' from '{repository.url}'.",
)
data = await response.json()
if data is None:
raise ValueError("Received empty response from Forgejo API.")
pull_request = data.get("pull_request")
if pull_request is not None:
if pull_request["merged"] is True:
issue_type = "pull_request_merged"
elif pull_request["draft"] is True:
issue_type = "pull_request_draft"
elif data.get("state", "open") == "closed":
issue_type = "pull_request_closed"
else:
issue_type = "pull_request"
elif data.get("state", "open") == "closed":
issue_type = "issue_closed"
else:
issue_type = "issue"
return Issue(
repository=repository,
number=data["number"],
author=data["user"]["login"],
author_avatar=data["user"]["avatar_url"],
author_url=data["user"]["html_url"],
link=data["html_url"],
title=data["title"],
body=data["body"] or "",
type=issue_type,
labels=[label["name"] for label in data.get("labels", [])],
draft=bool(data["pull_request"].get("draft", False) if data.get("pull_request") is not None else False),
creation_date=data["created_at"],
milestone=data.get("milestone", {}).get("title") if data.get("milestone") is not None else None,
merge_date=data.get("pull_request").get("merged_at") if data.get("pull_request") is not None else None,
response=response,
)