# HG changeset patch # User Goffi # Date 1522044066 -7200 # Node ID 27539029a662bfdfc79ab96e57a2e53643c5594f # Parent a19b2c43e71933a59c821c6a346038675059870b 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 diff -r a19b2c43e719 -r 27539029a662 frontends/src/bridge/dbus_bridge.py --- 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: diff -r a19b2c43e719 -r 27539029a662 src/bridge/bridge_constructor/bridge_template.ini --- 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) diff -r a19b2c43e719 -r 27539029a662 src/bridge/dbus_bridge.py --- 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)})', diff -r a19b2c43e719 -r 27539029a662 src/core/sat_main.py --- 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))