core (memory/disco): getInfos now handle node + use client instead of profile in many methods
This commit is contained in:
parent
a205ff4e90
commit
3bc851abf2
1 changed files with 69 additions and 60 deletions
|
|
@ -104,57 +104,56 @@ class Discovery(object):
|
|||
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 @@ class Discovery(object):
|
|||
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 @@ class Discovery(object):
|
|||
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 @@ class Discovery(object):
|
|||
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 @@ class Discovery(object):
|
|||
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 @@ class Discovery(object):
|
|||
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 @@ class Discovery(object):
|
|||
@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 @@ class Discovery(object):
|
|||
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 @@ class Discovery(object):
|
|||
|
||||
@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 @@ class Discovery(object):
|
|||
[(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)
|
||||
|
|
|
|||
Loading…
Reference in a new issue