changeset 336:629c99bbd031

browser + server side: refactored menus: - getMenus is added to Register class, so it can be used before being logged - dynamic menus are added to main menu bar - security limit is used - menus use i18n
author Goffi <goffi@goffi.org>
date Tue, 04 Feb 2014 16:49:20 +0100
parents e8c26e24a6c7
children ea1be522ba88
files browser_side/menu.py libervia.py libervia_server/__init__.py
diffstat 3 files changed, 76 insertions(+), 43 deletions(-) [+]
line wrap: on
line diff
--- a/browser_side/menu.py	Tue Feb 04 16:49:20 2014 +0100
+++ b/browser_side/menu.py	Tue Feb 04 16:49:20 2014 +0100
@@ -43,12 +43,13 @@
 import dialog
 from contact_group import ContactGroupEditor
 import re
+from sat.core.i18n import _
 
 
 class MenuCmd:
 
-    def __init__(self, object, handler):
-        self._object = object
+    def __init__(self, object_, handler):
+        self._object = object_
         self._handler = handler
 
     def execute(self):
@@ -56,6 +57,16 @@
         handler()
 
 
+class PluginMenuCmd:
+
+    def __init__(self, host, action_id):
+        self.host = host
+        self.action_id = action_id
+
+    def execute(self):
+        self.host.launchAction(self.action_id, None)
+
+
 class LiberviaMenuBar(MenuBar):
 
     def __init__(self):
@@ -138,51 +149,65 @@
         self.host = host
         SimplePanel.__init__(self)
         self.setStyleName('menuContainer')
+
+    def createMenus(self, add_menus):
         _item_tpl = "<img src='media/icons/menu/%s_menu_red.png' />%s"
-
-        menu_general = MenuBar(vertical=True)
-        menu_general.addItem("Web widget", MenuCmd(self, "onWebWidget"))
-        menu_general.addItem("Disconnect", MenuCmd(self, "onDisconnect"))
+        menus_dict = {}
+        menus_order = []
 
-        menu_contacts = MenuBar(vertical=True)
-        menu_contacts.addItem("Add contact", MenuCmd(self, "onAddContact"))
-        menu_contacts.addItem("Update contact", MenuCmd(self, "onUpdateContact"))
-        menu_contacts.addItem("Remove contact", MenuCmd(self, "onRemoveContact"))
-        menu_contacts.addItem("Manage groups", MenuCmd(self, "onManageContactGroups"))
+        def addMenu(menu_name, menu_name_i18n, item_name_i18n, icon, menu_cmd):
+            """ add a menu to menu_dict """
+            print "addMenu:",menu_name, menu_name_i18n, item_name_i18n, icon, menu_cmd
+            try:
+                menu_bar = menus_dict[menu_name]
+            except KeyError:
+                menu_bar = menus_dict[menu_name] = MenuBar(vertical=True)
+                menus_order.append((menu_name, menu_name_i18n, icon))
+            menu_bar.addItem(item_name_i18n, menu_cmd)
 
-        menu_group = MenuBar(vertical=True)
-        menu_group.addItem("Discussion", MenuCmd(self, "onJoinRoom"))
-        menu_group.addItem("Collective radio", MenuCmd(self, "onCollectiveRadio"))
-
-        menu_games = MenuBar(vertical=True)
-        menu_games.addItem("Tarot", MenuCmd(self, "onTarotGame"))
-        menu_games.addItem("Xiangqi", MenuCmd(self, "onXiangqiGame"))
+        addMenu("General", _("General"), _("Web widget"), 'home', MenuCmd(self, "onWebWidget"))
+        addMenu("General", _("General"), _("Disconnect"), 'home', MenuCmd(self, "onDisconnect"))
+        addMenu("Contacts", _("Contacts"), _("Add contact"), 'social', MenuCmd(self, "onAddContact"))
+        addMenu("Contacts", _("Contacts"), _("Update contact"), 'social', MenuCmd(self, "onUpdateContact"))
+        addMenu("Contacts", _("Contacts"), _("Remove contact"), 'social', MenuCmd(self, "onRemoveContact"))
+        addMenu("Contacts", _("Contacts"), _("Manage groups"), 'social', MenuCmd(self, "onManageContactGroups"))
+        addMenu("Groups", _("Groups"), _("Discussion"), 'social', MenuCmd(self, "onJoinRoom"))
+        addMenu("Groups", _("Groups"), _("Collective radio"), 'social', MenuCmd(self, "onCollectiveRadio"))
+        addMenu("Games", _("Games"), _("Tarot"), 'games', MenuCmd(self, "onTarotGame"))
+        addMenu("Games", _("Games"), _("Xiangqi"), 'games', MenuCmd(self, "onXiangqiGame"))
 
-        menu_help = MenuBar(vertical=True)
-        menu_help.addItem("Social contract", MenuCmd(self, "onSocialContract"))
-        menu_help.addItem("About", MenuCmd(self, "onAbout"))
+        # additional menus
+        for action_id, type_, path, path_i18n in add_menus:
+            if not path:
+                print "WARNING: skipping menu without path"
+                continue
+            menu_name = path[0]
+            menu_name_i18n = path_i18n[0]
+            item_name_i18n = ' | '.join(path_i18n[1:])
+            if not item_name:
+                print "WARNING: skipping menu with a path of lenght 1 [%s]" % path[0]
+                continue
+            addMenu(menu_name, menu_name_i18n, item_name_i18n, 'plugins', PluginMenuCmd(self.host, action_id))
 
-        self.menu_settings = MenuBar(vertical=True)
-        self.item_params = self.menu_settings.addItem("Parameters",
-                                                      MenuCmd(self, "onParameters"))
+        menus_order.append(None) # we add separator
+
+        addMenu("Help", _("Help"), _("Social contract"), 'help', MenuCmd(self, "onSocialContract"))
+        addMenu("Help", _("Help"), _("About"), 'help', MenuCmd(self, "onAbout"))
+        addMenu("Settings", _("Settings"), _("Parameters"), 'settings', MenuCmd(self, "onParameters"))
+
         # XXX: temporary, will change when a full profile will be managed in SàT
-        self.menu_settings.addItem("Upload avatar", MenuCmd(self, "onAvatarUpload"))
+        addMenu("Settings", _("Settings"), _("Upload avatar"), 'settings', MenuCmd(self, "onAvatarUpload"))
 
         menubar = LiberviaMenuBar()
 
-        for _name, _icon, _menu in [('General', 'home', menu_general),
-                                    ('Contacts', 'social', menu_contacts),
-                                    ('Groups', 'social', menu_group),
-                                    ('Games', 'games', menu_games)]:
-            menubar.addItem(MenuItem(_item_tpl % (_icon, _name), True, _menu))
-
-        _separator = MenuItem('', None)
-        _separator.setStyleName('menuSeparator')
-        menubar.addItem(_separator, None)
-
-        for _name, _icon, _menu in [('Help', 'help', menu_help),
-                                    ('Settings', 'settings', self.menu_settings)]:
-            menubar.addItem(MenuItem(_item_tpl % (_icon, _name), True, _menu))
+        for menu_data in menus_order:
+            if menu_data is None:
+                _separator = MenuItem('', None)
+                _separator.setStyleName('menuSeparator')
+                menubar.addItem(_separator, None)
+            else:
+                menu_name, menu_name_i18n, icon = menu_data
+                menubar.addItem(MenuItem(_item_tpl % (icon, menu_name_i18n), True, menus_dict[menu_name]))
 
         self.add(menubar)
 
@@ -335,7 +360,7 @@
                 return
             body = XMLUI(self.host, xmlui)
             _dialog = dialog.GenericDialog("Parameters", body, options=['NO_CLOSE'])
-            body.setCloseCb(_dialog.close) 
+            body.setCloseCb(_dialog.close)
             _dialog.setSize('80%', '80%')
             _dialog.show()
         self.host.bridge.call('getParamsUI', gotParams)
--- a/libervia.py	Tue Feb 04 16:49:20 2014 +0100
+++ b/libervia.py	Tue Feb 04 16:49:20 2014 +0100
@@ -113,7 +113,7 @@
 class RegisterCall(LiberviaJsonProxy):
     def __init__(self):
         LiberviaJsonProxy.__init__(self, "/register_api",
-                        ["isRegistered", "isConnected", "connect", "registerParams"])
+                        ["isRegistered", "isConnected", "connect", "registerParams", "getMenus"])
 
 
 class BridgeCall(LiberviaJsonProxy):
@@ -127,7 +127,7 @@
                          "getWaitingSub", "subscription", "delContact", "updateContact", "getCard",
                          "getEntityData", "getParamsUI", "asyncGetParamA", "setParam", "launchAction",
                          "disconnect", "chatStateComposing", "getNewAccountDomain", "confirmationAnswer",
-                         "syntaxConvert"
+                         "syntaxConvert",
                         ])
 
 
@@ -184,6 +184,7 @@
         self.notification = Notification()
         DOM.addEventPreview(self)
         self._register = RegisterCall()
+        self._register.call('getMenus', self.panel.menu.createMenus)
         self._register.call('registerParams', None)
         self._register.call('isRegistered', self._isRegisteredCB)
         self.initialised = False
--- a/libervia_server/__init__.py	Tue Feb 04 16:49:20 2014 +0100
+++ b/libervia_server/__init__.py	Tue Feb 04 16:49:20 2014 +0100
@@ -480,6 +480,8 @@
                     % (name, category))
 
     def jsonrpc_launchAction(self, callback_id, data):
+        #FIXME: any action can be launched, this can be a huge security issue if callback_id can be guessed
+        #       a security system with authorised callback_id must be implemented, similar to the one for authorised params
         profile = ISATSession(self.session).profile
         d = self.asyncBridgeCall("launchAction", callback_id, data, profile)
         return d
@@ -540,8 +542,8 @@
         _session = request.getSession()
         parsed = jsonrpclib.loads(request.content.read())
         method = parsed.get("method")
-        if  method != "isRegistered" and method != "registerParams":
-            #if we don't call login or isRegistered, we need to be identified
+        if  method not in ['isRegistered',  'registerParams', 'getMenus']:
+            #if we don't call these methods, we need to be identified
             profile = ISATSession(_session).profile
             if not profile:
                 #user is not identified, we return a jsonrpc fault
@@ -741,6 +743,11 @@
 
         self.sat_host.bridge.paramsRegisterApp(params, Const.SECURITY_LIMIT, Const.APP_NAME)
 
+    def jsonrpc_getMenus(self):
+        """Return the parameters XML for profile"""
+        # XXX: we put this method in Register because we get menus before being logged
+        return self.sat_host.bridge.getMenus('', Const.SECURITY_LIMIT)
+
 
 class SignalHandler(jsonrpc.JSONRPC):