Mercurial > libervia-backend
comparison src/memory/memory.py @ 944:e1842ebcb2f3
core, plugin XEP-0115: discovery refactoring:
- hashing algorithm of XEP-0115 has been including in core
- our own hash is still calculated by XEP-0115 and can be regenerated with XEP_0115.recalculateHash
- old discovery methods have been removed. Now the following methods are used:
- hasFeature: tell if a feature is available for an entity
- getDiscoInfos: self explaining
- getDiscoItems: self explaining
- findServiceEntities: return all available items of an entity which given (category, type)
- findFeaturesSet: search for a set of features in entity + entity's items
all these methods are asynchronous, and manage cache automatically
- XEP-0115 manage in a better way hashes, and now use a trigger for presence instead of monkey patch
- new FeatureNotFound exception, when we want to do something which is not available
- refactored client initialisation sequence, removed client.initialized Deferred
- added constant APP_URL
- test_plugin_xep_0033.py has been temporarly deactivated, the time to adapt it
- lot of cleaning
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 28 Mar 2014 18:07:22 +0100 |
parents | 71926ec2114d |
children | fe181994246a |
comparison
equal
deleted
inserted
replaced
943:71926ec2114d | 944:e1842ebcb2f3 |
---|---|
30 from sat.core import exceptions | 30 from sat.core import exceptions |
31 from sat.core.constants import Const as C | 31 from sat.core.constants import Const as C |
32 from sat.memory.sqlite import SqliteStorage | 32 from sat.memory.sqlite import SqliteStorage |
33 from sat.memory.persistent import PersistentDict | 33 from sat.memory.persistent import PersistentDict |
34 from sat.memory.params import Params | 34 from sat.memory.params import Params |
35 from sat.memory.disco import Discovery | |
35 | 36 |
36 | 37 |
37 class Sessions(object): | 38 class Sessions(object): |
38 DEFAULT_TIMEOUT = 600 | 39 DEFAULT_TIMEOUT = 600 |
39 | 40 |
113 self.initialized = defer.Deferred() | 114 self.initialized = defer.Deferred() |
114 self.host = host | 115 self.host = host |
115 self._entities_cache = {} # XXX: keep presence/last resource/other data in cache | 116 self._entities_cache = {} # XXX: keep presence/last resource/other data in cache |
116 # /!\ an entity is not necessarily in roster | 117 # /!\ an entity is not necessarily in roster |
117 self.subscriptions = {} | 118 self.subscriptions = {} |
118 self.server_features = {} # used to store discovery's informations | 119 self.disco = Discovery(host) |
119 self.server_identities = {} | |
120 self.config = self.parseMainConf() | 120 self.config = self.parseMainConf() |
121 self.__fixLocalDir() | 121 self.__fixLocalDir() |
122 database_file = os.path.expanduser(os.path.join(self.getConfig('', 'local_dir'), C.SAVEFILE_DATABASE)) | 122 database_file = os.path.expanduser(os.path.join(self.getConfig('', 'local_dir'), C.SAVEFILE_DATABASE)) |
123 self.storage = SqliteStorage(database_file, host.__version__) | 123 self.storage = SqliteStorage(database_file, host.__version__) |
124 PersistentDict.storage = self.storage | 124 PersistentDict.storage = self.storage |
278 | 278 |
279 def getHistory(self, from_jid, to_jid, limit=0, between=True, profile=C.PROF_KEY_NONE): | 279 def getHistory(self, from_jid, to_jid, limit=0, between=True, profile=C.PROF_KEY_NONE): |
280 assert profile != C.PROF_KEY_NONE | 280 assert profile != C.PROF_KEY_NONE |
281 return self.storage.getHistory(jid.JID(from_jid), jid.JID(to_jid), limit, between, profile) | 281 return self.storage.getHistory(jid.JID(from_jid), jid.JID(to_jid), limit, between, profile) |
282 | 282 |
283 def addServerFeature(self, feature, jid_, profile): | |
284 """Add a feature discovered from server | |
285 @param feature: string of the feature | |
286 @param jid_: the jid of the target server | |
287 @param profile: which profile asked this server?""" | |
288 if profile not in self.server_features: | |
289 self.server_features[profile] = {} | |
290 features = self.server_features[profile].setdefault(jid_, []) | |
291 features.append(feature) | |
292 | |
293 def addServerIdentity(self, category, type_, entity, jid_, profile): | |
294 """Add an identity discovered from server | |
295 @param feature: string of the feature | |
296 @param jid_: the jid of the target server | |
297 @param profile: which profile asked this server?""" | |
298 if not profile in self.server_identities: | |
299 self.server_identities[profile] = {} | |
300 identities = self.server_identities[profile].setdefault(jid_, {}) | |
301 if (category, type_) not in identities: | |
302 identities[(category, type_)] = set() | |
303 identities[(category, type_)].add(entity) | |
304 | |
305 def getServerServiceEntities(self, category, type_, jid_=None, profile=None): | |
306 """Return all available entities of a server for the service (category, type_) | |
307 @param category: identity's category | |
308 @param type_: identitiy's type | |
309 @param jid_: the jid of the target server (None for profile's server) | |
310 @param profile: which profile is asking this server? | |
311 @return: a set of entities or None if no cached data were found | |
312 """ | |
313 if jid_ is None: | |
314 jid_ = self.host.getClientHostJid(profile) | |
315 if profile in self.server_identities and jid_ in self.server_identities[profile]: | |
316 return self.server_identities[profile][jid_].get((category, type_), set()) | |
317 else: | |
318 return None | |
319 | |
320 def getServerServiceEntity(self, category, type_, jid_=None, profile=None): | |
321 """Helper method to get first available entity of a server for the service (category, type_) | |
322 @param category: identity's category | |
323 @param type_: identitiy's type | |
324 @param jid_: the jid of the target server (None for profile's server) | |
325 @param profile: which profile is asking this server? | |
326 @return: the first found entity or None if no cached data were found | |
327 """ | |
328 entities = self.getServerServiceEntities(category, type_, jid_, profile) | |
329 if entities is None: | |
330 warning(_("Entities (%(category)s/%(type)s) of %(server)s not available, maybe they haven't been asked yet?") | |
331 % {"category": category, "type": type_, "server": jid_}) | |
332 return None | |
333 else: | |
334 return list(entities)[0] if entities else None | |
335 | |
336 def getAllServerIdentities(self, jid_, profile): | |
337 """Helper method to get all identities of a server | |
338 @param jid_: the jid of the target server (None for profile's server) | |
339 @param profile: which profile is asking this server? | |
340 @return: a set of entities or None if no cached data were found | |
341 """ | |
342 if jid_ is None: | |
343 jid_ = self.host.getClientHostJid(profile) | |
344 if jid_ not in self.server_identities[profile]: | |
345 return None | |
346 entities = set() | |
347 for set_ in self.server_identities[profile][jid_].values(): | |
348 entities.update(set_) | |
349 return entities | |
350 | |
351 def hasServerFeature(self, feature, jid_=None, profile_key=C.PROF_KEY_NONE): | |
352 """Tell if the specified server has the required feature | |
353 @param feature: requested feature | |
354 @param jid_: the jid of the target server (None for profile's server) | |
355 @param profile_key: %(doc_profile_key)s | |
356 """ | |
357 profile = self.getProfileName(profile_key) | |
358 if not profile: | |
359 error(_('Trying find server feature for a non-existant profile')) | |
360 return None | |
361 assert profile in self.server_features | |
362 if jid_ is None: | |
363 jid_ = self.host.getClientHostJid(profile) | |
364 if jid_ in self.server_features[profile]: | |
365 return feature in self.server_features[profile][jid_] | |
366 else: | |
367 warning(_("Features of %s not available, maybe they haven't been asked yet?") % jid_) | |
368 return None | |
369 | |
370 def _getLastResource(self, jid_s, profile_key): | 283 def _getLastResource(self, jid_s, profile_key): |
371 jid_ = jid.JID(jid_s) | 284 jid_ = jid.JID(jid_s) |
372 return self.getLastResource(jid_, profile_key) or "" | 285 return self.getLastResource(jid_, profile_key) or "" |
373 | 286 |
374 | 287 |
482 except KeyError: | 395 except KeyError: |
483 debug("Key [%s] doesn't exist for [%s] in entities_cache" % (key, entity_jid.full())) | 396 debug("Key [%s] doesn't exist for [%s] in entities_cache" % (key, entity_jid.full())) |
484 | 397 |
485 def getEntityData(self, entity_jid, keys_list, profile_key): | 398 def getEntityData(self, entity_jid, keys_list, profile_key): |
486 """Get a list of cached values for entity | 399 """Get a list of cached values for entity |
400 | |
487 @param entity_jid: JID of the entity | 401 @param entity_jid: JID of the entity |
488 @param keys_list: list of keys to get, empty list for everything | 402 @param keys_list (iterable): list of keys to get, empty list for everything |
489 @param profile_key: %(doc_profile_key)s | 403 @param profile_key: %(doc_profile_key)s |
490 @return: dict withs values for each key in keys_list. | 404 @return: dict withs values for each key in keys_list. |
491 if there is no value of a given key, resulting dict will | 405 if there is no value of a given key, resulting dict will |
492 have nothing with that key nether | 406 have nothing with that key nether |
493 @raise: exceptions.UnknownEntityError if entity is not in cache | 407 @raise: exceptions.UnknownEntityError if entity is not in cache |
502 for key in keys_list: | 416 for key in keys_list: |
503 if key in entity_data: | 417 if key in entity_data: |
504 ret[key] = entity_data[key] | 418 ret[key] = entity_data[key] |
505 return ret | 419 return ret |
506 | 420 |
421 def getEntityDatum(self, entity_jid, key, profile_key): | |
422 """Get a datum from entity | |
423 | |
424 @param entity_jid: JID of the entity | |
425 @param keys: key to get | |
426 @param profile_key: %(doc_profile_key)s | |
427 @return: requested value | |
428 | |
429 @raise: exceptions.UnknownEntityError if entity is not in cache | |
430 @raise: KeyError if there is no value for this key and this entity | |
431 """ | |
432 return self.getEntityData(entity_jid, (key,), profile_key)[key] | |
433 | |
434 | |
507 def delEntityCache(self, entity_jid, delete_all_resources=True, profile_key=C.PROF_KEY_NONE): | 435 def delEntityCache(self, entity_jid, delete_all_resources=True, profile_key=C.PROF_KEY_NONE): |
508 """Remove cached data for entity | 436 """Remove cached data for entity |
509 @param entity_jid: JID of the entity to delete | 437 @param entity_jid: JID of the entity to delete |
510 @param delete_all_resources: if True also delete all known resources form cache | 438 @param delete_all_resources: if True also delete all known resources form cache |
511 @param profile_key: %(doc_profile_key)s | 439 @param profile_key: %(doc_profile_key)s |