]> git.ipfire.org Git - pbs.git/commitdiff
bugtracker: Make fetching bugs compatible with the API
authorMichael Tremer <michael.tremer@ipfire.org>
Tue, 15 Jul 2025 11:05:37 +0000 (11:05 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Tue, 15 Jul 2025 11:05:37 +0000 (11:05 +0000)
Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/buildservice/bugtracker.py

index a5b5386231e67cf0445bf7368696dc9dface528d..b408dfa1ab29d56faefecd98b0377a05c68178af 100644 (file)
@@ -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