From: Michael Tremer Date: Thu, 1 Dec 2016 23:46:38 +0000 (+0100) Subject: client: Rewrite of the client that interacts with the hub X-Git-Tag: 0.9.28~1285^2~1439 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=132c98ed431c56d75c3b2ff5c762a7f01520aeb2;p=pakfire.git client: Rewrite of the client that interacts with the hub This is a rewrite of the client that interacts with the Pakfire Hub to upload scratch builds and retrieve the status of builds and jobs. Signed-off-by: Michael Tremer --- diff --git a/src/pakfire/client.py b/src/pakfire/client.py index e0eba2092..8bc5ba906 100644 --- a/src/pakfire/client.py +++ b/src/pakfire/client.py @@ -19,29 +19,232 @@ # # ############################################################################### -from . import transport +import logging -from pakfire.constants import * -from pakfire.i18n import _ +from .ui.helpers import format_time + +from . import config +from . import hub + +from .constants import * +from .i18n import _ -import logging log = logging.getLogger("pakfire.client") +log.propagate = 1 + +class Client(object): + def __init__(self, config_file="client.conf"): + # Read configuration + self.config = config.Config(config_file) + + # Create connection to the hub + self.hub = self.connect_to_hub() + + def connect_to_hub(self): + huburl = self.config.get("client", "server", PAKFIRE_HUB) -class PakfireClient(object): - def __init__(self, config): - self.config = config + # User Credentials + username = self.config.get("client", "username") + password = self.config.get("client", "password") + + if not (username and password): + raise RuntimeError("User credentials are not set") # Create connection to the hub. - self.transport = transport.PakfireHubTransport(self.config) + return hub.Hub(huburl, username, password) + + def create_build(self, filename, **kwargs): + build_id = self.hub.create_build(filename, **kwargs) + + return self.get_build(build_id) + + def get_build(self, build_id): + return Build(self, build_id) + + +class _ClientObject(object): + def __init__(self, client, id): + self.client = client + + # UUID of the build + self.id = id + + self._data = None + self._cache = {} + + def __repr__(self): + return "<%s %s>" % (self.__class__.__name__, self.id) + + def __eq__(self, other): + return self.id == other.id + + @property + def data(self): + if self._data is None: + self._data = self._load() + + return self._data + + def refresh(self): + self._data = self._load() + + def _load(self): + """ + Loads information about this object from the hub + """ + raise NotImplementedError + + +class Build(_ClientObject): + def _load(self): + """ + Loads information about this build from the hub + """ + return self.client.hub.get_build(self.id) + + @property + def jobs(self): + jobs = [] + + for job in self.data.get("jobs"): + try: + j = self._cache[job] + except KeyError: + j = Job(self.client, job) + + jobs.append(j) + + return sorted(jobs) + + @property + def type(self): + """ + The type of this build (release or scratch) + """ + return self.data.get("type") + + @property + def _type_tag(self): + if self.type == "release": + return "[R]" + + elif self.type == "scratch": + return "[S]" + + @property + def name(self): + """ + The name of this build + """ + return self.data.get("name") + + @property + def priority(self): + """ + The priority of this build + """ + return self.data.get("priority") + + @property + def score(self): + """ + The score of this build + """ + return self.data.get("score") + + @property + def state(self): + """ + The state this build is in + """ + return self.data.get("state") + + def is_active(self): + return self.state == "building" + + @property + def oneline(self): + s = [ + self.name, + self._type_tag, + "(%s)" % self.id, + _("Score: %s") % self.score, + _("Priority: %s") % self.priority, + ] + + return " ".join(s) + + def dump(self): + # Add a headline for the build + s = [ + self.oneline, + ] + + # Add a short line for each job + for j in self.jobs: + s.append(" %s" % j.oneline) + + return "\n".join(s) + + +class Job(_ClientObject): + def _load(self): + """ + Loads information about this job from the hub + """ + return self.client.hub.get_job(self.id) + + def __lt__(self, other): + return self.arch < other.arch + + @property + def arch(self): + """ + The architecture of this job + """ + return self.data.get("arch") + + @property + def builder(self): + """ + The name of the builder that built this job + """ + return self.data.get("builder") + + @property + def duration(self): + """ + The duration the job took to build + """ + return self.data.get("duration") + + @property + def state(self): + """ + The state of this job + """ + return self.data.get("state") + + def is_active(self): + return self.state in ("dispatching", "running", "uploading") + + def is_finished(self): + return self.state == "finished" + + @property + def oneline(self): + s = [ + # Architecture + "[%-8s]" % self.arch, - def build_create(self, *args, **kwargs): - return self.transport.build_create(*args, **kwargs) + # State + "[%12s]" % self.state, + ] - def build_get(self, *args, **kwargs): - return self.transport.build_get(*args, **kwargs) + if self.is_active(): + s.append(_("on %s") % self.builder) - def job_get(self, *args, **kwargs): - return self.transport.job_get(*args, **kwargs) + elif self.is_finished(): + s.append(_("in %s") % format_time(self.duration)) - def package_get(self, *args, **kwargs): - return self.transport.package_get(*args, **kwargs) + return " ".join(s)