view libervia/frontends/bridge/dbus_bridge.py @ 4118:07370d2a9bde

plugin XEP-0167: keep media order when starting a call: media content order is relevant when building Jingle contents/SDP notably for bundling. This patch fixes the previous behaviour of always using the same order by keeping the order of the data (i.e. order of original SDP offer). Previous behaviour could lead to call failure. rel 424
author Goffi <goffi@goffi.org>
date Tue, 03 Oct 2023 15:15:24 +0200
parents 26b7ed2817da
children 02f0adc745c6
line wrap: on
line source

#!/usr/bin/env python3

# SàT communication bridge
# Copyright (C) 2009-2021 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
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.

# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.

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 .bridge_frontend import BridgeException


DBusGMainLoop(set_as_default=True)
log = getLogger(__name__)


# Interface prefix
const_INT_PREFIX = config.config_get(
    config.parse_main_conf(),
    "",
    "bridge_dbus_int_prefix",
    "org.libervia.Libervia")
const_ERROR_PREFIX = const_INT_PREFIX + ".error"
const_OBJ_PATH = '/org/libervia/Libervia/bridge'
const_CORE_SUFFIX = ".core"
const_PLUGIN_SUFFIX = ".plugin"
const_TIMEOUT = 120


def dbus_to_bridge_exception(dbus_e):
    """Convert a DBusException to a BridgeException.

    @param dbus_e (DBusException)
    @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:]
    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)


class bridge:

    def bridge_connect(self, callback, errback):
        try:
            self.sessions_bus = dbus.SessionBus()
            self.db_object = self.sessions_bus.get_object(const_INT_PREFIX,
                                                          const_OBJ_PATH)
            self.db_core_iface = dbus.Interface(self.db_object,
                                                dbus_interface=const_INT_PREFIX + const_CORE_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'):
                errback(BridgeExceptionNoService())
            elif e._dbus_error_name == 'org.freedesktop.DBus.Error.NotSupported':
                log.error(_("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()

    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=u'', 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=u'', 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 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 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 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):

    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 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

    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

    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

    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

    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

    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

    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

    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

    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

    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

    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

    def disco_find_by_features(self, namespaces, identities, bare_jid=False, service=True, roster=True, own_jid=True, 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(namespaces, identities, bare_jid, service, roster, 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=u'', 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

    def disco_items(self, entity_jid, node=u'', 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

    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

    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

    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))
        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

    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

    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

    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

    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))
        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

    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

    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

    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

    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

    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

    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

    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))
        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

    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

    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))
        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

    def message_send(self, to_jid, message, subject={}, mess_type="auto", 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))
        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))
        self.db_core_iface.namespaces_get(timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler)
        return fut

    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

    def param_get_a_async(self, name, category, attribute="value", 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_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

    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

    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))
        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

    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

    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

    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(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

    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

    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

    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

    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

    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

    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

    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

    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

    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

    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

    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

    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

    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

    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

    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))
        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

    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

    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

    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

    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))
        self.db_core_iface.version_get(timeout=const_TIMEOUT, reply_handler=reply_handler, error_handler=error_handler)
        return fut