changeset 2536:27539029a662

core: added bare_jid and identities arguments to discoGetByFeatures: - bare_jid indicate if we are looking for server implementation (True) of devices (False) - identities is an optional filter, only entities with this identities set will be kept
author Goffi <goffi@goffi.org>
date Mon, 26 Mar 2018 08:01:06 +0200
parents a19b2c43e719
children 8cf58a415126
files frontends/src/bridge/dbus_bridge.py src/bridge/bridge_constructor/bridge_template.ini src/bridge/dbus_bridge.py src/core/sat_main.py
diffstat 4 files changed, 45 insertions(+), 26 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/src/bridge/dbus_bridge.py	Sun Mar 25 20:51:02 2018 +0200
+++ b/frontends/src/bridge/dbus_bridge.py	Mon Mar 26 08:01:06 2018 +0200
@@ -209,14 +209,14 @@
             error_handler = lambda err:errback(dbus_to_bridge_exception(err))
         return self.db_core_iface.delContact(entity_jid, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
 
-    def discoFindByFeatures(self, namespaces, service=True, roster=True, own_jid=True, profile_key=u"@DEFAULT@", callback=None, errback=None):
+    def discoFindByFeatures(self, namespaces, identities, bare_jid=False, service=True, roster=True, own_jid=True, profile_key=u"@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.discoFindByFeatures(namespaces, service, roster, own_jid, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
+        return self.db_core_iface.discoFindByFeatures(namespaces, identities, bare_jid, service, roster, own_jid, profile_key, timeout=const_TIMEOUT, reply_handler=callback, error_handler=error_handler)
 
     def discoInfos(self, entity_jid, node=u'', use_cache=True, profile_key=u"@DEFAULT@", callback=None, errback=None):
         if callback is None:
--- a/src/bridge/bridge_constructor/bridge_template.ini	Sun Mar 25 20:51:02 2018 +0200
+++ b/src/bridge/bridge_constructor/bridge_template.ini	Mon Mar 26 08:01:06 2018 +0200
@@ -738,18 +738,22 @@
 async=
 type=method
 category=core
-sig_in=asbbbs
+sig_in=asa(ss)bbbbs
 sig_out=(a{sa(sss)}a{sa(sss)}a{sa(sss)})
-param_1_default=True
-param_2_default=True
+param_2_default=False
 param_3_default=True
-param_4_default=u"@DEFAULT@"
+param_4_default=True
+param_5_default=True
+param_6_default=u"@DEFAULT@"
 doc=Discover items of an entity
 doc_param_0=namespaces: namespaces of the features to check
-doc_param_1=service: True to check server's services
-doc_param_2=roster: True to check connected devices from people in roster
-doc_param_3=own_jid: True to check profile's jid
-doc_param_4=%(doc_profile_key)s
+doc_param_1=identities: identities to filter
+doc_param_2=bare_jid: if True only retrieve bare jids
+    if False, retrieve full jids of connected resources
+doc_param_3=service: True to check server's services
+doc_param_4=roster: True to check connected devices from people in roster
+doc_param_5=own_jid: True to check profile's jid
+doc_param_6=%(doc_profile_key)s
 doc_return=tuple of maps of found entities full jids to their identities. Maps are in this order:
  - services entities
  - own entities (i.e. entities linked to profile's jid)
--- a/src/bridge/dbus_bridge.py	Sun Mar 25 20:51:02 2018 +0200
+++ b/src/bridge/dbus_bridge.py	Mon Mar 26 08:01:06 2018 +0200
@@ -234,10 +234,10 @@
         return self._callback("delContact", unicode(entity_jid), unicode(profile_key), callback=callback, errback=errback)
 
     @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
-                         in_signature='asbbbs', out_signature='(a{sa(sss)}a{sa(sss)}a{sa(sss)})',
+                         in_signature='asa(ss)bbbbs', out_signature='(a{sa(sss)}a{sa(sss)}a{sa(sss)})',
                          async_callbacks=('callback', 'errback'))
-    def discoFindByFeatures(self, namespaces, service=True, roster=True, own_jid=True, profile_key=u"@DEFAULT@", callback=None, errback=None):
-        return self._callback("discoFindByFeatures", namespaces, service, roster, own_jid, unicode(profile_key), callback=callback, errback=errback)
+    def discoFindByFeatures(self, namespaces, identities, bare_jid=False, service=True, roster=True, own_jid=True, profile_key=u"@DEFAULT@", callback=None, errback=None):
+        return self._callback("discoFindByFeatures", namespaces, identities, bare_jid, service, roster, own_jid, unicode(profile_key), callback=callback, errback=errback)
 
     @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
                          in_signature='ssbs', out_signature='(asa(sss)a{sa(a{ss}as)})',
--- a/src/core/sat_main.py	Sun Mar 25 20:51:02 2018 +0200
+++ b/src/core/sat_main.py	Mon Mar 26 08:01:06 2018 +0200
@@ -671,15 +671,19 @@
     def findFeaturesSet(self, *args, **kwargs):
         return self.memory.disco.findFeaturesSet(*args, **kwargs)
 
-    def _findByFeatures(self, namespace, service, roster, own_jid, profile_key):
+    def _findByFeatures(self, namespaces, identities, bare_jids, service, roster, own_jid, profile_key):
         client = self.getClient(profile_key)
-        return self.findByFeatures(client, namespace, service, roster, own_jid)
+        return self.findByFeatures(client, namespaces, identities, bare_jids, service, roster, own_jid)
 
     @defer.inlineCallbacks
-    def findByFeatures(self, client, namespaces, service, roster, own_jid):
+    def findByFeatures(self, client, namespaces, identities=None, bare_jids=False, service=True, roster=True, own_jid=True):
         """retrieve all services or contacts managing a set a features
 
         @param namespaces(list[unicode]): features which must be handled
+        @param identities(list[tuple[unicode,unicode]], None): if not None or empty, only keep those identities
+            tuple must by (category, type)
+        @param bare_jids(bool): retrieve only bare_jids if True
+            if False, retrieve full jid of connected devices
         @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
@@ -689,8 +693,10 @@
             - own entities
             - roster entities
         """
-        if not namespaces:
-            raise exceptions.DataError("namespaces must not be empty")
+        if not identities:
+            identities = None
+        if not namespaces and not identities:
+            raise exceptions.DataError("at least one namespace or one identity must be set")
         found_service = {}
         found_own = {}
         found_roster = {}
@@ -698,8 +704,10 @@
             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
+                if identities is not None and not set(infos.identities.keys()).issuperset(identities):
+                    continue
+                found_identities = [(cat, type_, name or u'') for (cat, type_), name in infos.identities.iteritems()]
+                found_service[service_jid.full()] = found_identities
 
         jids = []
         if roster:
@@ -711,18 +719,25 @@
                             (found_roster, client.roster.getJids())):
             for jid_ in jids:
                 if jid_.resource:
+                    if bare_jids:
+                        continue
                     resources = [jid_.resource]
                 else:
-                    try:
-                        resources = self.memory.getAllResources(client, jid_)
-                    except exceptions.UnknownEntityError:
-                        continue
+                    if bare_jids:
+                        resources = [None]
+                    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
+                        if identities is not None and not set(infos.identities.keys()).issuperset(identities):
+                            continue
+                        found_identities = [(cat, type_, name or u'') for (cat, type_), name in infos.identities.iteritems()]
+                        found[full_jid.full()] = found_identities
 
         defer.returnValue((found_service, found_own, found_roster))