changeset 727:3bd097380da7

server side (blog): fixes displaying the avatar
author souliane <souliane@mailoo.org>
date Mon, 05 Oct 2015 09:15:47 +0200
parents e949b7c7ed9c
children 9d35d75566fb
files src/server/blog.py
diffstat 1 files changed, 39 insertions(+), 61 deletions(-) [+]
line wrap: on
line diff
--- a/src/server/blog.py	Mon Sep 21 12:01:34 2015 +0200
+++ b/src/server/blog.py	Mon Oct 05 09:15:47 2015 +0200
@@ -74,66 +74,43 @@
         self.host = host
         Resource.__init__(self)
         TemplateProcessor.__init__(self, host)
-        self.host.bridge.register('entityDataUpdated', self.entityDataUpdatedCb)
-        self.host.bridge.register('actionResult', self.actionResultCb)  # FIXME: actionResult is to be removed
+        self.host.bridge.register('entityDataUpdated', self.entityDataUpdatedHandler)
         self.avatars_cache = {}
         self.waiting_deferreds = {}
 
-    def entityDataUpdatedCb(self, entity_jid_s, key, value, dummy):
-        """Retrieve the avatar we've been waiting for and fires the callback
-        for self.getAvatar to return.
+    def entityDataUpdatedHandler(self, entity_s, key, value, dummy):
+        """Retrieve the avatar we've been waiting for and fires the callback.
 
-        @param entity_jid_s (str): JID of the contact
+        @param entity_s (str): JID of the contact
         @param key (str): entity data key
         @param value (str): entity data value
         @param dummy (str): that would be C.SERVICE_PROFILE
         """
-        if key != 'avatar':
+        if key != "avatar":
             return
-        entity_jid_s = entity_jid_s.lower()
-        log.debug(_(u"Received a new avatar for entity %s") % entity_jid_s)
-        avatar = C.AVATARS_DIR + value
-        self.avatars_cache[entity_jid_s] = avatar
-        try:
-            self.waiting_deferreds[entity_jid_s][1].callback(avatar)
-            del self.waiting_deferreds[entity_jid_s]
-        except KeyError:
-            pass
+        log.debug(_(u"Received a new avatar for entity %s") % entity_s)
+        
+        url = os.path.join(C.AVATARS_DIR, value)
+        self.avatars_cache[entity_s] = url
+        self.waiting_deferreds[entity_s].callback(url)
+        del self.waiting_deferreds[entity_s]
+        
+    def getAvatarURL(self, pub_jid):
+        """Return avatar of a jid if in cache, else ask for it.
 
-    def actionResultCb(self, answer_type, action_id, data, dummy):
-        """Fires the callback for self.getAvatar to return
-
-        @param answer_type (str): 'SUPPRESS' or another value that we would ignore
-        @param action_id (str): the request ID
-        @param data (dict): ignored
-        @param dummy (str): that would be C.SERVICE_PROFILE
+        @param pub_jid (JID): publisher JID
+        @return: deferred avatar URL (unicode)
         """
-        # FIXME: actionResult is to be removed. For now we use it to get notified
-        # when the requested vCard hasn't been found. Replace with the new system.
-        if answer_type != 'SUPPRESS':
-            return
+        bare_jid_s = pub_jid.userhost()
         try:
-            entity_jid_s = [key for (key, value) in self.waiting_deferreds.items() if value[0] == action_id][0]
-        except IndexError:  # impossible to guess the entity
-            return
-        log.debug(_(u"Using default avatar for entity %s") % entity_jid_s)
-        self.avatars_cache[entity_jid_s] = C.DEFAULT_AVATAR_URL
-        self.waiting_deferreds[entity_jid_s][1].callback(C.DEFAULT_AVATAR_URL)
-        del self.waiting_deferreds[entity_jid_s]
-
-    def getAvatar(self, profile):
-        """Get the avatar of the given profile
-
-        @param profile(unicode): %(doc_profile)s
-        @return: deferred avatar path, relative to the server's root
-        """
-        jid_s = (profile + '@' + self.host.bridge.getNewAccountDomain()).lower()
-        if jid_s in self.avatars_cache:
-            return defer.succeed(self.avatars_cache[jid_s])
-        # FIXME: request_id is no more needed when actionResult is removed
-        request_id = self.host.bridge.getCard(jid_s, C.SERVICE_PROFILE)
-        self.waiting_deferreds[jid_s] = (request_id, defer.Deferred())
-        return self.waiting_deferreds[jid_s][1]
+            url = self.avatars_cache[bare_jid_s]
+        except KeyError:
+            self.avatars_cache[bare_jid_s] = ''  # avoid to request the vcard several times
+            self.host.bridge.getCard(bare_jid_s, C.SERVICE_PROFILE)
+            d = defer.Deferred()
+            self.waiting_deferreds[bare_jid_s] = d
+            return d
+        return defer.succeed(url if url else C.DEFAULT_AVATAR_URL)
 
     def render_GET(self, request):
         if not request.postpath:
@@ -165,7 +142,7 @@
             self.host.bridge.mbGetAtom(pub_jid.userhost(), NS_MICROBLOG, max_items, item_ids,
                                        request.extra_dict, C.SERVICE_PROFILE,
                                        lambda feed: self.render_atom_feed(feed, request),
-                                       lambda failure: self.render_error_blog(failure, request, profile))
+                                       lambda failure: self.render_error_blog(failure, request, pub_jid))
         elif request.item_id:
             self.getItemById(pub_jid, request.item_id, request.extra_dict,
                              request.extra_comments_dict, request, profile)
@@ -257,7 +234,7 @@
                 def gotComments(comments):
                     # build the items as self.getItems would do it (and as self.render_html_blog expects them to be)
                     comments = [(item['comments_service'], item['comments_node'], "", comments[0], comments[1])]
-                    self.render_html_blog([(item, comments)], metadata, request, profile)
+                    self.render_html_blog([(item, comments)], metadata, request, pub_jid, profile)
 
                 # get the comments
                 max_comments = int(extra_comments_dict['rsm_max'])
@@ -288,7 +265,7 @@
             for result in results:
                 service, node, failure, items, metadata = result
                 if not failure:
-                    self.render_html_blog(items, metadata, request, profile)
+                    self.render_html_blog(items, metadata, request, pub_jid, profile)
     
             if remaining:
                 self._getResults(rt_session)
@@ -296,20 +273,21 @@
         def getResult(rt_session):
             self.host.bridge.mbGetFromManyWithCommentsRTResult(rt_session, C.SERVICE_PROFILE,
                                                                callback=lambda data: getResultCb(data, rt_session),
-                                                               errback=lambda failure: self.render_error_blog(failure, request, profile))
+                                                               errback=lambda failure: self.render_error_blog(failure, request, pub_jid))
 
         max_comments = int(extra_comments_dict['rsm_max'])
         self.host.bridge.mbGetFromManyWithComments(C.JID, [pub_jid.userhost()], max_items,
                                                    max_comments, extra_dict, extra_comments_dict,
                                                    C.SERVICE_PROFILE, callback=getResult)
         
-    def render_html_blog(self, items, metadata, request, profile):
+    def render_html_blog(self, items, metadata, request, pub_jid, profile):
         """Retrieve the user parameters before actually rendering the static blog
 
         @param items(list[tuple(dict, list)]): same as in self.__render_html_blog
         @param metadata(dict): original node metadata
         @param request: HTTP request
-        @param profile
+        @param pub_jid (JID): publisher JID
+        @param profile (unicode): %(doc_profile)s
         """
         d_list = []
         options = {}
@@ -320,16 +298,16 @@
             d_list.append(d)
             return d.callback
 
-        eb = lambda failure: self.render_error_blog(failure, request, profile)
+        eb = lambda failure: self.render_error_blog(failure, request, pub_jid)
 
-        self.getAvatar(profile).addCallbacks(getCallback('avatar'), eb)
+        self.getAvatarURL(pub_jid).addCallbacks(getCallback('avatar'), eb)
         for param_name in (C.STATIC_BLOG_PARAM_TITLE, C.STATIC_BLOG_PARAM_BANNER, C.STATIC_BLOG_PARAM_KEYWORDS, C.STATIC_BLOG_PARAM_DESCRIPTION):
             self.host.bridge.asyncGetParamA(param_name, C.STATIC_BLOG_KEY, 'value', C.SERVER_SECURITY_LIMIT, profile, callback=getCallback(param_name), errback=eb)
 
-        cb = lambda dummy: self.__render_html_blog(items, metadata, options, request, profile)
+        cb = lambda dummy: self.__render_html_blog(items, metadata, options, request, pub_jid)
         defer.DeferredList(d_list).addCallback(cb)
 
-    def __render_html_blog(self, items, metadata, options, request, profile):
+    def __render_html_blog(self, items, metadata, options, request, pub_jid):
         """Actually render the static blog.
         
         If mblog_data is a list of dict, we are missing the comments items so we just
@@ -347,11 +325,11 @@
         @param metadata(dict): original node metadata
         @param options: dict defining the blog's parameters
         @param request: the HTTP request
-        @param profile
+        @param pub_jid (JID): publisher JID
         """
         if not isinstance(options, dict):
             options = {}
-        user = sanitizeHtml(profile)
+        user = sanitizeHtml(pub_jid.user)
         root_url = '../' * len(request.postpath)
         base_url = root_url + 'blog/' + user
 
@@ -400,7 +378,7 @@
         request.write(feed.encode('utf-8'))
         request.finish()
 
-    def render_error_blog(self, error, request, profile):
+    def render_error_blog(self, error, request, pub_jid):
         request.write(self.useTemplate(request, "static_blog_error", {'message': "Can't access requested data"}))
         request.finish()