Mercurial > libervia-backend
diff src/memory/disco.py @ 2148:a543eda2c923
core (memory/disco): getInfos now handle node + use client instead of profile in many methods
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 12 Feb 2017 20:43:20 +0100 |
parents | efe31f0881fb |
children | 91347fe95384 |
line wrap: on
line diff
--- a/src/memory/disco.py Sun Feb 12 19:23:34 2017 +0100 +++ b/src/memory/disco.py Sun Feb 12 20:43:20 2017 +0100 @@ -104,57 +104,56 @@ return self.hashes.load() @defer.inlineCallbacks - def hasFeature(self, feature, jid_=None, profile=C.PROF_KEY_NONE): + def hasFeature(self, client, feature, jid_=None, node=u''): """Tell if an entity has the required feature @param feature: feature namespace @param jid_: jid of the target, or None for profile's server - @param profile: %(doc_profile)s + @param node(unicode): optional node to use for disco request @return: a Deferred which fire a boolean (True if feature is available) """ - disco_infos = yield self.getInfos(jid_, profile) + disco_infos = yield self.getInfos(client, jid_, node) defer.returnValue(feature in disco_infos.features) @defer.inlineCallbacks - def checkFeature(self, feature, jid_=None, profile=C.PROF_KEY_NONE): + def checkFeature(self, client, feature, jid_=None, node=u''): """Like hasFeature, but raise an exception is feature is not Found @param feature: feature namespace @param jid_: jid of the target, or None for profile's server - @param profile: %(doc_profile)s + @param node(unicode): optional node to use for disco request @raise: exceptions.FeatureNotFound """ - disco_infos = yield self.getInfos(jid_, profile) + disco_infos = yield self.getInfos(client, jid_, node) if not feature in disco_infos.features: raise failure.Failure(exceptions.FeatureNotFound) @defer.inlineCallbacks - def checkFeatures(self, features, jid_=None, identity=None, profile=C.PROF_KEY_NONE): + def checkFeatures(self, client, features, jid_=None, identity=None, node=u''): """Like checkFeature, but check several features at once, and check also identity @param features(iterable[unicode]): features to check @param jid_(jid.JID): jid of the target, or None for profile's server + @param node(unicode): optional node to use for disco request @param identity(None, tuple(unicode, unicode): if not None, the entity must have an identity with this (category, type) tuple - @param profile: %(doc_profile)s @raise: exceptions.FeatureNotFound """ - disco_infos = yield self.getInfos(jid_, profile) + disco_infos = yield self.getInfos(client, jid_, node) if not set(features).issubset(disco_infos.features): raise failure.Failure(exceptions.FeatureNotFound()) if identity is not None and identity not in disco_infos.identities: raise failure.Failure(exceptions.FeatureNotFound()) - def getInfos(self, jid_=None, profile=C.PROF_KEY_NONE): + def getInfos(self, client, jid_=None, node=u''): """get disco infos from jid_, filling capability hash if needed @param jid_: jid of the target, or None for profile's server - @param profile: %(doc_profile)s + @param node(unicode): optional node to use for disco request @return: a Deferred which fire disco.DiscoInfo """ - client = self.host.getClient(profile) if jid_ is None: jid_ = jid.JID(client.jid.host) try: @@ -178,7 +177,7 @@ self.host.memory.updateEntityData(jid_, C.ENTITY_CAP_HASH, CAP_HASH_ERROR, profile_key=client.profile) disco_infos = self.hashes[CAP_HASH_ERROR] return disco_infos - d = client.disco.requestInfo(jid_) + d = client.disco.requestInfo(jid_, nodeIdentifier=node) d.addCallback(infosCb) d.addErrback(infosEb) return d @@ -187,15 +186,13 @@ return defer.succeed(disco_infos) @defer.inlineCallbacks - def getItems(self, jid_=None, nodeIdentifier='', profile=C.PROF_KEY_NONE): + def getItems(self, client, jid_=None, node=u''): """get disco items from jid_, cache them for our own server - @param jid_ (jid.JID): jid of the target, or None for profile's server - @param nodeIdentifier (str): optional node identifier - @param profile: %(doc_profile)s + @param jid_(jid.JID): jid of the target, or None for profile's server + @param node(unicode): optional node to use for disco request @return: a Deferred which fire disco.DiscoItems """ - client = self.host.getClient(profile) if jid_ is None: jid_ = jid.JID(client.jid.host) # we cache items only for our own server @@ -204,11 +201,11 @@ log.debug(u"[%s] disco items are in cache" % jid_.full()) except (KeyError, exceptions.UnknownEntityError): log.debug(u"Caching [%s] disco items" % jid_.full()) - items = yield client.disco.requestItems(jid_, nodeIdentifier) + items = yield client.disco.requestItems(jid_, nodeIdentifier=node) self.host.memory.updateEntityData(jid_, "DISCO_ITEMS", items, profile_key=client.profile) else: try: - items = yield client.disco.requestItems(jid_, nodeIdentifier) + items = yield client.disco.requestItems(jid_, nodeIdentifier=node) except StanzaError as e: log.warning(u"Error while requesting items for {jid}: {reason}" .format(jid=jid_.full(), reason=e.condition)) @@ -222,13 +219,12 @@ log.warning(_(u"Error while requesting [%(jid)s]: %(error)s") % {'jid': entity_jid.full(), 'error': failure_.getErrorMessage()}) - def findServiceEntities(self, category, type_, jid_=None, profile=C.PROF_KEY_NONE): + def findServiceEntities(self, client, category, type_, jid_=None): """Return all available items of an entity which correspond to (category, type_) @param category: identity's category @param type_: identitiy's type @param jid_: the jid of the target server (None for profile's server) - @param profile: %(doc_profile)s @return: a set of found entities @raise defer.CancelledError: the request timed out """ @@ -241,18 +237,18 @@ def gotItems(items): defers_list = [] for item in items: - info_d = self.getInfos(item.entity, profile) + info_d = self.getInfos(client, item.entity) info_d.addCallbacks(infosCb, self._infosEb, [item.entity], None, [item.entity]) defers_list.append(info_d) return defer.DeferredList(defers_list) - d = self.getItems(jid_, profile=profile) + d = self.getItems(client, jid_) d.addCallback(gotItems) d.addCallback(lambda dummy: found_entities) reactor.callLater(TIMEOUT, d.cancel) # FIXME: one bad service make a general timeout return d - def findFeaturesSet(self, features, identity=None, jid_=None, profile=C.PROF_KEY_NONE): + def findFeaturesSet(self, client, features, identity=None, jid_=None): """Return entities (including jid_ and its items) offering features @param features: iterable of features which must be present @@ -261,7 +257,6 @@ @param profile: %(doc_profile)s @return: a set of found entities """ - client = self.host.getClient(profile) if jid_ is None: jid_ = jid.JID(client.jid.host) features = set(features) @@ -276,12 +271,12 @@ def gotItems(items): defer_list = [] for entity in [jid_] + [item.entity for item in items]: - infos_d = self.getInfos(entity, profile) + infos_d = self.getInfos(client, entity) infos_d.addCallbacks(infosCb, self._infosEb, [entity], None, [entity]) defer_list.append(infos_d) return defer.DeferredList(defer_list) - d = self.getItems(jid_, profile=profile) + d = self.getItems(client, jid_) d.addCallback(gotItems) d.addCallback(lambda dummy: found_entities) reactor.callLater(TIMEOUT, d.cancel) # FIXME: one bad service make a general timeout @@ -319,9 +314,9 @@ @return: list of tuples """ - profile = self.host.memory.getProfileName(profile_key) + client = self.host.getClient(profile_key) entity = jid.JID(entity_jid_s) - disco_infos = yield self.getInfos(entity, profile) + disco_infos = yield self.getInfos(client, entity) extensions = {} for form_type, form in disco_infos.extensions.items(): fields = [] @@ -341,20 +336,26 @@ [(cat, type_, name or '') for (cat, type_), name in disco_infos.identities.items()], extensions)) + def items2tuples(self, disco_items): + """convert disco items to tuple of strings + + @param disco_items(iterable[disco.DiscoItem]): items + @return G(tuple[unicode,unicode,unicode]): serialised items + """ + for item in disco_items: + if not item.entity: + log.warning(_(u"invalid item (no jid)")) + continue + yield (item.entity.full(), item.nodeIdentifier or '', item.name or '') + @defer.inlineCallbacks def _discoItems(self, entity_jid_s, profile_key=C.PROF_KEY_NONE): """ Discovery method for the bridge + @param entity_jid_s: entity we want to discover - @return: list of tuples""" - profile = self.host.memory.getProfileName(profile_key) + client = self.host.getClient(profile_key) entity = jid.JID(entity_jid_s) - disco_items = yield self.getItems(entity, profile=profile) - try: - ret = [(item.entity.full(), item.nodeIdentifier or '', item.name or '') for item in disco_items] - except AttributeError: - log.error(u"error while getting items from {entity}, it may result from invalid item(s)".format(entity=entity.full())) - # second try by ignoring empty items - ret = [(item.entity.full(), item.nodeIdentifier or '', item.name or '') for item in disco_items if item.entity] - + disco_items = yield self.getItems(client, entity) + ret = list(self.items2tuples(disco_items)) defer.returnValue(ret)