diff sat_frontends/jp/cmd_debug.py @ 3040:fee60f17ebac

jp: jp asyncio port: /!\ this commit is huge. Jp is temporarily not working with `dbus` bridge /!\ This patch implements the port of jp to asyncio, so it is now correctly using the bridge asynchronously, and it can be used with bridges like `pb`. This also simplify the code, notably for things which were previously implemented with many callbacks (like pagination with RSM). During the process, some behaviours have been modified/fixed, in jp and backends, check diff for details.
author Goffi <goffi@goffi.org>
date Wed, 25 Sep 2019 08:56:41 +0200
parents ab2696e34d29
children cf843dd7c345
line wrap: on
line diff
--- a/sat_frontends/jp/cmd_debug.py	Wed Sep 25 08:53:38 2019 +0200
+++ b/sat_frontends/jp/cmd_debug.py	Wed Sep 25 08:56:41 2019 +0200
@@ -48,7 +48,6 @@
     def __init__(self, host):
         base.CommandBase.__init__(self, host, "method", help=_("call a bridge method"))
         BridgeCommon.__init__(self)
-        self.need_loop = True
 
     def add_parser_options(self):
         self.parser.add_argument(
@@ -58,34 +57,31 @@
             "arg", nargs="*", help=_("argument of the method")
         )
 
-    def method_cb(self, ret=None):
-        if ret is not None:
-            self.disp(str(ret))
-        self.host.quit()
-
-    def method_eb(self, failure):
-        self.disp(
-            _("Error while executing {}: {}".format(self.args.method, failure)),
-            error=True,
-        )
-        self.host.quit(C.EXIT_ERROR)
-
-    def start(self):
+    async def start(self):
         method = getattr(self.host.bridge, self.args.method)
+        import inspect
+        argspec = inspect.getargspec(method)
+
+        kwargs = {}
+        if 'profile_key' in argspec.args:
+            kwargs['profile_key'] = self.profile
+        elif 'profile' in argspec.args:
+            kwargs['profile'] = self.profile
+
         args = self.evalArgs()
+
         try:
-            method(
+            ret = await method(
                 *args,
-                profile=self.profile,
-                callback=self.method_cb,
-                errback=self.method_eb
+                **kwargs,
             )
-        except TypeError:
-            # maybe the method doesn't need a profile ?
-            try:
-                method(*args, callback=self.method_cb, errback=self.method_eb)
-            except TypeError:
-                self.method_eb(_("bad arguments"))
+        except Exception as e:
+            self.disp(_(f"Error while executing {self.args.method}: {e}"), error=True)
+            self.host.quit(C.EXIT_ERROR)
+        else:
+            if ret is not None:
+                self.disp(str(ret))
+            self.host.quit()
 
 
 class Signal(base.CommandBase, BridgeCommon):
@@ -103,12 +99,18 @@
             "arg", nargs="*", help=_("argument of the signal")
         )
 
-    def start(self):
+    async def start(self):
         args = self.evalArgs()
         json_args = json.dumps(args)
         # XXX: we use self.args.profile and not self.profile
         #      because we want the raw profile_key (so plugin handle C.PROF_KEY_NONE)
-        self.host.bridge.debugFakeSignal(self.args.signal, json_args, self.args.profile)
+        try:
+            await self.host.bridge.debugFakeSignal(self.args.signal, json_args, self.args.profile)
+        except Exception as e:
+            self.disp(_(f"Can't send fake signal: {e}"), error=True)
+            self.host.quit(C.EXIT_ERROR)
+        else:
+            self.host.quit()
 
 
 class Bridge(base.CommandBase):
@@ -130,7 +132,6 @@
             use_output=C.OUTPUT_XML,
             help=_("monitor XML stream"),
         )
-        self.need_loop = True
 
     def add_parser_options(self):
         self.parser.add_argument(
@@ -141,7 +142,7 @@
             help=_("stream direction filter"),
         )
 
-    def printXML(self, direction, xml_data, profile):
+    async def printXML(self, direction, xml_data, profile):
         if self.args.direction == "in" and direction != "IN":
             return
         if self.args.direction == "out" and direction != "OUT":
@@ -155,7 +156,7 @@
             whiteping = False
 
         if verbosity:
-            profile_disp = " ({})".format(profile) if verbosity > 1 else ""
+            profile_disp = f" ({profile})" if verbosity > 1 else ""
             if direction == "IN":
                 self.disp(
                     A.color(
@@ -172,7 +173,7 @@
             self.disp("[WHITESPACE PING]")
         else:
             try:
-                self.output(xml_data)
+                await self.output(xml_data)
             except Exception:
                 #  initial stream is not valid XML,
                 # in this case we print directly to data
@@ -182,7 +183,7 @@
                 self.disp(xml_data)
                 self.disp("")
 
-    def start(self):
+    async def start(self):
         self.host.bridge.register_signal("xmlLog", self.printXML, "plugin")