diff --git a/libervia/backend/bridge/bridge_constructor/base_constructor.py b/libervia/backend/bridge/bridge_constructor/base_constructor.py
index 00cb535e..6d5ff925 100644
--- a/libervia/backend/bridge/bridge_constructor/base_constructor.py
+++ b/libervia/backend/bridge/bridge_constructor/base_constructor.py
@@ -306,8 +306,10 @@ class Constructor(object):
extend_method(completion, function, default, arg_doc, async_)
for part, fmt in FORMATS.items():
- if part.startswith(function["type"]) or part.startswith(
- f"async_{function['type']}"
+ if (
+ part.startswith(function["type"])
+ or part.startswith(f"async_{function['type']}")
+ or part.startswith(f"twisted_{function['type']}")
):
parts[part.upper()].append(fmt.format(**completion))
diff --git a/libervia/backend/bridge/bridge_constructor/constructors/dbus/constructor.py b/libervia/backend/bridge/bridge_constructor/constructors/dbus/constructor.py
index 7c3014a9..4fc1d5c6 100644
--- a/libervia/backend/bridge/bridge_constructor/constructors/dbus/constructor.py
+++ b/libervia/backend/bridge/bridge_constructor/constructors/dbus/constructor.py
@@ -41,16 +41,14 @@ class DbusConstructor(base_constructor.Constructor):
FRONTEND_DEST = CORE_DEST
FRONTEND_FORMATS = {
"methods": """\
- def {name}(self, {args}{async_comma}{async_args}):
- {error_handler}{blocking_call}{debug}return {result}\n""",
+ def {name}(self, {args}):
+ {debug}return self.call("{name}", {args_result})\n""",
"async_methods": """\
- def {name}(self{async_comma}{args}):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(fut.set_exception, dbus_to_bridge_exception(err))
- self.db_{category}_iface.{name}({args_result}{async_comma}timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler)
- {debug}return fut\n""",
+ async def {name}(self, {args}):
+ {debug}return await self.call("{name}", {args_result})\n""",
+ "twisted_methods": """\
+ def {name}(self, {args}):
+ {debug}return self.call("{name}", {args_result})\n""",
}
def core_completion_signal(self, completion, function, default, arg_doc, async_):
@@ -75,42 +73,11 @@ class DbusConstructor(base_constructor.Constructor):
def frontend_completion_method(self, completion, function, default, arg_doc, async_):
completion.update(
{
- # XXX: we can manage blocking call in the same way as async one: if callback is None the call will be blocking
"debug": (
""
if not self.args.debug
else 'log.debug ("%s")\n%s' % (completion["name"], 8 * " ")
),
"args_result": self.get_arguments(function["sig_in"], name=arg_doc),
- "async_args": "callback=None, errback=None",
- "async_comma": ", " if function["sig_in"] else "",
- "error_handler": """if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err:errback(dbus_to_bridge_exception(err))
- """,
}
)
- if async_:
- completion["blocking_call"] = ""
- completion["async_args_result"] = (
- "timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler"
- )
- else:
- # XXX: To have a blocking call, we must have not reply_handler, so we test if callback exists, and add reply_handler only in this case
- completion["blocking_call"] = """kwargs={}
- if callback is not None:
- kwargs['timeout'] = const_TIMEOUT
- kwargs['reply_handler'] = callback
- kwargs['error_handler'] = error_handler
- """
- completion["async_args_result"] = "**kwargs"
- result = (
- "self.db_%(category)s_iface.%(name)s(%(args_result)s%(async_comma)s%(async_args_result)s)"
- % completion
- )
- completion["result"] = (
- "str(%s)" if self.args.unicode and function["sig_out"] == "s" else "%s"
- ) % result
diff --git a/libervia/backend/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py b/libervia/backend/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py
index a19dca4f..4598bdd1 100644
--- a/libervia/backend/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py
+++ b/libervia/backend/bridge/bridge_constructor/constructors/dbus/dbus_frontend_template.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
-# SàT communication bridge
-# Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
+# Libervia D-Bus communication bridge
+# Copyright (C) 2009-2026 Jérôme Poisson (goffi@goffi.org)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -17,23 +17,17 @@
# along with this program. If not, see .
import asyncio
-import dbus
-import ast
-from libervia.backend.core.i18n import _
-from libervia.backend.tools import config
-from libervia.backend.core.log import getLogger
-from libervia.backend.core.exceptions import BridgeExceptionNoService, BridgeInitError
-from dbus.mainloop.glib import DBusGMainLoop
+from functools import partial
+
+from twisted.internet import reactor
+from txdbus import client
+
from .bridge_frontend import BridgeException
+from libervia.backend.core.exceptions import BridgeExceptionNoService, BridgeInitError
+from libervia.backend.core.i18n import _
+from libervia.backend.core.log import getLogger
+from libervia.backend.tools import config
-# We check if GLib is actually available to avoid init error at a later stage.
-try:
- from gi.repository import GLib # type: ignore
-except ImportError as e:
- raise BridgeInitError(f"GLib is required for D-Bus bridge: {e}")
-
-
-DBusGMainLoop(set_as_default=True)
log = getLogger(__name__)
@@ -48,207 +42,306 @@ const_PLUGIN_SUFFIX = ".plugin"
const_TIMEOUT = 120
-def dbus_to_bridge_exception(dbus_e):
- """Convert a DBusException to a BridgeException.
+def dbus_to_bridge_exception(failure):
+ """Convert a txdbus Failure to a BridgeException.
- @param dbus_e (DBusException)
+ @param failure (Failure or RemoteError)
@return: BridgeException
"""
- full_name = dbus_e.get_dbus_name()
- if full_name.startswith(const_ERROR_PREFIX):
- name = dbus_e.get_dbus_name()[len(const_ERROR_PREFIX) + 1 :]
+ from twisted.python.failure import Failure
+
+ if isinstance(failure, Failure):
+ err = failure.value
+ message = failure.getErrorMessage()
+ else:
+ err = failure
+ message = str(failure)
+
+ full_name = getattr(err, "dbusErrorName", None) or getattr(err, "errName", None)
+ if full_name is None:
+ full_name = ".".join(
+ (const_ERROR_PREFIX, err.__class__.__module__, err.__class__.__name__)
+ )
+
+ if full_name and full_name.startswith(const_ERROR_PREFIX):
+ name = full_name[len(const_ERROR_PREFIX) + 1 :]
else:
name = full_name
- # XXX: dbus_e.args doesn't contain the original DBusException args, but we
- # receive its serialized form in dbus_e.args[0]. From that we can rebuild
- # the original arguments list thanks to ast.literal_eval (secure eval).
- message = dbus_e.get_dbus_message() # similar to dbus_e.args[0]
- try:
- message, condition = ast.literal_eval(message)
- except (SyntaxError, ValueError, TypeError):
- condition = ""
- return BridgeException(name, message, condition)
+
+ return BridgeException(name, message, "")
+
+
+class SignalsHandler:
+
+ def __init__(self, db_object, iface_name):
+ self.db_object = db_object
+ self._iface_names = {
+ "core": const_INT_PREFIX + const_CORE_SUFFIX,
+ "plugin": iface_name,
+ }
+
+ def __getattr__(self, name):
+ if name.startswith("remote_"):
+ log.debug("calling an unregistered signal: {name}".format(name=name[7:]))
+ return lambda *args, **kwargs: None
+ else:
+ raise AttributeError(name)
+
+ def register_signal(self, name, handler, iface="core"):
+ log.debug("registering signal {name}".format(name=name))
+ method_name = "remote_" + name
+ try:
+ self.__getattribute__(method_name)
+ except AttributeError:
+ pass
+ else:
+ from libervia.backend.core import exceptions
+
+ raise exceptions.InternalError(
+ "{name} signal handler has been registered twice".format(name=method_name)
+ )
+
+ def on_signal(*args):
+ handler(*args)
+
+ d = self.db_object.notifyOnSignal(
+ name, on_signal, interface=self._iface_names[iface]
+ )
+ d.addErrback(
+ lambda failure_: log.error(
+ f"Failed to register signal {name}: {failure_.getErrorMessage()}"
+ )
+ )
+
+ setattr(self, method_name, on_signal)
class bridge:
- def bridge_connect(self, callback, errback):
+ def __init__(self):
+ self.conn = None
+ self.db_object = None
+ self.db_core_iface = None
+ self.db_plugin_iface = None
+ self.signals_handler = None
+
+ def __getattr__(self, name):
+ return partial(self.call, name)
+
+ @staticmethod
+ def _unwrap_txdbus_result(d, return_sig):
+ """Unwrap txdbus result."""
+ # txdbus seems to wrongly wrap result in a list, this is a workaround.
+ # FIXME: check txdbus behaviour, and report upstream if it's confirmed to be a
+ # bug.
+ if return_sig and return_sig.startswith("("):
+ d.addCallback(
+ lambda result: (
+ result[0] if isinstance(result, list) and len(result) == 1 else result
+ )
+ )
+ return d
+
+ def call(self, name: str, *args, **kwargs):
+ """Call a remote method.
+
+ @param name: name of the bridge method
+ @param args: method arguments
+ @param kwargs: keyword arguments (callback, errback, and methods arguments)
+ """
+ # Determine which interface to use by checking where the method is defined
+ for iface in self.db_object.interfaces:
+ if name in iface.methods:
+ interface_name = iface.name
+ return_sig = iface.methods[name].sigOut
+ break
+ else:
+ # Default to core interface if method not found (will raise AttributeError)
+ interface_name = const_INT_PREFIX + const_CORE_SUFFIX
+ return_sig = None
+
+ # Call the remote method
+ d = self.db_object.callRemote(
+ name,
+ *args,
+ interface=interface_name,
+ timeout=const_TIMEOUT,
+ )
+
+ self._unwrap_txdbus_result(d, return_sig)
+
+ return d
+
+ async def bridge_connect(self) -> None:
+ """Connect to the D-Bus bridge."""
try:
- self.sessions_bus = dbus.SessionBus()
- self.db_object = self.sessions_bus.get_object(
+ self.conn = await client.connect(reactor)
+ self.db_object = await self.conn.getRemoteObject(
const_INT_PREFIX, const_OBJ_PATH
)
- self.db_core_iface = dbus.Interface(
- self.db_object, dbus_interface=const_INT_PREFIX + const_CORE_SUFFIX
+ # Find the core and plugin interfaces
+ for iface in self.db_object.interfaces:
+ if iface.name == const_INT_PREFIX + const_CORE_SUFFIX:
+ self.db_core_iface = iface
+ elif iface.name == const_INT_PREFIX + const_PLUGIN_SUFFIX:
+ self.db_plugin_iface = iface
+
+ if self.db_core_iface is None:
+ raise BridgeInitError(
+ f"Core interface {const_INT_PREFIX + const_CORE_SUFFIX} not found"
+ )
+ if self.db_plugin_iface is None:
+ raise BridgeInitError(
+ f"Plugin interface {const_INT_PREFIX + const_PLUGIN_SUFFIX} not found"
+ )
+
+ # Initialize signals handler
+ self.signals_handler = SignalsHandler(
+ self.db_object, const_INT_PREFIX + const_PLUGIN_SUFFIX
)
- self.db_plugin_iface = dbus.Interface(
- self.db_object, dbus_interface=const_INT_PREFIX + const_PLUGIN_SUFFIX
- )
- except dbus.exceptions.DBusException as e:
- if e._dbus_error_name in (
- "org.freedesktop.DBus.Error.ServiceUnknown",
- "org.freedesktop.DBus.Error.Spawn.ExecFailed",
+ except BridgeInitError as e:
+ raise e
+ except Exception as e:
+ msg = str(e)
+ if (
+ "org.freedesktop.DBus.Error.ServiceUnknown" in msg
+ or "org.freedesktop.DBus.Error.Spawn.ExecFailed" in msg
):
- errback(BridgeExceptionNoService())
- elif e._dbus_error_name == "org.freedesktop.DBus.Error.NotSupported":
+ raise BridgeExceptionNoService from e
+ elif "org.freedesktop.DBus.Error.NotSupported" in msg:
log.error(
_(
- "D-Bus is not launched, please see README to see instructions on how to launch it"
+ "D-Bus is not launched, please see README to see instructions on"
+ " how to launch it"
)
)
- errback(BridgeInitError)
- else:
- errback(e)
- else:
- callback()
- # props = self.db_core_iface.getProperties()
+ raise BridgeInitError from e
def register_signal(self, functionName, handler, iface="core"):
- if iface == "core":
- self.db_core_iface.connect_to_signal(functionName, handler)
- elif iface == "plugin":
- self.db_plugin_iface.connect_to_signal(functionName, handler)
- else:
- log.error(_("Unknown interface"))
-
- def __getattribute__(self, name):
- """usual __getattribute__ if the method exists, else try to find a plugin method"""
- try:
- return object.__getattribute__(self, name)
- except AttributeError:
- # The attribute is not found, we try the plugin proxy to find the requested method
-
- def get_plugin_method(*args, **kwargs):
- # We first check if we have an async call. We detect this in two ways:
- # - if we have the 'callback' and 'errback' keyword arguments
- # - or if the last two arguments are callable
-
- async_ = False
- args = list(args)
-
- if kwargs:
- if "callback" in kwargs:
- async_ = True
- _callback = kwargs.pop("callback")
- _errback = kwargs.pop(
- "errback", lambda failure: log.error(str(failure))
- )
- try:
- args.append(kwargs.pop("profile"))
- except KeyError:
- try:
- args.append(kwargs.pop("profile_key"))
- except KeyError:
- pass
- # at this point, kwargs should be empty
- if kwargs:
- log.warning(
- "unexpected keyword arguments, they will be ignored: {}".format(
- kwargs
- )
- )
- elif len(args) >= 2 and callable(args[-1]) and callable(args[-2]):
- async_ = True
- _errback = args.pop()
- _callback = args.pop()
-
- method = getattr(self.db_plugin_iface, name)
-
- if async_:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = _callback
- kwargs["error_handler"] = lambda err: _errback(
- dbus_to_bridge_exception(err)
- )
-
- try:
- return method(*args, **kwargs)
- except ValueError as e:
- if e.args[0].startswith("Unable to guess signature"):
- # XXX: if frontend is started too soon after backend, the
- # inspection misses methods (notably plugin dynamically added
- # methods). The following hack works around that by redoing the
- # cache of introspected methods signatures.
- log.debug("using hack to work around inspection issue")
- proxy = self.db_plugin_iface.proxy_object
- IN_PROGRESS = proxy.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS
- proxy._introspect_state = IN_PROGRESS
- proxy._Introspect()
- return self.db_plugin_iface.get_dbus_method(name)(*args, **kwargs)
- raise e
-
- return get_plugin_method
+ if self.signals_handler is None:
+ log.error("Bridge not initialized")
+ return
+ self.signals_handler.register_signal(functionName, handler, iface)
##METHODS_PART##
-class AIOBridge(bridge):
+class AIOSignalsHandler(SignalsHandler):
- async def post_init(self) -> None:
- pass
-
- def register_signal(self, functionName, handler, iface="core"):
- loop = asyncio.get_running_loop()
- async_handler = lambda *args: asyncio.run_coroutine_threadsafe(
- handler(*args), loop
- )
- return super().register_signal(functionName, async_handler, iface)
-
- def __getattribute__(self, name):
- """usual __getattribute__ if the method exists, else try to find a plugin method"""
- try:
- return object.__getattribute__(self, name)
- except AttributeError:
- # The attribute is not found, we try the plugin proxy to find the requested method
- def get_plugin_method(*args, **kwargs):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- method = getattr(self.db_plugin_iface, name)
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(
- fut.set_result, ret
- )
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- try:
- method(
- *args,
- **kwargs,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- except ValueError as e:
- if e.args[0].startswith("Unable to guess signature"):
- # same hack as for bridge.__getattribute__
- log.warning("using hack to work around inspection issue")
- proxy = self.db_plugin_iface.proxy_object
- IN_PROGRESS = proxy.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS
- proxy._introspect_state = IN_PROGRESS
- proxy._Introspect()
- self.db_plugin_iface.get_dbus_method(name)(
- *args,
- **kwargs,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
-
- else:
- raise e
- return fut
-
- return get_plugin_method
-
- def bridge_connect(self):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- super().bridge_connect(
- callback=lambda: loop.call_soon_threadsafe(fut.set_result, None),
- errback=lambda e: loop.call_soon_threadsafe(fut.set_exception, e),
- )
- return fut
+ def register_signal(self, name, handler, iface="core"):
+ """Register an async signal handler."""
+ async_handler = lambda *args: asyncio.ensure_future(handler(*args))
+ return super().register_signal(name, async_handler, iface)
##ASYNC_METHODS_PART##
+
+
+class AIOBridge(bridge):
+
+ def __init__(self):
+ super().__init__()
+ self.signals_handler = None
+
+ async def post_init(self):
+ """Post-initialization hook.
+
+ Actually no post init is needed, but the "__getattr__" return "partial" for
+ unknown methods, and this causes "dynamic_import.load_and_init_bridge" to fail.
+ """
+ pass
+
+ def call(self, name: str, *args, **kwargs):
+ """Call a remote method and return an awaitable.
+
+ @param name: name of the bridge method
+ """
+ d = super().call(name, *args, **kwargs)
+ return d.asFuture(asyncio.get_event_loop())
+
+ async def bridge_connect(self):
+ """Connect to the D-Bus bridge (async version)."""
+ try:
+ self.conn = await client.connect(reactor).asFuture(asyncio.get_event_loop())
+ self.db_object = await self.conn.getRemoteObject(
+ const_INT_PREFIX, const_OBJ_PATH
+ ).asFuture(asyncio.get_event_loop())
+
+ # Find the core and plugin interfaces
+ for iface in self.db_object.interfaces:
+ if iface.name == const_INT_PREFIX + const_CORE_SUFFIX:
+ self.db_core_iface = iface
+ elif iface.name == const_INT_PREFIX + const_PLUGIN_SUFFIX:
+ self.db_plugin_iface = iface
+
+ if self.db_core_iface is None:
+ raise BridgeInitError(
+ f"Core interface {const_INT_PREFIX + const_CORE_SUFFIX} not found"
+ )
+ if self.db_plugin_iface is None:
+ raise BridgeInitError(
+ f"Plugin interface {const_INT_PREFIX + const_PLUGIN_SUFFIX} not found"
+ )
+
+ # Initialize signals handler
+ self.signals_handler = AIOSignalsHandler(
+ self.db_object, const_INT_PREFIX + const_PLUGIN_SUFFIX
+ )
+ except BridgeInitError as e:
+ raise e
+ except Exception as e:
+ msg = str(e)
+ if (
+ "org.freedesktop.DBus.Error.ServiceUnknown" in msg
+ or "org.freedesktop.DBus.Error.Spawn.ExecFailed" in msg
+ ):
+ raise BridgeExceptionNoService from e
+ elif "org.freedesktop.DBus.Error.NotSupported" in msg:
+ log.error(
+ _(
+ "D-Bus is not launched, please see README to see instructions on"
+ " how to launch it"
+ )
+ )
+ raise BridgeInitError from e
+
+ def register_signal(self, functionName, handler, iface="core"):
+ if self.signals_handler is None:
+ log.error("Bridge not initialized")
+ return
+ self.signals_handler.register_signal(functionName, handler, iface)
+
+
+class TwistedBridge(bridge):
+
+ async def post_init(self):
+ """Post-initialization hook.
+
+ Actually no post init is needed, but the "__getattr__" return "partial" for
+ unknown methods, and this causes "dynamic_import.load_and_init_bridge" to fail.
+ """
+ pass
+
+ def _errback(self, failure_):
+ """Convert Failure to BridgeException"""
+ raise dbus_to_bridge_exception(failure_)
+
+ def call(self, name, *args, **kwargs):
+ """Call a remote method and return a Deferred.
+
+ @param name(str): name of the bridge method
+ @param args(list): arguments
+ @param kwargs(dict): keyword arguments (profile, etc.)
+ """
+ return super().call(name, *args, **kwargs)
+
+ async def bridge_connect(self) -> None:
+ """Connect to the D-Bus bridge."""
+ return await super().bridge_connect()
+
+ def register_signal(self, functionName, handler, iface="core"):
+ super().register_signal(functionName, handler, iface)
+
+
+##TWISTED_METHODS_PART##
diff --git a/libervia/frontends/bridge/dbus_bridge.py b/libervia/frontends/bridge/dbus_bridge.py
index 849bcca4..83637af2 100644
--- a/libervia/frontends/bridge/dbus_bridge.py
+++ b/libervia/frontends/bridge/dbus_bridge.py
@@ -1,7 +1,7 @@
#!/usr/bin/env python3
-# SàT communication bridge
-# Copyright (C) 2009-2021 Jérôme Poisson (goffi@goffi.org)
+# Libervia D-Bus communication bridge
+# Copyright (C) 2009-2026 Jérôme Poisson (goffi@goffi.org)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
@@ -17,23 +17,17 @@
# along with this program. If not, see .
import asyncio
-import dbus
-import ast
-from libervia.backend.core.i18n import _
-from libervia.backend.tools import config
-from libervia.backend.core.log import getLogger
-from libervia.backend.core.exceptions import BridgeExceptionNoService, BridgeInitError
-from dbus.mainloop.glib import DBusGMainLoop
+from functools import partial
+
+from twisted.internet import reactor
+from txdbus import client
+
from .bridge_frontend import BridgeException
+from libervia.backend.core.exceptions import BridgeExceptionNoService, BridgeInitError
+from libervia.backend.core.i18n import _
+from libervia.backend.core.log import getLogger
+from libervia.backend.tools import config
-# We check if GLib is actually available to avoid init error at a later stage.
-try:
- from gi.repository import GLib # type: ignore
-except ImportError as e:
- raise BridgeInitError(f"GLib is required for D-Bus bridge: {e}")
-
-
-DBusGMainLoop(set_as_default=True)
log = getLogger(__name__)
@@ -48,1695 +42,219 @@ const_PLUGIN_SUFFIX = ".plugin"
const_TIMEOUT = 120
-def dbus_to_bridge_exception(dbus_e):
- """Convert a DBusException to a BridgeException.
+def dbus_to_bridge_exception(failure):
+ """Convert a txdbus Failure to a BridgeException.
- @param dbus_e (DBusException)
+ @param failure (Failure or RemoteError)
@return: BridgeException
"""
- full_name = dbus_e.get_dbus_name()
- if full_name.startswith(const_ERROR_PREFIX):
- name = dbus_e.get_dbus_name()[len(const_ERROR_PREFIX) + 1 :]
+ from twisted.python.failure import Failure
+
+ if isinstance(failure, Failure):
+ err = failure.value
+ message = failure.getErrorMessage()
+ else:
+ err = failure
+ message = str(failure)
+
+ full_name = getattr(err, "dbusErrorName", None) or getattr(err, "errName", None)
+ if full_name is None:
+ full_name = ".".join(
+ (const_ERROR_PREFIX, err.__class__.__module__, err.__class__.__name__)
+ )
+
+ if full_name and full_name.startswith(const_ERROR_PREFIX):
+ name = full_name[len(const_ERROR_PREFIX) + 1 :]
else:
name = full_name
- # XXX: dbus_e.args doesn't contain the original DBusException args, but we
- # receive its serialized form in dbus_e.args[0]. From that we can rebuild
- # the original arguments list thanks to ast.literal_eval (secure eval).
- message = dbus_e.get_dbus_message() # similar to dbus_e.args[0]
- try:
- message, condition = ast.literal_eval(message)
- except (SyntaxError, ValueError, TypeError):
- condition = ""
- return BridgeException(name, message, condition)
+
+ return BridgeException(name, message, "")
+
+
+class SignalsHandler:
+
+ def __init__(self, db_object, iface_name):
+ self.db_object = db_object
+ self._iface_names = {
+ "core": const_INT_PREFIX + const_CORE_SUFFIX,
+ "plugin": iface_name,
+ }
+
+ def __getattr__(self, name):
+ if name.startswith("remote_"):
+ log.debug("calling an unregistered signal: {name}".format(name=name[7:]))
+ return lambda *args, **kwargs: None
+ else:
+ raise AttributeError(name)
+
+ def register_signal(self, name, handler, iface="core"):
+ log.debug("registering signal {name}".format(name=name))
+ method_name = "remote_" + name
+ try:
+ self.__getattribute__(method_name)
+ except AttributeError:
+ pass
+ else:
+ from libervia.backend.core import exceptions
+
+ raise exceptions.InternalError(
+ "{name} signal handler has been registered twice".format(name=method_name)
+ )
+
+ def on_signal(*args):
+ handler(*args)
+
+ d = self.db_object.notifyOnSignal(
+ name, on_signal, interface=self._iface_names[iface]
+ )
+ d.addErrback(
+ lambda failure_: log.error(
+ f"Failed to register signal {name}: {failure_.getErrorMessage()}"
+ )
+ )
+
+ setattr(self, method_name, on_signal)
class bridge:
- def bridge_connect(self, callback, errback):
+ def __init__(self):
+ self.conn = None
+ self.db_object = None
+ self.db_core_iface = None
+ self.db_plugin_iface = None
+ self.signals_handler = None
+
+ def __getattr__(self, name):
+ return partial(self.call, name)
+
+ @staticmethod
+ def _unwrap_txdbus_result(d, return_sig):
+ """Unwrap txdbus result."""
+ # txdbus seems to wrongly wrap result in a list, this is a workaround.
+ # FIXME: check txdbus behaviour, and report upstream if it's confirmed to be a
+ # bug.
+ if return_sig and return_sig.startswith("("):
+ d.addCallback(
+ lambda result: (
+ result[0] if isinstance(result, list) and len(result) == 1 else result
+ )
+ )
+ return d
+
+ def call(self, name: str, *args, **kwargs):
+ """Call a remote method.
+
+ @param name: name of the bridge method
+ @param args: method arguments
+ @param kwargs: keyword arguments (callback, errback, and methods arguments)
+ """
+ # Determine which interface to use by checking where the method is defined
+ for iface in self.db_object.interfaces:
+ if name in iface.methods:
+ interface_name = iface.name
+ return_sig = iface.methods[name].sigOut
+ break
+ else:
+ # Default to core interface if method not found (will raise AttributeError)
+ interface_name = const_INT_PREFIX + const_CORE_SUFFIX
+ return_sig = None
+
+ # Call the remote method
+ d = self.db_object.callRemote(
+ name,
+ *args,
+ interface=interface_name,
+ timeout=const_TIMEOUT,
+ )
+
+ self._unwrap_txdbus_result(d, return_sig)
+
+ return d
+
+ async def bridge_connect(self) -> None:
+ """Connect to the D-Bus bridge."""
try:
- self.sessions_bus = dbus.SessionBus()
- self.db_object = self.sessions_bus.get_object(
+ self.conn = await client.connect(reactor)
+ self.db_object = await self.conn.getRemoteObject(
const_INT_PREFIX, const_OBJ_PATH
)
- self.db_core_iface = dbus.Interface(
- self.db_object, dbus_interface=const_INT_PREFIX + const_CORE_SUFFIX
+ # Find the core and plugin interfaces
+ for iface in self.db_object.interfaces:
+ if iface.name == const_INT_PREFIX + const_CORE_SUFFIX:
+ self.db_core_iface = iface
+ elif iface.name == const_INT_PREFIX + const_PLUGIN_SUFFIX:
+ self.db_plugin_iface = iface
+
+ if self.db_core_iface is None:
+ raise BridgeInitError(
+ f"Core interface {const_INT_PREFIX + const_CORE_SUFFIX} not found"
+ )
+ if self.db_plugin_iface is None:
+ raise BridgeInitError(
+ f"Plugin interface {const_INT_PREFIX + const_PLUGIN_SUFFIX} not found"
+ )
+
+ # Initialize signals handler
+ self.signals_handler = SignalsHandler(
+ self.db_object, const_INT_PREFIX + const_PLUGIN_SUFFIX
)
- self.db_plugin_iface = dbus.Interface(
- self.db_object, dbus_interface=const_INT_PREFIX + const_PLUGIN_SUFFIX
- )
- except dbus.exceptions.DBusException as e:
- if e._dbus_error_name in (
- "org.freedesktop.DBus.Error.ServiceUnknown",
- "org.freedesktop.DBus.Error.Spawn.ExecFailed",
+ except BridgeInitError as e:
+ raise e
+ except Exception as e:
+ msg = str(e)
+ if (
+ "org.freedesktop.DBus.Error.ServiceUnknown" in msg
+ or "org.freedesktop.DBus.Error.Spawn.ExecFailed" in msg
):
- errback(BridgeExceptionNoService())
- elif e._dbus_error_name == "org.freedesktop.DBus.Error.NotSupported":
+ raise BridgeExceptionNoService from e
+ elif "org.freedesktop.DBus.Error.NotSupported" in msg:
log.error(
_(
- "D-Bus is not launched, please see README to see instructions on how to launch it"
+ "D-Bus is not launched, please see README to see instructions on"
+ " how to launch it"
)
)
- errback(BridgeInitError)
- else:
- errback(e)
- else:
- callback()
- # props = self.db_core_iface.getProperties()
+ raise BridgeInitError from e
def register_signal(self, functionName, handler, iface="core"):
- if iface == "core":
- self.db_core_iface.connect_to_signal(functionName, handler)
- elif iface == "plugin":
- self.db_plugin_iface.connect_to_signal(functionName, handler)
- else:
- log.error(_("Unknown interface"))
-
- def __getattribute__(self, name):
- """usual __getattribute__ if the method exists, else try to find a plugin method"""
- try:
- return object.__getattribute__(self, name)
- except AttributeError:
- # The attribute is not found, we try the plugin proxy to find the requested method
-
- def get_plugin_method(*args, **kwargs):
- # We first check if we have an async call. We detect this in two ways:
- # - if we have the 'callback' and 'errback' keyword arguments
- # - or if the last two arguments are callable
-
- async_ = False
- args = list(args)
-
- if kwargs:
- if "callback" in kwargs:
- async_ = True
- _callback = kwargs.pop("callback")
- _errback = kwargs.pop(
- "errback", lambda failure: log.error(str(failure))
- )
- try:
- args.append(kwargs.pop("profile"))
- except KeyError:
- try:
- args.append(kwargs.pop("profile_key"))
- except KeyError:
- pass
- # at this point, kwargs should be empty
- if kwargs:
- log.warning(
- "unexpected keyword arguments, they will be ignored: {}".format(
- kwargs
- )
- )
- elif len(args) >= 2 and callable(args[-1]) and callable(args[-2]):
- async_ = True
- _errback = args.pop()
- _callback = args.pop()
-
- method = getattr(self.db_plugin_iface, name)
-
- if async_:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = _callback
- kwargs["error_handler"] = lambda err: _errback(
- dbus_to_bridge_exception(err)
- )
-
- try:
- return method(*args, **kwargs)
- except ValueError as e:
- if e.args[0].startswith("Unable to guess signature"):
- # XXX: if frontend is started too soon after backend, the
- # inspection misses methods (notably plugin dynamically added
- # methods). The following hack works around that by redoing the
- # cache of introspected methods signatures.
- log.debug("using hack to work around inspection issue")
- proxy = self.db_plugin_iface.proxy_object
- IN_PROGRESS = proxy.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS
- proxy._introspect_state = IN_PROGRESS
- proxy._Introspect()
- return self.db_plugin_iface.get_dbus_method(name)(*args, **kwargs)
- raise e
-
- return get_plugin_method
-
- def action_launch(
- self, callback_id, data, profile_key="@DEFAULT@", callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return str(
- self.db_core_iface.action_launch(
- callback_id,
- data,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
- )
-
- def actions_get(self, profile_key="@DEFAULT@", callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.actions_get(profile_key, **kwargs)
-
- def config_get(self, section, name, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return str(self.db_core_iface.config_get(section, name, **kwargs))
-
- def connect(
- self,
- profile_key="@DEFAULT@",
- password="",
- options={},
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.connect(
- profile_key,
- password,
- options,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def contact_add(
- self, entity_jid, profile_key="@DEFAULT@", callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.contact_add(entity_jid, profile_key, **kwargs)
-
- def contact_del(
- self, entity_jid, profile_key="@DEFAULT@", callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.contact_del(
- entity_jid,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def contact_get(self, arg_0, profile_key="@DEFAULT@", callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.contact_get(
- arg_0,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def contact_update(
- self,
- entity_jid,
- name,
- groups,
- profile_key="@DEFAULT@",
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.contact_update(
- entity_jid, name, groups, profile_key, **kwargs
- )
-
- def contacts_get(self, profile_key="@DEFAULT@", callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.contacts_get(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def contacts_get_from_group(
- self, group, profile_key="@DEFAULT@", callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.contacts_get_from_group(group, profile_key, **kwargs)
-
- def devices_infos_get(self, bare_jid, profile_key, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return str(
- self.db_core_iface.devices_infos_get(
- bare_jid,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
- )
-
- def disco_find_by_features(
- self,
- namespaces,
- identities,
- bare_jid=False,
- service=True,
- roster=True,
- own_jid=True,
- local_device=False,
- profile_key="@DEFAULT@",
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.disco_find_by_features(
- namespaces,
- identities,
- bare_jid,
- service,
- roster,
- own_jid,
- local_device,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def disco_infos(
- self,
- entity_jid,
- node="",
- use_cache=True,
- profile_key="@DEFAULT@",
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.disco_infos(
- entity_jid,
- node,
- use_cache,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def disco_items(
- self,
- entity_jid,
- node="",
- use_cache=True,
- profile_key="@DEFAULT@",
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.disco_items(
- entity_jid,
- node,
- use_cache,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def disconnect(self, profile_key="@DEFAULT@", callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.disconnect(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def encryption_namespace_get(self, arg_0, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return str(self.db_core_iface.encryption_namespace_get(arg_0, **kwargs))
-
- def encryption_plugins_get(self, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return str(self.db_core_iface.encryption_plugins_get(**kwargs))
-
- def encryption_trust_ui_get(
- self, to_jid, namespace, profile_key, callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return str(
- self.db_core_iface.encryption_trust_ui_get(
- to_jid,
- namespace,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
- )
-
- def entities_data_get(self, jids, keys, profile, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.entities_data_get(jids, keys, profile, **kwargs)
-
- def entity_data_get(self, jid, keys, profile, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.entity_data_get(jid, keys, profile, **kwargs)
-
- def features_get(self, profile_key, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.features_get(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def history_get(
- self,
- from_jid,
- to_jid,
- limit,
- between=True,
- filters="",
- profile="@NONE@",
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.history_get(
- from_jid,
- to_jid,
- limit,
- between,
- filters,
- profile,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def image_check(self, arg_0, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return str(self.db_core_iface.image_check(arg_0, **kwargs))
-
- def image_convert(self, source, dest, arg_2, extra, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return str(
- self.db_core_iface.image_convert(
- source,
- dest,
- arg_2,
- extra,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
- )
-
- def image_generate_preview(
- self, image_path, profile_key, callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return str(
- self.db_core_iface.image_generate_preview(
- image_path,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
- )
-
- def image_resize(self, image_path, width, height, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return str(
- self.db_core_iface.image_resize(
- image_path,
- width,
- height,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
- )
-
- def init_pre_script(self, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.init_pre_script(
- timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler
- )
-
- def is_connected(self, profile_key="@DEFAULT@", callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.is_connected(profile_key, **kwargs)
-
- def main_resource_get(
- self, contact_jid, profile_key="@DEFAULT@", callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return str(
- self.db_core_iface.main_resource_get(contact_jid, profile_key, **kwargs)
- )
-
- def menu_help_get(self, menu_id, language, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return str(self.db_core_iface.menu_help_get(menu_id, language, **kwargs))
-
- def menu_launch(
- self,
- menu_type,
- path,
- data,
- security_limit,
- profile_key,
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.menu_launch(
- menu_type,
- path,
- data,
- security_limit,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def menus_get(self, language, security_limit, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.menus_get(language, security_limit, **kwargs)
-
- def message_encryption_get(self, to_jid, profile_key, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return str(
- self.db_core_iface.message_encryption_get(to_jid, profile_key, **kwargs)
- )
-
- def message_encryption_start(
- self,
- to_jid,
- namespace="",
- replace=False,
- profile_key="@NONE@",
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.message_encryption_start(
- to_jid,
- namespace,
- replace,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def message_encryption_stop(self, to_jid, profile_key, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.message_encryption_stop(
- to_jid,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def message_send(
- self,
- to_jid,
- message,
- subject={},
- mess_type="auto",
- extra={},
- profile_key="@NONE@",
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.message_send(
- to_jid,
- message,
- subject,
- mess_type,
- extra,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def namespaces_get(self, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.namespaces_get(**kwargs)
-
- def notification_add(
- self,
- type_,
- body_plain,
- body_rich,
- title,
- is_global,
- requires_action,
- arg_6,
- priority,
- expire_at,
- extra,
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.notification_add(
- type_,
- body_plain,
- body_rich,
- title,
- is_global,
- requires_action,
- arg_6,
- priority,
- expire_at,
- extra,
- **kwargs,
- )
-
- def notification_delete(
- self, id_, is_global, profile_key, callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.notification_delete(
- id_, is_global, profile_key, **kwargs
- )
-
- def notifications_expired_clean(
- self, limit_timestamp, profile_key, callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.notifications_expired_clean(
- limit_timestamp, profile_key, **kwargs
- )
-
- def notifications_get(self, filters, profile_key, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return str(self.db_core_iface.notifications_get(filters, profile_key, **kwargs))
-
- def param_get_a(
- self,
- name,
- category,
- attribute="value",
- profile_key="@DEFAULT@",
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return str(
- self.db_core_iface.param_get_a(
- name, category, attribute, profile_key, **kwargs
- )
- )
-
- def param_get_a_async(
- self,
- name,
- category,
- attribute="value",
- security_limit=-1,
- profile_key="@DEFAULT@",
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return str(
- self.db_core_iface.param_get_a_async(
- name,
- category,
- attribute,
- security_limit,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
- )
-
- def param_set(
- self,
- name,
- value,
- category,
- security_limit=-1,
- profile_key="@DEFAULT@",
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.param_set(
- name, value, category, security_limit, profile_key, **kwargs
- )
-
- def param_ui_get(
- self,
- security_limit=-1,
- app="",
- extra="",
- profile_key="@DEFAULT@",
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return str(
- self.db_core_iface.param_ui_get(
- security_limit,
- app,
- extra,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
- )
-
- def params_categories_get(self, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.params_categories_get(**kwargs)
-
- def params_register_app(
- self, xml, security_limit=-1, app="", callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.params_register_app(xml, security_limit, app, **kwargs)
-
- def params_template_load(self, filename, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.params_template_load(filename, **kwargs)
-
- def params_template_save(self, filename, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.params_template_save(filename, **kwargs)
-
- def params_values_from_category_get_async(
- self,
- category,
- security_limit=-1,
- app="",
- extra="",
- profile_key="@DEFAULT@",
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.params_values_from_category_get_async(
- category,
- security_limit,
- app,
- extra,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def presence_set(
- self,
- to_jid="",
- show="",
- statuses={},
- profile_key="@DEFAULT@",
- callback=None,
- errback=None,
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.presence_set(
- to_jid, show, statuses, profile_key, **kwargs
- )
-
- def presence_statuses_get(self, profile_key="@DEFAULT@", callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.presence_statuses_get(profile_key, **kwargs)
-
- def private_data_delete(self, namespace, key, arg_2, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.private_data_delete(
- namespace,
- key,
- arg_2,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def private_data_get(self, namespace, key, profile_key, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return str(
- self.db_core_iface.private_data_get(
- namespace,
- key,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
- )
-
- def private_data_set(
- self, namespace, key, data, profile_key, callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.private_data_set(
- namespace,
- key,
- data,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def profile_create(
- self, profile, password="", component="", callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.profile_create(
- profile,
- password,
- component,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def profile_delete_async(self, profile, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.profile_delete_async(
- profile,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def profile_is_session_started(
- self, profile_key="@DEFAULT@", callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.profile_is_session_started(profile_key, **kwargs)
-
- def profile_name_get(self, profile_key="@DEFAULT@", callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return str(self.db_core_iface.profile_name_get(profile_key, **kwargs))
-
- def profile_set_default(self, profile, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.profile_set_default(profile, **kwargs)
-
- def profile_start_session(
- self, password="", profile_key="@DEFAULT@", callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.profile_start_session(
- password,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def profiles_list_get(
- self, clients=True, components=False, callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.profiles_list_get(clients, components, **kwargs)
-
- def progress_get(self, id, profile, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.progress_get(id, profile, **kwargs)
-
- def progress_get_all(self, profile, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.progress_get_all(profile, **kwargs)
-
- def progress_get_all_metadata(self, profile, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.progress_get_all_metadata(profile, **kwargs)
-
- def ready_get(self, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.ready_get(
- timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler
- )
-
- def roster_resync(self, profile_key="@DEFAULT@", callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.roster_resync(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def session_infos_get(self, profile_key, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return self.db_core_iface.session_infos_get(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
-
- def sub_waiting_get(self, profile_key="@DEFAULT@", callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.sub_waiting_get(profile_key, **kwargs)
-
- def subscription(
- self, sub_type, entity, profile_key="@DEFAULT@", callback=None, errback=None
- ):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return self.db_core_iface.subscription(sub_type, entity, profile_key, **kwargs)
-
- def tor_infos_get(self, extra, profile_key, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return str(
- self.db_core_iface.tor_infos_get(
- extra,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
- )
-
- def tor_mode_get(self, profile_key, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- return str(
- self.db_core_iface.tor_mode_get(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=callback,
- error_handler=error_handler,
- )
- )
-
- def version_get(self, callback=None, errback=None):
- if callback is None:
- error_handler = None
- else:
- if errback is None:
- errback = log.error
- error_handler = lambda err: errback(dbus_to_bridge_exception(err))
- kwargs = {}
- if callback is not None:
- kwargs["timeout"] = const_TIMEOUT
- kwargs["reply_handler"] = callback
- kwargs["error_handler"] = error_handler
- return str(self.db_core_iface.version_get(**kwargs))
-
-
-class AIOBridge(bridge):
-
- async def post_init(self) -> None:
- pass
-
- def register_signal(self, functionName, handler, iface="core"):
- loop = asyncio.get_running_loop()
- async_handler = lambda *args: asyncio.run_coroutine_threadsafe(
- handler(*args), loop
- )
- return super().register_signal(functionName, async_handler, iface)
-
- def __getattribute__(self, name):
- """usual __getattribute__ if the method exists, else try to find a plugin method"""
- try:
- return object.__getattribute__(self, name)
- except AttributeError:
- # The attribute is not found, we try the plugin proxy to find the requested method
- def get_plugin_method(*args, **kwargs):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- method = getattr(self.db_plugin_iface, name)
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(
- fut.set_result, ret
- )
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- try:
- method(
- *args,
- **kwargs,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- except ValueError as e:
- if e.args[0].startswith("Unable to guess signature"):
- # same hack as for bridge.__getattribute__
- log.warning("using hack to work around inspection issue")
- proxy = self.db_plugin_iface.proxy_object
- IN_PROGRESS = proxy.INTROSPECT_STATE_INTROSPECT_IN_PROGRESS
- proxy._introspect_state = IN_PROGRESS
- proxy._Introspect()
- self.db_plugin_iface.get_dbus_method(name)(
- *args,
- **kwargs,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
-
- else:
- raise e
- return fut
-
- return get_plugin_method
-
- def bridge_connect(self):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- super().bridge_connect(
- callback=lambda: loop.call_soon_threadsafe(fut.set_result, None),
- errback=lambda e: loop.call_soon_threadsafe(fut.set_exception, e),
- )
- return fut
+ if self.signals_handler is None:
+ log.error("Bridge not initialized")
+ return
+ self.signals_handler.register_signal(functionName, handler, iface)
def action_launch(self, callback_id, data, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.action_launch(
- callback_id,
- data,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("action_launch", callback_id, data, profile_key)
def actions_get(self, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.actions_get(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("actions_get", profile_key)
def config_get(self, section, name):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.config_get(
- section,
- name,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("config_get", section, name)
def connect(self, profile_key="@DEFAULT@", password="", options={}):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.connect(
- profile_key,
- password,
- options,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("connect", profile_key, password, options)
def contact_add(self, entity_jid, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.contact_add(
- entity_jid,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("contact_add", entity_jid, profile_key)
def contact_del(self, entity_jid, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.contact_del(
- entity_jid,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("contact_del", entity_jid, profile_key)
def contact_get(self, arg_0, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.contact_get(
- arg_0,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("contact_get", arg_0, profile_key)
def contact_update(self, entity_jid, name, groups, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.contact_update(
- entity_jid,
- name,
- groups,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("contact_update", entity_jid, name, groups, profile_key)
def contacts_get(self, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.contacts_get(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("contacts_get", profile_key)
def contacts_get_from_group(self, group, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.contacts_get_from_group(
- group,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("contacts_get_from_group", group, profile_key)
def devices_infos_get(self, bare_jid, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.devices_infos_get(
- bare_jid,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("devices_infos_get", bare_jid, profile_key)
def disco_find_by_features(
self,
@@ -1749,13 +267,8 @@ class AIOBridge(bridge):
local_device=False,
profile_key="@DEFAULT@",
):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.disco_find_by_features(
+ return self.call(
+ "disco_find_by_features",
namespaces,
identities,
bare_jid,
@@ -1764,393 +277,94 @@ class AIOBridge(bridge):
own_jid,
local_device,
profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
)
- return fut
def disco_infos(self, entity_jid, node="", use_cache=True, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.disco_infos(
- entity_jid,
- node,
- use_cache,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("disco_infos", entity_jid, node, use_cache, profile_key)
def disco_items(self, entity_jid, node="", use_cache=True, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.disco_items(
- entity_jid,
- node,
- use_cache,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("disco_items", entity_jid, node, use_cache, profile_key)
def disconnect(self, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.disconnect(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("disconnect", profile_key)
def encryption_namespace_get(self, arg_0):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.encryption_namespace_get(
- arg_0,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("encryption_namespace_get", arg_0)
- def encryption_plugins_get(self):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
+ def encryption_plugins_get(
+ self,
+ ):
+ return self.call(
+ "encryption_plugins_get",
)
- self.db_core_iface.encryption_plugins_get(
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
def encryption_trust_ui_get(self, to_jid, namespace, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.encryption_trust_ui_get(
- to_jid,
- namespace,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("encryption_trust_ui_get", to_jid, namespace, profile_key)
def entities_data_get(self, jids, keys, profile):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.entities_data_get(
- jids,
- keys,
- profile,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("entities_data_get", jids, keys, profile)
def entity_data_get(self, jid, keys, profile):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.entity_data_get(
- jid,
- keys,
- profile,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("entity_data_get", jid, keys, profile)
def features_get(self, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.features_get(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("features_get", profile_key)
def history_get(
self, from_jid, to_jid, limit, between=True, filters="", profile="@NONE@"
):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
+ return self.call(
+ "history_get", from_jid, to_jid, limit, between, filters, profile
)
- self.db_core_iface.history_get(
- from_jid,
- to_jid,
- limit,
- between,
- filters,
- profile,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
def image_check(self, arg_0):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.image_check(
- arg_0,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("image_check", arg_0)
def image_convert(self, source, dest, arg_2, extra):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.image_convert(
- source,
- dest,
- arg_2,
- extra,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("image_convert", source, dest, arg_2, extra)
def image_generate_preview(self, image_path, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.image_generate_preview(
- image_path,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("image_generate_preview", image_path, profile_key)
def image_resize(self, image_path, width, height):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.image_resize(
- image_path,
- width,
- height,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("image_resize", image_path, width, height)
- def init_pre_script(self):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
+ def init_pre_script(
+ self,
+ ):
+ return self.call(
+ "init_pre_script",
)
- self.db_core_iface.init_pre_script(
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
def is_connected(self, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.is_connected(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("is_connected", profile_key)
def main_resource_get(self, contact_jid, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.main_resource_get(
- contact_jid,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("main_resource_get", contact_jid, profile_key)
def menu_help_get(self, menu_id, language):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.menu_help_get(
- menu_id,
- language,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("menu_help_get", menu_id, language)
def menu_launch(self, menu_type, path, data, security_limit, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
+ return self.call(
+ "menu_launch", menu_type, path, data, security_limit, profile_key
)
- self.db_core_iface.menu_launch(
- menu_type,
- path,
- data,
- security_limit,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
def menus_get(self, language, security_limit):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.menus_get(
- language,
- security_limit,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("menus_get", language, security_limit)
def message_encryption_get(self, to_jid, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.message_encryption_get(
- to_jid,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("message_encryption_get", to_jid, profile_key)
def message_encryption_start(
self, to_jid, namespace="", replace=False, profile_key="@NONE@"
):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
+ return self.call(
+ "message_encryption_start", to_jid, namespace, replace, profile_key
)
- self.db_core_iface.message_encryption_start(
- to_jid,
- namespace,
- replace,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
def message_encryption_stop(self, to_jid, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.message_encryption_stop(
- to_jid,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("message_encryption_stop", to_jid, profile_key)
def message_send(
self,
@@ -2161,38 +375,16 @@ class AIOBridge(bridge):
extra={},
profile_key="@NONE@",
):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
+ return self.call(
+ "message_send", to_jid, message, subject, mess_type, extra, profile_key
)
- self.db_core_iface.message_send(
- to_jid,
- message,
- subject,
- mess_type,
- extra,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
- def namespaces_get(self):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
+ def namespaces_get(
+ self,
+ ):
+ return self.call(
+ "namespaces_get",
)
- self.db_core_iface.namespaces_get(
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
def notification_add(
self,
@@ -2207,13 +399,8 @@ class AIOBridge(bridge):
expire_at,
extra,
):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.notification_add(
+ return self.call(
+ "notification_add",
type_,
body_plain,
body_rich,
@@ -2224,78 +411,19 @@ class AIOBridge(bridge):
priority,
expire_at,
extra,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
)
- return fut
def notification_delete(self, id_, is_global, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.notification_delete(
- id_,
- is_global,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("notification_delete", id_, is_global, profile_key)
def notifications_expired_clean(self, limit_timestamp, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.notifications_expired_clean(
- limit_timestamp,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("notifications_expired_clean", limit_timestamp, profile_key)
def notifications_get(self, filters, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.notifications_get(
- filters,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("notifications_get", filters, profile_key)
def param_get_a(self, name, category, attribute="value", profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.param_get_a(
- name,
- category,
- attribute,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("param_get_a", name, category, attribute, profile_key)
def param_get_a_async(
self,
@@ -2305,502 +433,901 @@ class AIOBridge(bridge):
security_limit=-1,
profile_key="@DEFAULT@",
):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
+ return self.call(
+ "param_get_a_async", name, category, attribute, security_limit, profile_key
)
- self.db_core_iface.param_get_a_async(
- name,
- category,
- attribute,
- security_limit,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
def param_set(
self, name, value, category, security_limit=-1, profile_key="@DEFAULT@"
):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.param_set(
- name,
- value,
- category,
- security_limit,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("param_set", name, value, category, security_limit, profile_key)
def param_ui_get(self, security_limit=-1, app="", extra="", profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.param_ui_get(
- security_limit,
- app,
- extra,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("param_ui_get", security_limit, app, extra, profile_key)
- def params_categories_get(self):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
+ def params_categories_get(
+ self,
+ ):
+ return self.call(
+ "params_categories_get",
)
- self.db_core_iface.params_categories_get(
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
def params_register_app(self, xml, security_limit=-1, app=""):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.params_register_app(
- xml,
- security_limit,
- app,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("params_register_app", xml, security_limit, app)
def params_template_load(self, filename):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.params_template_load(
- filename,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("params_template_load", filename)
def params_template_save(self, filename):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.params_template_save(
- filename,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("params_template_save", filename)
def params_values_from_category_get_async(
self, category, security_limit=-1, app="", extra="", profile_key="@DEFAULT@"
):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.params_values_from_category_get_async(
+ return self.call(
+ "params_values_from_category_get_async",
category,
security_limit,
app,
extra,
profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
)
- return fut
def presence_set(self, to_jid="", show="", statuses={}, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.presence_set(
- to_jid,
- show,
- statuses,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("presence_set", to_jid, show, statuses, profile_key)
def presence_statuses_get(self, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.presence_statuses_get(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("presence_statuses_get", profile_key)
def private_data_delete(self, namespace, key, arg_2):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.private_data_delete(
- namespace,
- key,
- arg_2,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("private_data_delete", namespace, key, arg_2)
def private_data_get(self, namespace, key, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.private_data_get(
- namespace,
- key,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("private_data_get", namespace, key, profile_key)
def private_data_set(self, namespace, key, data, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.private_data_set(
- namespace,
- key,
- data,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("private_data_set", namespace, key, data, profile_key)
def profile_create(self, profile, password="", component=""):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.profile_create(
- profile,
- password,
- component,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("profile_create", profile, password, component)
def profile_delete_async(self, profile):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.profile_delete_async(
- profile,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("profile_delete_async", profile)
def profile_is_session_started(self, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.profile_is_session_started(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("profile_is_session_started", profile_key)
def profile_name_get(self, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.profile_name_get(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("profile_name_get", profile_key)
def profile_set_default(self, profile):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.profile_set_default(
- profile,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("profile_set_default", profile)
def profile_start_session(self, password="", profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.profile_start_session(
- password,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("profile_start_session", password, profile_key)
def profiles_list_get(self, clients=True, components=False):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.profiles_list_get(
- clients,
- components,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("profiles_list_get", clients, components)
def progress_get(self, id, profile):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.progress_get(
- id,
- profile,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("progress_get", id, profile)
def progress_get_all(self, profile):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.progress_get_all(
- profile,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("progress_get_all", profile)
def progress_get_all_metadata(self, profile):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.progress_get_all_metadata(
- profile,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("progress_get_all_metadata", profile)
- def ready_get(self):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
+ def ready_get(
+ self,
+ ):
+ return self.call(
+ "ready_get",
)
- self.db_core_iface.ready_get(
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
def roster_resync(self, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.roster_resync(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("roster_resync", profile_key)
def session_infos_get(self, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.session_infos_get(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("session_infos_get", profile_key)
def sub_waiting_get(self, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.sub_waiting_get(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("sub_waiting_get", profile_key)
def subscription(self, sub_type, entity, profile_key="@DEFAULT@"):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.subscription(
- sub_type,
- entity,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("subscription", sub_type, entity, profile_key)
def tor_infos_get(self, extra, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.tor_infos_get(
- extra,
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("tor_infos_get", extra, profile_key)
def tor_mode_get(self, profile_key):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
- )
- self.db_core_iface.tor_mode_get(
- profile_key,
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
- )
- return fut
+ return self.call("tor_mode_get", profile_key)
- def version_get(self):
- loop = asyncio.get_running_loop()
- fut = loop.create_future()
- reply_handler = lambda ret=None: loop.call_soon_threadsafe(fut.set_result, ret)
- error_handler = lambda err: loop.call_soon_threadsafe(
- fut.set_exception, dbus_to_bridge_exception(err)
+ def version_get(
+ self,
+ ):
+ return self.call(
+ "version_get",
)
- self.db_core_iface.version_get(
- timeout=const_TIMEOUT,
- reply_handler=reply_handler,
- error_handler=error_handler,
+
+
+class AIOSignalsHandler(SignalsHandler):
+
+ def register_signal(self, name, handler, iface="core"):
+ """Register an async signal handler."""
+ async_handler = lambda *args: asyncio.ensure_future(handler(*args))
+ return super().register_signal(name, async_handler, iface)
+
+ async def action_launch(self, callback_id, data, profile_key="@DEFAULT@"):
+ return await self.call("action_launch", callback_id, data, profile_key)
+
+ async def actions_get(self, profile_key="@DEFAULT@"):
+ return await self.call("actions_get", profile_key)
+
+ async def config_get(self, section, name):
+ return await self.call("config_get", section, name)
+
+ async def connect(self, profile_key="@DEFAULT@", password="", options={}):
+ return await self.call("connect", profile_key, password, options)
+
+ async def contact_add(self, entity_jid, profile_key="@DEFAULT@"):
+ return await self.call("contact_add", entity_jid, profile_key)
+
+ async def contact_del(self, entity_jid, profile_key="@DEFAULT@"):
+ return await self.call("contact_del", entity_jid, profile_key)
+
+ async def contact_get(self, arg_0, profile_key="@DEFAULT@"):
+ return await self.call("contact_get", arg_0, profile_key)
+
+ async def contact_update(self, entity_jid, name, groups, profile_key="@DEFAULT@"):
+ return await self.call("contact_update", entity_jid, name, groups, profile_key)
+
+ async def contacts_get(self, profile_key="@DEFAULT@"):
+ return await self.call("contacts_get", profile_key)
+
+ async def contacts_get_from_group(self, group, profile_key="@DEFAULT@"):
+ return await self.call("contacts_get_from_group", group, profile_key)
+
+ async def devices_infos_get(self, bare_jid, profile_key):
+ return await self.call("devices_infos_get", bare_jid, profile_key)
+
+ async def disco_find_by_features(
+ self,
+ namespaces,
+ identities,
+ bare_jid=False,
+ service=True,
+ roster=True,
+ own_jid=True,
+ local_device=False,
+ profile_key="@DEFAULT@",
+ ):
+ return await self.call(
+ "disco_find_by_features",
+ namespaces,
+ identities,
+ bare_jid,
+ service,
+ roster,
+ own_jid,
+ local_device,
+ profile_key,
+ )
+
+ async def disco_infos(
+ self, entity_jid, node="", use_cache=True, profile_key="@DEFAULT@"
+ ):
+ return await self.call("disco_infos", entity_jid, node, use_cache, profile_key)
+
+ async def disco_items(
+ self, entity_jid, node="", use_cache=True, profile_key="@DEFAULT@"
+ ):
+ return await self.call("disco_items", entity_jid, node, use_cache, profile_key)
+
+ async def disconnect(self, profile_key="@DEFAULT@"):
+ return await self.call("disconnect", profile_key)
+
+ async def encryption_namespace_get(self, arg_0):
+ return await self.call("encryption_namespace_get", arg_0)
+
+ async def encryption_plugins_get(
+ self,
+ ):
+ return await self.call(
+ "encryption_plugins_get",
+ )
+
+ async def encryption_trust_ui_get(self, to_jid, namespace, profile_key):
+ return await self.call("encryption_trust_ui_get", to_jid, namespace, profile_key)
+
+ async def entities_data_get(self, jids, keys, profile):
+ return await self.call("entities_data_get", jids, keys, profile)
+
+ async def entity_data_get(self, jid, keys, profile):
+ return await self.call("entity_data_get", jid, keys, profile)
+
+ async def features_get(self, profile_key):
+ return await self.call("features_get", profile_key)
+
+ async def history_get(
+ self, from_jid, to_jid, limit, between=True, filters="", profile="@NONE@"
+ ):
+ return await self.call(
+ "history_get", from_jid, to_jid, limit, between, filters, profile
+ )
+
+ async def image_check(self, arg_0):
+ return await self.call("image_check", arg_0)
+
+ async def image_convert(self, source, dest, arg_2, extra):
+ return await self.call("image_convert", source, dest, arg_2, extra)
+
+ async def image_generate_preview(self, image_path, profile_key):
+ return await self.call("image_generate_preview", image_path, profile_key)
+
+ async def image_resize(self, image_path, width, height):
+ return await self.call("image_resize", image_path, width, height)
+
+ async def init_pre_script(
+ self,
+ ):
+ return await self.call(
+ "init_pre_script",
+ )
+
+ async def is_connected(self, profile_key="@DEFAULT@"):
+ return await self.call("is_connected", profile_key)
+
+ async def main_resource_get(self, contact_jid, profile_key="@DEFAULT@"):
+ return await self.call("main_resource_get", contact_jid, profile_key)
+
+ async def menu_help_get(self, menu_id, language):
+ return await self.call("menu_help_get", menu_id, language)
+
+ async def menu_launch(self, menu_type, path, data, security_limit, profile_key):
+ return await self.call(
+ "menu_launch", menu_type, path, data, security_limit, profile_key
+ )
+
+ async def menus_get(self, language, security_limit):
+ return await self.call("menus_get", language, security_limit)
+
+ async def message_encryption_get(self, to_jid, profile_key):
+ return await self.call("message_encryption_get", to_jid, profile_key)
+
+ async def message_encryption_start(
+ self, to_jid, namespace="", replace=False, profile_key="@NONE@"
+ ):
+ return await self.call(
+ "message_encryption_start", to_jid, namespace, replace, profile_key
+ )
+
+ async def message_encryption_stop(self, to_jid, profile_key):
+ return await self.call("message_encryption_stop", to_jid, profile_key)
+
+ async def message_send(
+ self,
+ to_jid,
+ message,
+ subject={},
+ mess_type="auto",
+ extra={},
+ profile_key="@NONE@",
+ ):
+ return await self.call(
+ "message_send", to_jid, message, subject, mess_type, extra, profile_key
+ )
+
+ async def namespaces_get(
+ self,
+ ):
+ return await self.call(
+ "namespaces_get",
+ )
+
+ async def notification_add(
+ self,
+ type_,
+ body_plain,
+ body_rich,
+ title,
+ is_global,
+ requires_action,
+ arg_6,
+ priority,
+ expire_at,
+ extra,
+ ):
+ return await self.call(
+ "notification_add",
+ type_,
+ body_plain,
+ body_rich,
+ title,
+ is_global,
+ requires_action,
+ arg_6,
+ priority,
+ expire_at,
+ extra,
+ )
+
+ async def notification_delete(self, id_, is_global, profile_key):
+ return await self.call("notification_delete", id_, is_global, profile_key)
+
+ async def notifications_expired_clean(self, limit_timestamp, profile_key):
+ return await self.call(
+ "notifications_expired_clean", limit_timestamp, profile_key
+ )
+
+ async def notifications_get(self, filters, profile_key):
+ return await self.call("notifications_get", filters, profile_key)
+
+ async def param_get_a(
+ self, name, category, attribute="value", profile_key="@DEFAULT@"
+ ):
+ return await self.call("param_get_a", name, category, attribute, profile_key)
+
+ async def param_get_a_async(
+ self,
+ name,
+ category,
+ attribute="value",
+ security_limit=-1,
+ profile_key="@DEFAULT@",
+ ):
+ return await self.call(
+ "param_get_a_async", name, category, attribute, security_limit, profile_key
+ )
+
+ async def param_set(
+ self, name, value, category, security_limit=-1, profile_key="@DEFAULT@"
+ ):
+ return await self.call(
+ "param_set", name, value, category, security_limit, profile_key
+ )
+
+ async def param_ui_get(
+ self, security_limit=-1, app="", extra="", profile_key="@DEFAULT@"
+ ):
+ return await self.call("param_ui_get", security_limit, app, extra, profile_key)
+
+ async def params_categories_get(
+ self,
+ ):
+ return await self.call(
+ "params_categories_get",
+ )
+
+ async def params_register_app(self, xml, security_limit=-1, app=""):
+ return await self.call("params_register_app", xml, security_limit, app)
+
+ async def params_template_load(self, filename):
+ return await self.call("params_template_load", filename)
+
+ async def params_template_save(self, filename):
+ return await self.call("params_template_save", filename)
+
+ async def params_values_from_category_get_async(
+ self, category, security_limit=-1, app="", extra="", profile_key="@DEFAULT@"
+ ):
+ return await self.call(
+ "params_values_from_category_get_async",
+ category,
+ security_limit,
+ app,
+ extra,
+ profile_key,
+ )
+
+ async def presence_set(
+ self, to_jid="", show="", statuses={}, profile_key="@DEFAULT@"
+ ):
+ return await self.call("presence_set", to_jid, show, statuses, profile_key)
+
+ async def presence_statuses_get(self, profile_key="@DEFAULT@"):
+ return await self.call("presence_statuses_get", profile_key)
+
+ async def private_data_delete(self, namespace, key, arg_2):
+ return await self.call("private_data_delete", namespace, key, arg_2)
+
+ async def private_data_get(self, namespace, key, profile_key):
+ return await self.call("private_data_get", namespace, key, profile_key)
+
+ async def private_data_set(self, namespace, key, data, profile_key):
+ return await self.call("private_data_set", namespace, key, data, profile_key)
+
+ async def profile_create(self, profile, password="", component=""):
+ return await self.call("profile_create", profile, password, component)
+
+ async def profile_delete_async(self, profile):
+ return await self.call("profile_delete_async", profile)
+
+ async def profile_is_session_started(self, profile_key="@DEFAULT@"):
+ return await self.call("profile_is_session_started", profile_key)
+
+ async def profile_name_get(self, profile_key="@DEFAULT@"):
+ return await self.call("profile_name_get", profile_key)
+
+ async def profile_set_default(self, profile):
+ return await self.call("profile_set_default", profile)
+
+ async def profile_start_session(self, password="", profile_key="@DEFAULT@"):
+ return await self.call("profile_start_session", password, profile_key)
+
+ async def profiles_list_get(self, clients=True, components=False):
+ return await self.call("profiles_list_get", clients, components)
+
+ async def progress_get(self, id, profile):
+ return await self.call("progress_get", id, profile)
+
+ async def progress_get_all(self, profile):
+ return await self.call("progress_get_all", profile)
+
+ async def progress_get_all_metadata(self, profile):
+ return await self.call("progress_get_all_metadata", profile)
+
+ async def ready_get(
+ self,
+ ):
+ return await self.call(
+ "ready_get",
+ )
+
+ async def roster_resync(self, profile_key="@DEFAULT@"):
+ return await self.call("roster_resync", profile_key)
+
+ async def session_infos_get(self, profile_key):
+ return await self.call("session_infos_get", profile_key)
+
+ async def sub_waiting_get(self, profile_key="@DEFAULT@"):
+ return await self.call("sub_waiting_get", profile_key)
+
+ async def subscription(self, sub_type, entity, profile_key="@DEFAULT@"):
+ return await self.call("subscription", sub_type, entity, profile_key)
+
+ async def tor_infos_get(self, extra, profile_key):
+ return await self.call("tor_infos_get", extra, profile_key)
+
+ async def tor_mode_get(self, profile_key):
+ return await self.call("tor_mode_get", profile_key)
+
+ async def version_get(
+ self,
+ ):
+ return await self.call(
+ "version_get",
+ )
+
+
+class AIOBridge(bridge):
+
+ def __init__(self):
+ super().__init__()
+ self.signals_handler = None
+
+ async def post_init(self):
+ """Post-initialization hook.
+
+ Actually no post init is needed, but the "__getattr__" return "partial" for
+ unknown methods, and this causes "dynamic_import.load_and_init_bridge" to fail.
+ """
+ pass
+
+ def call(self, name: str, *args, **kwargs):
+ """Call a remote method and return an awaitable.
+
+ @param name: name of the bridge method
+ """
+ d = super().call(name, *args, **kwargs)
+ return d.asFuture(asyncio.get_event_loop())
+
+ async def bridge_connect(self):
+ """Connect to the D-Bus bridge (async version)."""
+ try:
+ self.conn = await client.connect(reactor).asFuture(asyncio.get_event_loop())
+ self.db_object = await self.conn.getRemoteObject(
+ const_INT_PREFIX, const_OBJ_PATH
+ ).asFuture(asyncio.get_event_loop())
+
+ # Find the core and plugin interfaces
+ for iface in self.db_object.interfaces:
+ if iface.name == const_INT_PREFIX + const_CORE_SUFFIX:
+ self.db_core_iface = iface
+ elif iface.name == const_INT_PREFIX + const_PLUGIN_SUFFIX:
+ self.db_plugin_iface = iface
+
+ if self.db_core_iface is None:
+ raise BridgeInitError(
+ f"Core interface {const_INT_PREFIX + const_CORE_SUFFIX} not found"
+ )
+ if self.db_plugin_iface is None:
+ raise BridgeInitError(
+ f"Plugin interface {const_INT_PREFIX + const_PLUGIN_SUFFIX} not found"
+ )
+
+ # Initialize signals handler
+ self.signals_handler = AIOSignalsHandler(
+ self.db_object, const_INT_PREFIX + const_PLUGIN_SUFFIX
+ )
+ except BridgeInitError as e:
+ raise e
+ except Exception as e:
+ msg = str(e)
+ if (
+ "org.freedesktop.DBus.Error.ServiceUnknown" in msg
+ or "org.freedesktop.DBus.Error.Spawn.ExecFailed" in msg
+ ):
+ raise BridgeExceptionNoService from e
+ elif "org.freedesktop.DBus.Error.NotSupported" in msg:
+ log.error(
+ _(
+ "D-Bus is not launched, please see README to see instructions on"
+ " how to launch it"
+ )
+ )
+ raise BridgeInitError from e
+
+ def register_signal(self, functionName, handler, iface="core"):
+ if self.signals_handler is None:
+ log.error("Bridge not initialized")
+ return
+ self.signals_handler.register_signal(functionName, handler, iface)
+
+
+class TwistedBridge(bridge):
+
+ async def post_init(self):
+ """Post-initialization hook.
+
+ Actually no post init is needed, but the "__getattr__" return "partial" for
+ unknown methods, and this causes "dynamic_import.load_and_init_bridge" to fail.
+ """
+ pass
+
+ def _errback(self, failure_):
+ """Convert Failure to BridgeException"""
+ raise dbus_to_bridge_exception(failure_)
+
+ def call(self, name, *args, **kwargs):
+ """Call a remote method and return a Deferred.
+
+ @param name(str): name of the bridge method
+ @param args(list): arguments
+ @param kwargs(dict): keyword arguments (profile, etc.)
+ """
+ return super().call(name, *args, **kwargs)
+
+ async def bridge_connect(self) -> None:
+ """Connect to the D-Bus bridge."""
+ return await super().bridge_connect()
+
+ def register_signal(self, functionName, handler, iface="core"):
+ super().register_signal(functionName, handler, iface)
+
+ def action_launch(self, callback_id, data, profile_key="@DEFAULT@"):
+ return self.call("action_launch", callback_id, data, profile_key)
+
+ def actions_get(self, profile_key="@DEFAULT@"):
+ return self.call("actions_get", profile_key)
+
+ def config_get(self, section, name):
+ return self.call("config_get", section, name)
+
+ def connect(self, profile_key="@DEFAULT@", password="", options={}):
+ return self.call("connect", profile_key, password, options)
+
+ def contact_add(self, entity_jid, profile_key="@DEFAULT@"):
+ return self.call("contact_add", entity_jid, profile_key)
+
+ def contact_del(self, entity_jid, profile_key="@DEFAULT@"):
+ return self.call("contact_del", entity_jid, profile_key)
+
+ def contact_get(self, arg_0, profile_key="@DEFAULT@"):
+ return self.call("contact_get", arg_0, profile_key)
+
+ def contact_update(self, entity_jid, name, groups, profile_key="@DEFAULT@"):
+ return self.call("contact_update", entity_jid, name, groups, profile_key)
+
+ def contacts_get(self, profile_key="@DEFAULT@"):
+ return self.call("contacts_get", profile_key)
+
+ def contacts_get_from_group(self, group, profile_key="@DEFAULT@"):
+ return self.call("contacts_get_from_group", group, profile_key)
+
+ def devices_infos_get(self, bare_jid, profile_key):
+ return self.call("devices_infos_get", bare_jid, profile_key)
+
+ def disco_find_by_features(
+ self,
+ namespaces,
+ identities,
+ bare_jid=False,
+ service=True,
+ roster=True,
+ own_jid=True,
+ local_device=False,
+ profile_key="@DEFAULT@",
+ ):
+ return self.call(
+ "disco_find_by_features",
+ namespaces,
+ identities,
+ bare_jid,
+ service,
+ roster,
+ own_jid,
+ local_device,
+ profile_key,
+ )
+
+ def disco_infos(self, entity_jid, node="", use_cache=True, profile_key="@DEFAULT@"):
+ return self.call("disco_infos", entity_jid, node, use_cache, profile_key)
+
+ def disco_items(self, entity_jid, node="", use_cache=True, profile_key="@DEFAULT@"):
+ return self.call("disco_items", entity_jid, node, use_cache, profile_key)
+
+ def disconnect(self, profile_key="@DEFAULT@"):
+ return self.call("disconnect", profile_key)
+
+ def encryption_namespace_get(self, arg_0):
+ return self.call("encryption_namespace_get", arg_0)
+
+ def encryption_plugins_get(
+ self,
+ ):
+ return self.call(
+ "encryption_plugins_get",
+ )
+
+ def encryption_trust_ui_get(self, to_jid, namespace, profile_key):
+ return self.call("encryption_trust_ui_get", to_jid, namespace, profile_key)
+
+ def entities_data_get(self, jids, keys, profile):
+ return self.call("entities_data_get", jids, keys, profile)
+
+ def entity_data_get(self, jid, keys, profile):
+ return self.call("entity_data_get", jid, keys, profile)
+
+ def features_get(self, profile_key):
+ return self.call("features_get", profile_key)
+
+ def history_get(
+ self, from_jid, to_jid, limit, between=True, filters="", profile="@NONE@"
+ ):
+ return self.call(
+ "history_get", from_jid, to_jid, limit, between, filters, profile
+ )
+
+ def image_check(self, arg_0):
+ return self.call("image_check", arg_0)
+
+ def image_convert(self, source, dest, arg_2, extra):
+ return self.call("image_convert", source, dest, arg_2, extra)
+
+ def image_generate_preview(self, image_path, profile_key):
+ return self.call("image_generate_preview", image_path, profile_key)
+
+ def image_resize(self, image_path, width, height):
+ return self.call("image_resize", image_path, width, height)
+
+ def init_pre_script(
+ self,
+ ):
+ return self.call(
+ "init_pre_script",
+ )
+
+ def is_connected(self, profile_key="@DEFAULT@"):
+ return self.call("is_connected", profile_key)
+
+ def main_resource_get(self, contact_jid, profile_key="@DEFAULT@"):
+ return self.call("main_resource_get", contact_jid, profile_key)
+
+ def menu_help_get(self, menu_id, language):
+ return self.call("menu_help_get", menu_id, language)
+
+ def menu_launch(self, menu_type, path, data, security_limit, profile_key):
+ return self.call(
+ "menu_launch", menu_type, path, data, security_limit, profile_key
+ )
+
+ def menus_get(self, language, security_limit):
+ return self.call("menus_get", language, security_limit)
+
+ def message_encryption_get(self, to_jid, profile_key):
+ return self.call("message_encryption_get", to_jid, profile_key)
+
+ def message_encryption_start(
+ self, to_jid, namespace="", replace=False, profile_key="@NONE@"
+ ):
+ return self.call(
+ "message_encryption_start", to_jid, namespace, replace, profile_key
+ )
+
+ def message_encryption_stop(self, to_jid, profile_key):
+ return self.call("message_encryption_stop", to_jid, profile_key)
+
+ def message_send(
+ self,
+ to_jid,
+ message,
+ subject={},
+ mess_type="auto",
+ extra={},
+ profile_key="@NONE@",
+ ):
+ return self.call(
+ "message_send", to_jid, message, subject, mess_type, extra, profile_key
+ )
+
+ def namespaces_get(
+ self,
+ ):
+ return self.call(
+ "namespaces_get",
+ )
+
+ def notification_add(
+ self,
+ type_,
+ body_plain,
+ body_rich,
+ title,
+ is_global,
+ requires_action,
+ arg_6,
+ priority,
+ expire_at,
+ extra,
+ ):
+ return self.call(
+ "notification_add",
+ type_,
+ body_plain,
+ body_rich,
+ title,
+ is_global,
+ requires_action,
+ arg_6,
+ priority,
+ expire_at,
+ extra,
+ )
+
+ def notification_delete(self, id_, is_global, profile_key):
+ return self.call("notification_delete", id_, is_global, profile_key)
+
+ def notifications_expired_clean(self, limit_timestamp, profile_key):
+ return self.call("notifications_expired_clean", limit_timestamp, profile_key)
+
+ def notifications_get(self, filters, profile_key):
+ return self.call("notifications_get", filters, profile_key)
+
+ def param_get_a(self, name, category, attribute="value", profile_key="@DEFAULT@"):
+ return self.call("param_get_a", name, category, attribute, profile_key)
+
+ def param_get_a_async(
+ self,
+ name,
+ category,
+ attribute="value",
+ security_limit=-1,
+ profile_key="@DEFAULT@",
+ ):
+ return self.call(
+ "param_get_a_async", name, category, attribute, security_limit, profile_key
+ )
+
+ def param_set(
+ self, name, value, category, security_limit=-1, profile_key="@DEFAULT@"
+ ):
+ return self.call("param_set", name, value, category, security_limit, profile_key)
+
+ def param_ui_get(self, security_limit=-1, app="", extra="", profile_key="@DEFAULT@"):
+ return self.call("param_ui_get", security_limit, app, extra, profile_key)
+
+ def params_categories_get(
+ self,
+ ):
+ return self.call(
+ "params_categories_get",
+ )
+
+ def params_register_app(self, xml, security_limit=-1, app=""):
+ return self.call("params_register_app", xml, security_limit, app)
+
+ def params_template_load(self, filename):
+ return self.call("params_template_load", filename)
+
+ def params_template_save(self, filename):
+ return self.call("params_template_save", filename)
+
+ def params_values_from_category_get_async(
+ self, category, security_limit=-1, app="", extra="", profile_key="@DEFAULT@"
+ ):
+ return self.call(
+ "params_values_from_category_get_async",
+ category,
+ security_limit,
+ app,
+ extra,
+ profile_key,
+ )
+
+ def presence_set(self, to_jid="", show="", statuses={}, profile_key="@DEFAULT@"):
+ return self.call("presence_set", to_jid, show, statuses, profile_key)
+
+ def presence_statuses_get(self, profile_key="@DEFAULT@"):
+ return self.call("presence_statuses_get", profile_key)
+
+ def private_data_delete(self, namespace, key, arg_2):
+ return self.call("private_data_delete", namespace, key, arg_2)
+
+ def private_data_get(self, namespace, key, profile_key):
+ return self.call("private_data_get", namespace, key, profile_key)
+
+ def private_data_set(self, namespace, key, data, profile_key):
+ return self.call("private_data_set", namespace, key, data, profile_key)
+
+ def profile_create(self, profile, password="", component=""):
+ return self.call("profile_create", profile, password, component)
+
+ def profile_delete_async(self, profile):
+ return self.call("profile_delete_async", profile)
+
+ def profile_is_session_started(self, profile_key="@DEFAULT@"):
+ return self.call("profile_is_session_started", profile_key)
+
+ def profile_name_get(self, profile_key="@DEFAULT@"):
+ return self.call("profile_name_get", profile_key)
+
+ def profile_set_default(self, profile):
+ return self.call("profile_set_default", profile)
+
+ def profile_start_session(self, password="", profile_key="@DEFAULT@"):
+ return self.call("profile_start_session", password, profile_key)
+
+ def profiles_list_get(self, clients=True, components=False):
+ return self.call("profiles_list_get", clients, components)
+
+ def progress_get(self, id, profile):
+ return self.call("progress_get", id, profile)
+
+ def progress_get_all(self, profile):
+ return self.call("progress_get_all", profile)
+
+ def progress_get_all_metadata(self, profile):
+ return self.call("progress_get_all_metadata", profile)
+
+ def ready_get(
+ self,
+ ):
+ return self.call(
+ "ready_get",
+ )
+
+ def roster_resync(self, profile_key="@DEFAULT@"):
+ return self.call("roster_resync", profile_key)
+
+ def session_infos_get(self, profile_key):
+ return self.call("session_infos_get", profile_key)
+
+ def sub_waiting_get(self, profile_key="@DEFAULT@"):
+ return self.call("sub_waiting_get", profile_key)
+
+ def subscription(self, sub_type, entity, profile_key="@DEFAULT@"):
+ return self.call("subscription", sub_type, entity, profile_key)
+
+ def tor_infos_get(self, extra, profile_key):
+ return self.call("tor_infos_get", extra, profile_key)
+
+ def tor_mode_get(self, profile_key):
+ return self.call("tor_mode_get", profile_key)
+
+ def version_get(
+ self,
+ ):
+ return self.call(
+ "version_get",
)
- return fut