diff src/core/sat_main.py @ 2534:7da86e1633a5

core: new discoFindFeatures method which return all server services/roster entities implementing a set of features.
author Goffi <goffi@goffi.org>
date Sat, 24 Mar 2018 10:46:09 +0100
parents e8e1507049b7
children 27539029a662
line wrap: on
line diff
--- a/src/core/sat_main.py	Sat Mar 24 10:44:37 2018 +0100
+++ b/src/core/sat_main.py	Sat Mar 24 10:46:09 2018 +0100
@@ -118,6 +118,7 @@
         self.bridge.register_method("menuLaunch", self._launchMenu)
         self.bridge.register_method("discoInfos", self.memory.disco._discoInfos)
         self.bridge.register_method("discoItems", self.memory.disco._discoItems)
+        self.bridge.register_method("discoFindByFeatures", self._findByFeatures)
         self.bridge.register_method("saveParamsTemplate", self.memory.save_xml)
         self.bridge.register_method("loadParamsTemplate", self.memory.load_xml)
         self.bridge.register_method("sessionInfosGet", self.getSessionInfos)
@@ -670,6 +671,60 @@
     def findFeaturesSet(self, *args, **kwargs):
         return self.memory.disco.findFeaturesSet(*args, **kwargs)
 
+    def _findByFeatures(self, namespace, service, roster, own_jid, profile_key):
+        client = self.getClient(profile_key)
+        return self.findByFeatures(client, namespace, service, roster, own_jid)
+
+    @defer.inlineCallbacks
+    def findByFeatures(self, client, namespaces, service, roster, own_jid):
+        """retrieve all services or contacts managing a set a features
+
+        @param namespaces(list[unicode]): features which must be handled
+        @param service(bool): if True return service from our roster
+        @param roster(bool): if True, return entities in roster
+            full jid of all matching resources available will be returned
+        @param own_jid(bool): if True, return profile's jid resources
+        @return (tuple(dict[jid.JID(), tuple[unicode, unicode, unicode]]*3)): found entities in a tuple with:
+            - service entities
+            - own entities
+            - roster entities
+        """
+        if not namespaces:
+            raise exceptions.DataError("namespaces must not be empty")
+        found_service = {}
+        found_own = {}
+        found_roster = {}
+        if service:
+            services_jids = yield self.findFeaturesSet(client, namespaces)
+            for service_jid in services_jids:
+                infos = yield self.getDiscoInfos(client, service_jid)
+                identities = [(cat, type_, name or u'') for (cat, type_), name in infos.identities.iteritems()]
+                found_service[service_jid.full()] = identities
+
+        jids = []
+        if roster:
+            jids.extend(client.roster.getJids())
+        if own_jid:
+            jids.append(client.jid.userhostJID())
+
+        for found, jids in ((found_own, [client.jid.userhostJID()]),
+                            (found_roster, client.roster.getJids())):
+            for jid_ in jids:
+                if jid_.resource:
+                    resources = [jid_.resource]
+                else:
+                    try:
+                        resources = self.memory.getAllResources(client, jid_)
+                    except exceptions.UnknownEntityError:
+                        continue
+                for resource in resources:
+                    full_jid = jid.JID(tuple=(jid_.user, jid_.host, resource))
+                    infos = yield self.getDiscoInfos(client, full_jid)
+                    if infos.features.issuperset(namespaces):
+                        identities = [(cat, type_, name or u'') for (cat, type_), name in infos.identities.iteritems()]
+                        found[full_jid.full()] = identities
+
+        defer.returnValue((found_service, found_own, found_roster))
 
     ## Generic HMI ##