From: Michael Tremer Date: Tue, 15 Jul 2025 11:05:37 +0000 (+0000) Subject: bugtracker: Make fetching bugs compatible with the API X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=639e293251e113c5147ceef87be43be9836c5e86;p=pbs.git bugtracker: Make fetching bugs compatible with the API Signed-off-by: Michael Tremer --- diff --git a/src/buildservice/bugtracker.py b/src/buildservice/bugtracker.py index a5b53862..b408dfa1 100644 --- a/src/buildservice/bugtracker.py +++ b/src/buildservice/bugtracker.py @@ -26,6 +26,7 @@ import io import json import logging import mimetypes +import pydantic import urllib.parse from . import base @@ -34,8 +35,6 @@ from .decorators import * # Setup logging log = logging.getLogger("pbs.bugzilla") -TIME_FORMAT = "%Y-%m-%dT%H:%M:%SZ" - class BugzillaError(Exception): pass @@ -205,11 +204,26 @@ class Bugzilla(base.Object): response = await self._request("GET", "/rest/bug", data=kwargs) # Parse the response - bugs = [Bug(self.backend, self, data) for data in response.get("bugs")] + bugs = [self._make_bug(**data)for data in response.get("bugs")] # Sort and return in reverse order return sorted(bugs, reverse=True) + def _make_bug(self, id, creation_time, url=None, **kwargs): + """ + Creates a new Bug object, but renames a couple of fields on the way. + """ + # Make the URL + url = self.make_url("/show_bug.cgi", id=id) + + # Return the Bug + return Bug( + id = id, + url = url, + created_at = creation_time, + **kwargs, + ) + async def get_bugs(self, bugs): """ Fetches multiple bugs concurrently @@ -218,9 +232,10 @@ class Bugzilla(base.Object): async with asyncio.TaskGroup() as tg: for bug in bugs: - tg.create_task( + task = tg.create_task( self.get_bug(bug), ) + tasks.append(task) # Return the result from all tasks return [task.result() for task in tasks] @@ -234,7 +249,7 @@ class Bugzilla(base.Object): response = await self._request("GET", "/rest/bug/%s" % bug) for data in response.get("bugs"): - return Bug(self.backend, self, data) + return self._make_bug(**data) async def create_bug(self, product, component, version, summary, **kwargs): data = { @@ -257,11 +272,7 @@ class Bugzilla(base.Object): return await self.get_bug(id) -class Bug(base.Object): - def init(self, bugzilla, data): - self.bugzilla = bugzilla - self.data = data - +class Bug(pydantic.BaseModel): def __repr__(self): return "<%s #%s>" % (self.__class__.__name__, self.id) @@ -280,30 +291,29 @@ class Bug(base.Object): raise NotImplemented - @property - def id(self): - return self.data.get("id") + # ID - @property - def url(self): - return self.bugzilla.make_url("/show_bug.cgi", id=self.id) + id: int - @property - def created_at(self): - t = self.data.get("creation_time") + # URL - return datetime.datetime.strptime(t, TIME_FORMAT) + url: str - @property - def summary(self): - return self.data.get("summary") + # Created At - @property - def component(self): - return self.data.get("component") + created_at: datetime.datetime + + # Summary + + summary: str + + # Component + + component: str # Creator + # XXX TODO async def get_creator(self): creator = self.data.get("creator") @@ -311,29 +321,27 @@ class Bug(base.Object): # Assignee + # XXX TODO async def get_assignee(self): assignee = self.data.get("assigned_to") return await self.backend.users.get_by_email(assignee) - @property - def status(self): - return self.data.get("status") + # Status - @property - def resolution(self): - return self.data.get("resolution") + status: str - @property - def severity(self): - return self.data.get("severity") + # Resolution - def is_closed(self): - return not self.data["is_open"] + resolution: str - @property - def keywords(self): - return self.data.get("keywords") + # Severity + + severity: str + + # Keywords + + keywords: list[str] = [] # Update