changeset 606:7af8f4ab3675 frontends_multi_profiles

browser side: fixed avatar getting + better DEFAULT/EMPTY avatars constants + use of jid.JID for microblog's author
author Goffi <goffi@goffi.org>
date Mon, 09 Feb 2015 21:55:16 +0100
parents 917e271975d9
children 537649f6a2d0
files src/browser/libervia_main.py src/browser/sat_browser/base_widget.py src/browser/sat_browser/blog.py src/browser/sat_browser/constants.py src/browser/sat_browser/contact_list.py src/common/constants.py src/server/blog.py
diffstat 7 files changed, 58 insertions(+), 52 deletions(-) [+]
line wrap: on
line diff
--- a/src/browser/libervia_main.py	Mon Feb 09 21:46:15 2015 +0100
+++ b/src/browser/libervia_main.py	Mon Feb 09 21:55:16 2015 +0100
@@ -51,6 +51,7 @@
 from sat_browser import notification
 
 from sat_browser.constants import Const as C
+import os.path
 
 
 try:
@@ -98,7 +99,6 @@
         self.cached_params = {}
 
         #FIXME: to be removed (managed with cache and in quick_frontend
-        self.avatars_cache = {}  # keep track of jid's avatar hash (key=jid, value=file)
         #FIXME: microblog cache should be managed directly in blog module
         self.mblog_cache = []  # used to keep our own blog entries in memory, to show them in new mblog panel
 
@@ -197,26 +197,21 @@
 
     # FIXME: must not call _entityDataUpdatedCb by itself
     #        should not get VCard, backend plugin must be fixed too
-    # def getAvatar(self, jid_str):
-    #     """Return avatar of a jid if in cache, else ask for it.
+    def getAvatarURL(self, jid_):
+        """Return avatar of a jid if in cache, else ask for it.
 
-    #     @param jid_str (str): JID of the contact
-    #     @return: the URL to the avatar (str)
-    #     """
-    #     def dataReceived(result):
-    #         if 'avatar' in result:
-    #             self._entityDataUpdatedCb(jid_str, 'avatar', result['avatar'])
-    #         else:
-    #             self.bridge.call("getCard", None, jid_str)
-
-    #     def avatarError(error_data):
-    #         # The jid is maybe not in our roster, we ask for the VCard
-    #         self.bridge.call("getCard", None, jid_str)
-
-    #     if jid_str not in self.avatars_cache:
-    #         self.bridge.call('getEntityData', (dataReceived, avatarError), jid_str, ['avatar'])
-    #         self.avatars_cache[jid_str] = C.DEFAULT_AVATAR
-    #     return self.avatars_cache[jid_str]
+        @param jid_ (jid.JID): JID of the contact
+        @return: the URL to the avatar (str)
+        """
+        assert isinstance(jid_, jid.JID)
+        avatar_hash = self.contact_lists[C.PROF_KEY_NONE].getCache(jid_, 'avatar')
+        if avatar_hash is None:
+            # we have no value for avatar_hash, so we request the vcard
+            self.bridge.getCard(unicode(jid_), profile=C.PROF_KEY_NONE)
+        if not avatar_hash:
+            return C.DEFAULT_AVATAR_URL
+        ret = os.path.join(C.AVATARS_DIR, avatar_hash)
+        return ret
 
     def registerWidget(self, wid):
         log.debug("Registering %s" % wid.getDebugName())
@@ -348,8 +343,8 @@
         # for cat, name in C.CACHED_PARAMS:
         #     self.bridge.call('asyncGetParamA', param_cb(cat, name, count), name, cat)
 
-    def profilePlugged(self, profile):
-        #we fill the panels already here
+    def profilePlugged(self, dummy):
+        # we fill the panels already here
         for widget in self.widgets.getWidgets(blog.MicroblogPanel):
             if widget.accept_all():
                 self.bridge.getMassiveLastMblogs('ALL', [], 10, profile=C.PROF_KEY_NONE, callback=widget.massiveInsert)
@@ -424,7 +419,7 @@
         """
         if data is None:
             data = {}
-        self.bridge.call('launchAction', (self._actionCb, self._actionEb), callback_id, data)
+        self.bridge.launchAction(callback_id, data, profile=C.PROF_KEY_NONE, callback=self._actionCb, errback=self._actionEb)
 
     def _getContactsCB(self, contacts_data):
         for contact_ in contacts_data:
@@ -800,6 +795,7 @@
         self.contact_panel.updateContact(contact_jid, attributes, groups)
 
     def _entityDataUpdatedCb(self, entity_jid_s, key, value):
+        raise Exception # FIXME should not be here
         if key == "avatar":
             avatar = '/' + C.AVATARS_DIR + value
             self.avatars_cache[entity_jid_s] = avatar
--- a/src/browser/sat_browser/base_widget.py	Mon Feb 09 21:46:15 2015 +0100
+++ b/src/browser/sat_browser/base_widget.py	Mon Feb 09 21:55:16 2015 +0100
@@ -205,13 +205,12 @@
             menu_styles.update(styles)
         base_menu.GenericMenuBar.__init__(self, host, vertical=vertical, styles=menu_styles)
 
-        # FIXME
-        # if hasattr(parent, 'addMenus'):
-        #     # regroup all the dynamic menu categories in a sub-menu
-        #     sub_menu = WidgetSubMenuBar(host, vertical=True)
-        #     parent.addMenus(sub_menu)
-        #     if len(sub_menu.getCategories()) > 0:
-        #         self.addCategory('', '', 'plugins', sub_menu)
+        if hasattr(parent, 'addMenus'):
+            # regroup all the dynamic menu categories in a sub-menu
+            sub_menu = WidgetSubMenuBar(host, vertical=True)
+            parent.addMenus(sub_menu)
+            if len(sub_menu.getCategories()) > 0:
+                self.addCategory('', '', 'plugins', sub_menu)
 
     @classmethod
     def getCategoryHTML(cls, menu_name_i18n, type_):
--- a/src/browser/sat_browser/blog.py	Mon Feb 09 21:46:15 2015 +0100
+++ b/src/browser/sat_browser/blog.py	Mon Feb 09 21:55:16 2015 +0100
@@ -47,11 +47,14 @@
 import richtext
 from constants import Const as C
 from sat_frontends.quick_frontend import quick_widgets
+from sat_frontends.tools import jid
 
 # TODO: at some point we should decide which behaviors to keep and remove these two constants
 TOGGLE_EDITION_USE_ICON = False  # set to True to use an icon inside the "toggle syntax" button
 NEW_MESSAGE_USE_BUTTON = False  # set to True to display the "New message" button instead of an empty entry
 
+unicode = str # XXX: pyjamas doesn't manage unicode
+
 
 class MicroblogItem():
     # XXX: should be moved in a separated module
@@ -64,7 +67,7 @@
         self.title_xhtml = data.get('title_xhtml', '')
         self.content = data.get('content', '')
         self.content_xhtml = data.get('content_xhtml', '')
-        self.author = data['author']
+        self.author = jid.JID(data['author'])
         self.updated = float(data.get('updated', 0))  # XXX: int doesn't work here
         self.published = float(data.get('published', self.updated))  # XXX: int doesn't work here
         self.service = data.get('service', '')
@@ -104,8 +107,8 @@
 
         entry_avatar = SimplePanel()
         entry_avatar.setStyleName('mb_entry_avatar')
-        # FIXME
-        self.avatar = Image(C.DEFAULT_AVATAR) # self._blog_panel.host.getAvatar(self.author))
+        assert isinstance(self.author, jid.JID) # FIXME: temporary
+        self.avatar = Image(self._blog_panel.host.getAvatarURL(self.author)) # FIXME: self.author should be initially a jid.JID
         entry_avatar.add(self.avatar)
         self.panel.add(entry_avatar)
 
@@ -139,7 +142,7 @@
         self.header.setHTML("""<div class='mb_entry_header'>
                                    <span class='mb_entry_author'>%(author)s</span> on
                                    <span class='mb_entry_timestamp'>%(published)s</span>%(updated)s
-                               </div>""" % {'author': html_tools.html_sanitize(self.author),
+                               </div>""" % {'author': html_tools.html_sanitize(unicode(self.author)),
                                             'published': datetime.fromtimestamp(self.published),
                                             'updated': update_text if self.published != self.updated else ''
                                             }
@@ -275,7 +278,7 @@
         data = {'id': str(time()),
                 'new': True,
                 'type': 'comment',
-                'author': self._blog_panel.host.whoami.bare,
+                'author': unicode(self._blog_panel.host.whoami.bare),
                 'service': self.comments_service,
                 'node': self.comments_node
                 }
@@ -391,7 +394,7 @@
                     self.new_button.setVisible(False)
                 data = {'id': str(time()),
                         'new': True,
-                        'author': self.host.whoami.bare,
+                        'author': unicode(self.host.whoami.bare),
                         }
                 entry = self.addEntry(data)
                 entry.edit(True)
@@ -541,10 +544,11 @@
     def addEntryIfAccepted(self, sender, groups, mblog_entry):
         """Check if an entry can go in MicroblogPanel and add to it
 
-        @param sender: jid of the entry sender
+        @param sender(jid.JID): jid of the entry sender
         @param groups: groups which can receive this entry
         @param mblog_entry: panels.MicroblogItem instance
         """
+        assert isinstance(sender, jid.JID) # FIXME temporary
         if (mblog_entry.type == "comment"
             or self.isJidAccepted(sender)
             or (groups == None and sender == self.host.profiles[self.profile].whoami.bare)
@@ -660,19 +664,22 @@
         if self.selected_entry:
             self.selected_entry.removeStyleName('selected_entry')
         if entry:
-            log.debug("microblog entry selected (author=%s)" % entry.author)
+            log.debug("microblog entry selected (author=%s)" % unicode(entry.author))
             entry.addStyleName('selected_entry')
         self.selected_entry = entry
 
-    def updateValue(self, type_, jid, value):
+    def updateValue(self, type_, jid_, value):
         """Update a jid value in entries
+
         @param type_: one of 'avatar', 'nick'
-        @param jid: jid concerned
+        @param jid_(jid.JID): jid concerned
         @param value: new value"""
+        assert isinstance(jid_, jid.JID) # FIXME: temporary
         def updateVPanel(vpanel):
+            avatar_url = self.host.getAvatarURL(jid_)
             for child in vpanel.children:
-                if isinstance(child, MicroblogEntry) and child.author == jid:
-                    child.updateAvatar(value)
+                if isinstance(child, MicroblogEntry) and child.author == jid_:
+                    child.updateAvatar(avatar_url)
                 elif isinstance(child, VerticalPanel):
                     updateVPanel(child)
         if type_ == 'avatar':
@@ -700,6 +707,7 @@
         @param jid_(jid.JID): jid to check
         @return: True if the jid is accepted
         """
+        assert isinstance(jid_, jid.JID) # FIXME temporary
         if self.accept_all():
             return True
         for group in self._accepted_groups:
--- a/src/browser/sat_browser/constants.py	Mon Feb 09 21:46:15 2015 +0100
+++ b/src/browser/sat_browser/constants.py	Mon Feb 09 21:55:16 2015 +0100
@@ -35,6 +35,4 @@
                      ('General', C.SHOW_EMPTY_GROUPS),
                      ]
 
-    # Empty avatar
-    EMPTY_AVATAR = "/media/misc/empty_avatar"
     WEB_PANEL_DEFAULT_URL = "http://salut-a-toi.org"
--- a/src/browser/sat_browser/contact_list.py	Mon Feb 09 21:46:15 2015 +0100
+++ b/src/browser/sat_browser/contact_list.py	Mon Feb 09 21:55:16 2015 +0100
@@ -113,7 +113,7 @@
 
     @classmethod
     def getCategoryHTML(cls, menu_name_i18n, type_):
-        return '<img src="%s"/>' % C.DEFAULT_AVATAR
+        return '<img src="%s"/>' % C.DEFAULT_AVATAR_URL
 
     def setUrl(self, url):
         """Set the URL of the contact avatar."""
@@ -128,7 +128,7 @@
         self.jid = jid_
         self.label = ContactLabel(jid_, name)
         self.avatar = ContactMenuBar(self, host) if handle_menu else Image()
-        # self.updateAvatar(host.getAvatar(jid_)) # FIXME
+        self.updateAvatar(host.getAvatarURL(jid_))
         self.add(self.avatar)
         self.add(self.label)
         if click_listener:
--- a/src/common/constants.py	Mon Feb 09 21:46:15 2015 +0100
+++ b/src/common/constants.py	Mon Feb 09 21:55:16 2015 +0100
@@ -19,6 +19,7 @@
 
 from sat.core.i18n import D_
 from sat_frontends import constants
+import os.path
 
 
 class Const(constants.Const):
@@ -46,8 +47,12 @@
     UPLOAD_KO = 'UPLOAD KO'
     UNKNOWN_ERROR = 'UNMANAGED FAULT STRING (%s)'
 
-    # PATHS
+    # directories
     AVATARS_DIR = "avatars/"
+    MEDIA_DIR = "media/"
 
-    # Default avatar
-    DEFAULT_AVATAR = "/media/misc/default_avatar.png"
+    # avatars
+    DEFAULT_AVATAR_FILE = "default_avatar.png"
+    DEFAULT_AVATAR_URL = os.path.join(MEDIA_DIR, "misc", DEFAULT_AVATAR_FILE)
+    EMPTY_AVATAR_FILE = "empty_avatar"
+    EMPTY_AVATAR_URL = os.path.join(MEDIA_DIR, "misc", EMPTY_AVATAR_FILE)
--- a/src/server/blog.py	Mon Feb 09 21:46:15 2015 +0100
+++ b/src/server/blog.py	Mon Feb 09 21:55:16 2015 +0100
@@ -96,14 +96,14 @@
         except IndexError:  # impossible to guess the entity
             return
         log.debug(_("Using default avatar for entity %s") % entity_jid_s)
-        self.avatars_cache[entity_jid_s] = C.DEFAULT_AVATAR
-        self.waiting_deferreds[entity_jid_s][1].callback(C.DEFAULT_AVATAR)
+        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 (str):
+        @param profile(unicode): %(doc_profile)s
         @return: deferred avatar path, relative to the server's root
         """
         jid_s = (profile + '@' + self.host.bridge.getNewAccountDomain()).lower()