comparison src/memory/disco.py @ 2342:f047d5410040

core (memory/disco): added use_cache parameter to discoInfos/discoItems (set to False to ignore cache)
author Goffi <goffi@goffi.org>
date Tue, 22 Aug 2017 22:12:57 +0200
parents 91347fe95384
children cf9b276f4a08
comparison
equal deleted inserted replaced
2341:f9580b4a105a 2342:f047d5410040
145 raise failure.Failure(exceptions.FeatureNotFound()) 145 raise failure.Failure(exceptions.FeatureNotFound())
146 146
147 if identity is not None and identity not in disco_infos.identities: 147 if identity is not None and identity not in disco_infos.identities:
148 raise failure.Failure(exceptions.FeatureNotFound()) 148 raise failure.Failure(exceptions.FeatureNotFound())
149 149
150 def getInfos(self, client, jid_=None, node=u''): 150 def getInfos(self, client, jid_=None, node=u'', use_cache=True):
151 """get disco infos from jid_, filling capability hash if needed 151 """get disco infos from jid_, filling capability hash if needed
152 152
153 @param jid_: jid of the target, or None for profile's server 153 @param jid_: jid of the target, or None for profile's server
154 @param node(unicode): optional node to use for disco request 154 @param node(unicode): optional node to use for disco request
155 @param use_cache(bool): if True, use cached data if available
155 @return: a Deferred which fire disco.DiscoInfo 156 @return: a Deferred which fire disco.DiscoInfo
156 """ 157 """
157 if jid_ is None: 158 if jid_ is None:
158 jid_ = jid.JID(client.jid.host) 159 jid_ = jid.JID(client.jid.host)
159 try: 160 try:
160 cap_hash = self.host.memory.getEntityData(jid_, [C.ENTITY_CAP_HASH], client.profile)[C.ENTITY_CAP_HASH] 161 cap_hash = self.host.memory.getEntityData(jid_, [C.ENTITY_CAP_HASH], client.profile)[C.ENTITY_CAP_HASH]
162 if not use_cache:
163 # we ignore cache, so we pretend we haven't found it
164 raise KeyError
161 except (KeyError, exceptions.UnknownEntityError): 165 except (KeyError, exceptions.UnknownEntityError):
162 # capability hash is not available, we'll compute one 166 # capability hash is not available, we'll compute one
163 def infosCb(disco_infos): 167 def infosCb(disco_infos):
164 cap_hash = self.generateHash(disco_infos) 168 cap_hash = self.generateHash(disco_infos)
165 self.hashes[cap_hash] = disco_infos 169 self.hashes[cap_hash] = disco_infos
184 else: 188 else:
185 disco_infos = self.hashes[cap_hash] 189 disco_infos = self.hashes[cap_hash]
186 return defer.succeed(disco_infos) 190 return defer.succeed(disco_infos)
187 191
188 @defer.inlineCallbacks 192 @defer.inlineCallbacks
189 def getItems(self, client, jid_=None, node=u''): 193 def getItems(self, client, jid_=None, node=u'', use_cache=True):
190 """get disco items from jid_, cache them for our own server 194 """get disco items from jid_, cache them for our own server
191 195
192 @param jid_(jid.JID): jid of the target, or None for profile's server 196 @param jid_(jid.JID): jid of the target, or None for profile's server
193 @param node(unicode): optional node to use for disco request 197 @param node(unicode): optional node to use for disco request
198 @param use_cache(bool): if True, use cached data if available
194 @return: a Deferred which fire disco.DiscoItems 199 @return: a Deferred which fire disco.DiscoItems
195 """ 200 """
196 if jid_ is None: 201 if jid_ is None:
197 jid_ = jid.JID(client.jid.host) 202 jid_ = jid.JID(client.jid.host)
198 # we cache items only for our own server 203 # we cache items only for our own server
199 try: 204 try:
200 items = self.host.memory.getEntityData(jid_, ["DISCO_ITEMS"], client.profile)["DISCO_ITEMS"] 205 items = self.host.memory.getEntityData(jid_, ["DISCO_ITEMS"], client.profile)["DISCO_ITEMS"]
201 log.debug(u"[%s] disco items are in cache" % jid_.full()) 206 log.debug(u"[%s] disco items are in cache" % jid_.full())
207 if not use_cache:
208 # we ignore cache, so we pretend we haven't found it
209 raise KeyError
202 except (KeyError, exceptions.UnknownEntityError): 210 except (KeyError, exceptions.UnknownEntityError):
203 log.debug(u"Caching [%s] disco items" % jid_.full()) 211 log.debug(u"Caching [%s] disco items" % jid_.full())
204 items = yield client.disco.requestItems(jid_, nodeIdentifier=node) 212 items = yield client.disco.requestItems(jid_, nodeIdentifier=node)
205 self.host.memory.updateEntityData(jid_, "DISCO_ITEMS", items, profile_key=client.profile) 213 self.host.memory.updateEntityData(jid_, "DISCO_ITEMS", items, profile_key=client.profile)
206 else: 214 else:
306 cap_hash = b64encode(sha1(''.join(s)).digest()) 314 cap_hash = b64encode(sha1(''.join(s)).digest())
307 log.debug(_(u'Capability hash generated: [%s]') % cap_hash) 315 log.debug(_(u'Capability hash generated: [%s]') % cap_hash)
308 return cap_hash 316 return cap_hash
309 317
310 @defer.inlineCallbacks 318 @defer.inlineCallbacks
311 def _discoInfos(self, entity_jid_s, node=u'', profile_key=C.PROF_KEY_NONE): 319 def _discoInfos(self, entity_jid_s, node=u'', use_cache=True, profile_key=C.PROF_KEY_NONE):
312 """ Discovery method for the bridge 320 """ Discovery method for the bridge
313 @param entity_jid_s: entity we want to discover 321 @param entity_jid_s: entity we want to discover
322 @param use_cache(bool): if True, use cached data if available
314 @param node(unicode): optional node to use 323 @param node(unicode): optional node to use
315 324
316 @return: list of tuples 325 @return: list of tuples
317 """ 326 """
318 client = self.host.getClient(profile_key) 327 client = self.host.getClient(profile_key)
319 entity = jid.JID(entity_jid_s) 328 entity = jid.JID(entity_jid_s)
320 disco_infos = yield self.getInfos(client, entity, node) 329 disco_infos = yield self.getInfos(client, entity, node, use_cache)
321 extensions = {} 330 extensions = {}
322 for form_type, form in disco_infos.extensions.items(): 331 for form_type, form in disco_infos.extensions.items():
323 fields = [] 332 fields = []
324 for field in form.fieldList: 333 for field in form.fieldList:
325 data = {'type': field.fieldType} 334 data = {'type': field.fieldType}
348 log.warning(_(u"invalid item (no jid)")) 357 log.warning(_(u"invalid item (no jid)"))
349 continue 358 continue
350 yield (item.entity.full(), item.nodeIdentifier or '', item.name or '') 359 yield (item.entity.full(), item.nodeIdentifier or '', item.name or '')
351 360
352 @defer.inlineCallbacks 361 @defer.inlineCallbacks
353 def _discoItems(self, entity_jid_s, node=u'', profile_key=C.PROF_KEY_NONE): 362 def _discoItems(self, entity_jid_s, node=u'', use_cache=True, profile_key=C.PROF_KEY_NONE):
354 """ Discovery method for the bridge 363 """ Discovery method for the bridge
355 364
356 @param entity_jid_s: entity we want to discover 365 @param entity_jid_s: entity we want to discover
357 @param node(unicode): optional node to use 366 @param node(unicode): optional node to use
367 @param use_cache(bool): if True, use cached data if available
358 @return: list of tuples""" 368 @return: list of tuples"""
359 client = self.host.getClient(profile_key) 369 client = self.host.getClient(profile_key)
360 entity = jid.JID(entity_jid_s) 370 entity = jid.JID(entity_jid_s)
361 disco_items = yield self.getItems(client, entity, node) 371 disco_items = yield self.getItems(client, entity, node, use_cache)
362 ret = list(self.items2tuples(disco_items)) 372 ret = list(self.items2tuples(disco_items))
363 defer.returnValue(ret) 373 defer.returnValue(ret)