core, bridge: added getFeatures method:

this async method indicate which plugins are activated, and add an additional data dictionary with plugin specific data.
    The result can be general (if profile==C.PROF_KEY_NONE) or specific to profile.
This commit is contained in:
Goffi 2015-08-21 17:08:26 +02:00
commit 0bf9461416
4 changed files with 74 additions and 0 deletions

View file

@ -293,6 +293,15 @@ class DBusBridgeFrontend(BridgeFrontend):
kwargs['error_handler'] = error_handler
return self.db_core_iface.getEntityData(jid, keys, profile, **kwargs)
def getFeatures(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.getFeatures(profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
def getHistory(self, from_jid, to_jid, limit, between=True, search='', profile="@NONE@", callback=None, errback=None):
if callback is None:
error_handler = None

View file

@ -287,6 +287,12 @@ class DbusObject(dbus.service.Object):
def getEntityData(self, jid, keys, profile):
return self._callback("getEntityData", unicode(jid), keys, unicode(profile))
@dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
in_signature='s', out_signature='a{sa{ss}}',
async_callbacks=('callback', 'errback'))
def getFeatures(self, profile_key, callback=None, errback=None):
return self._callback("getFeatures", unicode(profile_key), callback=callback, errback=errback)
@dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
in_signature='ssibss', out_signature='a(dssssa{ss})',
async_callbacks=('callback', 'errback'))

View file

@ -175,6 +175,18 @@ sig_in=
sig_out=s
doc=Get "Salut à Toi" full version
[getFeatures]
type=method
category=core
sig_in=s
sig_out=a{sa{ss}}
doc=Get available features and plugins
features can changes for differents profiles, e.g. because of differents server capabilities
doc_param_0=%(doc_profile_key)s
doc_return=dictionary of available features:
plugin import name is used as key, data is an other dict managed by the plugin
async=
[getProfileName]
type=method
category=core

View file

@ -87,6 +87,7 @@ class SAT(service.Service):
sys.exit(1)
self.bridge.register("getReady", lambda: self._initialised)
self.bridge.register("getVersion", lambda: self.full_version)
self.bridge.register("getFeatures", self.getFeatures)
self.bridge.register("getProfileName", self.memory.getProfileName)
self.bridge.register("getProfilesList", self.memory.getProfilesList)
self.bridge.register("getEntityData", lambda jid_, keys, profile: self.memory.getEntityData(jid.JID(jid_), keys, profile))
@ -340,6 +341,52 @@ class SAT(service.Service):
if disconnected_cb:
disconnected_cb(profile)
def getFeatures(self, profile_key=C.PROF_KEY_NONE):
"""Get available features
Return list of activated plugins and plugin specific data
@param profile_key: %(doc_profile_key)s
C.PROF_KEY_NONE can be used to have general plugins data (i.e. not profile dependent)
@return (dict)[Deferred]: features data where:
- key is plugin import name, present only for activated plugins
- value is a an other dict, when meaning is specifif to each plugin.
this dict is return by plugin's getFeature method.
If this method doesn't exists, an empty dict is returned.
"""
try:
# FIXME: there is no method yet to check profile session
# as soon as one is implemented, it should be used here
self.getClient(profile_key)
except KeyError:
log.warning("Requesting features for a profile outside a session")
profile_key = C.PROF_KEY_NONE
except exceptions.ProfileNotSetError:
pass
features = []
for import_name, plugin in self.plugins.iteritems():
try:
features_d = defer.maybeDeferred(plugin.getFeatures, profile_key)
except AttributeError:
features_d = defer.succeed({})
features.append(features_d)
d_list = defer.DeferredList(features)
def buildFeatures(result, import_names):
assert len(result) == len(import_names)
ret = {}
for name, (success, data) in zip (import_names, result):
if success:
ret[name] = data
else:
log.warning(u"Error while getting features for {name}: {failure}".format(
name=name, failure=data))
ret[name] = {}
return ret
d_list.addCallback(buildFeatures, self.plugins.keys())
return d_list
def getContacts(self, profile_key):
client = self.getClient(profile_key)
def got_roster(dummy):