changeset 1314:bb9c32249778 frontends_multi_profiles

core: added getEntitiesData which get cache data for several entities at once
author Goffi <goffi@goffi.org>
date Mon, 09 Feb 2015 21:39:51 +0100
parents a8d7500090f6
children be3a301540c0
files frontends/src/bridge/DBus.py src/bridge/DBus.py src/bridge/bridge_constructor/bridge_template.ini src/core/sat_main.py src/memory/memory.py
diffstat 5 files changed, 84 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/frontends/src/bridge/DBus.py	Mon Feb 09 21:39:47 2015 +0100
+++ b/frontends/src/bridge/DBus.py	Mon Feb 09 21:39:51 2015 +0100
@@ -265,6 +265,20 @@
             kwargs['error_handler'] = error_handler
         return self.db_core_iface.getContactsFromGroup(group, profile_key, **kwargs)
 
+    def getEntitiesData(self, jids, keys, profile, 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))
+        kwargs={}
+        if callback is not None:
+            kwargs['timeout'] = const_TIMEOUT
+            kwargs['reply_handler'] = callback
+            kwargs['error_handler'] = error_handler
+        return self.db_core_iface.getEntitiesData(jids, keys, profile, **kwargs)
+
     def getEntityData(self, jid, keys, profile, callback=None, errback=None):
         if callback is None:
             error_handler = None
--- a/src/bridge/DBus.py	Mon Feb 09 21:39:47 2015 +0100
+++ b/src/bridge/DBus.py	Mon Feb 09 21:39:51 2015 +0100
@@ -271,6 +271,12 @@
         return self._callback("getContactsFromGroup", unicode(group), unicode(profile_key))
 
     @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
+                         in_signature='asass', out_signature='a{sa{ss}}',
+                         async_callbacks=None)
+    def getEntitiesData(self, jids, keys, profile):
+        return self._callback("getEntitiesData", jids, keys, unicode(profile))
+
+    @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX,
                          in_signature='sass', out_signature='a{ss}',
                          async_callbacks=None)
     def getEntityData(self, jid, keys, profile):
--- a/src/bridge/bridge_constructor/bridge_template.ini	Mon Feb 09 21:39:47 2015 +0100
+++ b/src/bridge/bridge_constructor/bridge_template.ini	Mon Feb 09 21:39:51 2015 +0100
@@ -184,12 +184,24 @@
 category=core
 sig_in=sass
 sig_out=a{ss}
-doc=Get data for an entity
+doc=Get data in cache for an entity
 doc_param_0=jid: entity's bare jid
 doc_param_1=keys: list of keys to get
 doc_param_2=%(doc_profile)s
 doc_return=dictionary of asked key,
- if key doesn't exist, the resulting dictionary will neither have the key
+ if key doesn't exist, the resulting dictionary will not have the key
+
+[getEntitiesData]
+type=method
+category=core
+sig_in=asass
+sig_out=a{sa{ss}}
+doc=Get data in cache for several entities at once
+doc_param_0=jids: list of entities bare jid, or empty list to have all jids in cache
+doc_param_1=keys: list of keys to get
+doc_param_2=%(doc_profile)s
+doc_return=dictionary with jids as keys and dictionary of asked key as values
+ if key doesn't exist for a jid, the resulting dictionary will not have it
 
 [asyncCreateProfile]
 async=
--- a/src/core/sat_main.py	Mon Feb 09 21:39:47 2015 +0100
+++ b/src/core/sat_main.py	Mon Feb 09 21:39:51 2015 +0100
@@ -83,7 +83,8 @@
         self.bridge.register("getVersion", lambda: C.APP_VERSION)
         self.bridge.register("getProfileName", self.memory.getProfileName)
         self.bridge.register("getProfilesList", self.memory.getProfilesList)
-        self.bridge.register("getEntityData", lambda _jid, keys, profile: self.memory.getEntityData(jid.JID(_jid), keys, profile))
+        self.bridge.register("getEntityData", lambda jid_, keys, profile: self.memory.getEntityData(jid.JID(jid_), keys, profile))
+        self.bridge.register("getEntitiesData", self.memory._getEntitiesData)
         self.bridge.register("asyncCreateProfile", self.memory.asyncCreateProfile)
         self.bridge.register("asyncDeleteProfile", self.memory.asyncDeleteProfile)
         self.bridge.register("asyncConnect", self.asyncConnect)
--- a/src/memory/memory.py	Mon Feb 09 21:39:47 2015 +0100
+++ b/src/memory/memory.py	Mon Feb 09 21:39:51 2015 +0100
@@ -636,6 +636,54 @@
                 else:
                     raise e
 
+    def _getEntitiesData(self, entities_jids, keys_list, profile_key):
+        ret = self.getEntitiesData([jid.JID(jid_) for jid_ in entities_jids], keys_list, profile_key)
+        return {jid_.full(): data for jid_, data in ret.iteritems()}
+
+    def getEntitiesData(self, entities_jids, keys_list=None, profile_key=C.PROF_KEY_NONE):
+        """Get a list of cached values for several entities at once
+
+        @param entities_jids: jids of the entities, or empty list for all entities in cache
+        @param keys_list (iterable,None): list of keys to get, None for everything
+        @param profile_key: %(doc_profile_key)s
+        @return: dict withs values for each key in keys_list.
+                 if there is no value of a given key, resulting dict will
+                 have nothing with that key nether
+                 if an entity doesn't exist in cache, it will not appear
+                 in resulting dict
+
+        @raise exceptions.UnknownEntityError: if entity is not in cache
+        """
+        def fillEntityData(entity_cache_data):
+            entity_data = {}
+            if keys_list is None:
+                entity_data = entity_cache_data
+            else:
+                for key in keys_list:
+                    try:
+                        entity_data[key] = entity_cache_data[key]
+                    except KeyError:
+                        continue
+            return entity_data
+
+        profile_cache = self._getProfileCache(profile_key)
+        ret_data = {}
+        if entities_jids:
+            for entity in entities_jids:
+                try:
+                    entity_cache_data = profile_cache[entity.userhostJID()][entity.resource]
+                except KeyError:
+                    continue
+                ret_data[entity.full()] = fillEntityData(entity_cache_data, keys_list)
+        else:
+            for bare_jid, data in profile_cache.iteritems():
+                for resource, entity_cache_data in data.iteritems():
+                    full_jid = copy.copy(bare_jid)
+                    full_jid.resource = resource
+                    ret_data[full_jid] = fillEntityData(entity_cache_data)
+
+        return ret_data
+
     def getEntityData(self, entity_jid, keys_list=None, profile_key=C.PROF_KEY_NONE):
         """Get a list of cached values for entity