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.
This commit is contained in:
Goffi 2019-09-25 08:56:41 +02:00
commit 76aadbb3fb

View file

@ -48,7 +48,6 @@ class Method(base.CommandBase, BridgeCommon):
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 @@ class Method(base.CommandBase, BridgeCommon):
"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 @@ class Signal(base.CommandBase, BridgeCommon):
"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 @@ class Monitor(base.CommandBase):
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 @@ class Monitor(base.CommandBase):
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 @@ class Monitor(base.CommandBase):
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 @@ class Monitor(base.CommandBase):
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 @@ class Monitor(base.CommandBase):
self.disp(xml_data)
self.disp("")
def start(self):
async def start(self):
self.host.bridge.register_signal("xmlLog", self.printXML, "plugin")