diff src/core/sat_main.py @ 1482:80cd55dd5b04

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.
author Goffi <goffi@goffi.org>
date Fri, 21 Aug 2015 17:08:26 +0200
parents 8bfbf5cb0e28
children 704ca56f5ca9
line wrap: on
line diff
--- a/src/core/sat_main.py	Thu Aug 20 18:44:39 2015 +0200
+++ b/src/core/sat_main.py	Fri Aug 21 17:08:26 2015 +0200
@@ -87,6 +87,7 @@
             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 @@
             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):