diff frontends/src/quick_frontend/quick_contact_list.py @ 2065:f3167c873e7b

quick frontend (contact list): better handling of cache with full jid: - get_cache has a new argument "bare_default" - value of resource is returned if full jid is used. None is returned if not found and bare_default is False, bare jid value is returned if not found and bare_default is True
author Goffi <goffi@goffi.org>
date Fri, 09 Sep 2016 23:54:33 +0200
parents 748e539c5feb
children e8cb9cc09485
line wrap: on
line diff
--- a/frontends/src/quick_frontend/quick_contact_list.py	Fri Sep 09 23:54:33 2016 +0200
+++ b/frontends/src/quick_frontend/quick_contact_list.py	Fri Sep 09 23:54:33 2016 +0200
@@ -204,7 +204,7 @@
     def fill(self):
         handler.fill(self.profile)
 
-    def getCache(self, entity, name=None):
+    def getCache(self, entity, name=None, bare_default=False):
         """Return a cache value for a contact
 
         @param entity(jid.JID): entity of the contact from who we want data (resource is used if given)
@@ -212,6 +212,9 @@
                 - if no resource is given (bare jid), the main resource is used, according to priority
                 - if resource is given, it is used
         @param name(unicode): name the data to get, or None to get everything
+        @param bare_default(bool): if True and entity is a full jid, the value of bare jid
+            will be returned if not value is found for the requested resource.
+            If False, None is returned if no value is found for the requested resource.
         @return: full cache if no name is given, or value of "name", or None
         """
         # FIXME: resource handling need to be reworked
@@ -227,9 +230,8 @@
         if name in ('status', C.PRESENCE_STATUSES, C.PRESENCE_PRIORITY, C.PRESENCE_SHOW):
             # these data are related to the resource
             if not entity.resource:
-                try:
-                    main_resource = cache[C.CONTACT_MAIN_RESOURCE]
-                except KeyError:
+                main_resource = cache[C.CONTACT_MAIN_RESOURCE]
+                if main_resource is None:
                     # we ignore presence info if we don't have any resource in cache
                     # FIXME: to be checked
                     return
@@ -242,12 +244,11 @@
                 return cache[C.PRESENCE_STATUSES].get(C.PRESENCE_STATUSES_DEFAULT, '')
 
         elif entity.resource:
-            # if we have a resource, we first check if the value is not available for the resource
-            # and we fallback to main cache if not found
             try:
                 return cache[C.CONTACT_RESOURCES][entity.resource][name]
             except KeyError:
-                pass
+                if not bare_default:
+                    return None
 
         try:
             return cache[name]
@@ -347,8 +348,10 @@
         None value for 'groups' has a different meaning than [None] which is for the default group.
 
         @param entity (jid.JID): entity to add or replace
+            if entity is a full jid, attributes will be cached in for the full jid only
         @param groups (list): list of groups or None to ignore the groups membership.
         @param attributes (dict): attibutes of the added jid or to update
+            if attribute value is None, it will be removed
         @param in_roster (bool): True if contact is from roster
         """
         if attributes is None:
@@ -361,6 +364,7 @@
             self._roster.add(entity_bare)
 
         cache = self._cache.setdefault(entity_bare, {C.CONTACT_RESOURCES: {},
+                                                     C.CONTACT_MAIN_RESOURCE: None,
                                                      C.CONTACT_SELECTED: set()})
 
         assert not C.CONTACT_DATA_FORBIDDEN.intersection(attributes) # we don't want forbidden data in attributes
@@ -387,12 +391,13 @@
                 cache[C.CONTACT_MAIN_RESOURCE] = None
 
         # now the attributes we keep in cache
+        # XXX: if entity is a full jid, we store the value for the resource only
+        cache_attr = cache[C.CONTACT_RESOURCES].setdefault(entity.resource, {}) if entity.resource else cache
         for attribute, value in attributes.iteritems():
-            if attribute == 'avatar' and entity.resource:
-                # FIXME: Q&D hack to workaround avatar issue.
-                # TODO: Need to refactor avatar handling in backend and here
-                cache[C.CONTACT_RESOURCES].setdefault(entity.resource, {})[attribute] = value
-            cache[attribute] = value
+            if value is None:
+                cache_attr[attribute].pop(value, None)
+            else:
+                cache_attr[attribute] = value
 
         # we can update the display
         self.update([entity], update_type, self.profile)