# HG changeset patch # User souliane # Date 1388147306 -3600 # Node ID 5642939d254e5890b7f69cc94a1f12452eaf7e84 # Parent f89173f4485010eae9bf5721ea52a17d46debf05 core, bridge: new method paramsRegisterApp to register frontend's specific parameters diff -r f89173f44850 -r 5642939d254e frontends/src/bridge/DBus.py --- a/frontends/src/bridge/DBus.py Fri Jan 03 21:25:07 2014 +0100 +++ b/frontends/src/bridge/DBus.py Fri Dec 27 13:28:26 2013 +0100 @@ -152,17 +152,17 @@ def getParamA(self, name, category, attribute="value", profile_key="@DEFAULT@"): return unicode(self.db_core_iface.getParamA(name, category, attribute, profile_key)) - def getParams(self, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None): - return unicode(self.db_core_iface.getParams(security_limit, profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:]))) + def getParams(self, security_limit=-1, app='', profile_key="@DEFAULT@", callback=None, errback=None): + return unicode(self.db_core_iface.getParams(security_limit, app, profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:]))) def getParamsCategories(self, ): return self.db_core_iface.getParamsCategories() - def getParamsForCategory(self, category, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None): - return unicode(self.db_core_iface.getParamsForCategory(category, security_limit, profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:]))) + def getParamsForCategory(self, category, security_limit=-1, app='', profile_key="@DEFAULT@", callback=None, errback=None): + return unicode(self.db_core_iface.getParamsForCategory(category, security_limit, app, profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:]))) - def getParamsUI(self, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None): - return unicode(self.db_core_iface.getParamsUI(security_limit, profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:]))) + def getParamsUI(self, security_limit=-1, app='', profile_key="@DEFAULT@", callback=None, errback=None): + return unicode(self.db_core_iface.getParamsUI(security_limit, app, profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:]))) def getPresenceStatus(self, profile_key="@DEFAULT@"): return self.db_core_iface.getPresenceStatus(profile_key) @@ -191,6 +191,9 @@ def launchAction(self, callback_id, data, profile_key="@DEFAULT@", callback=None, errback=None): return self.db_core_iface.launchAction(callback_id, data, profile_key, reply_handler=callback, error_handler=lambda err:errback(err._dbus_error_name[len(const_ERROR_PREFIX)+1:])) + def paramsRegisterApp(self, xml, security_limit=-1, app=''): + return self.db_core_iface.paramsRegisterApp(xml, security_limit, app) + def registerNewAccount(self, login, password, email, host, port=5222): return unicode(self.db_core_iface.registerNewAccount(login, password, email, host, port)) diff -r f89173f44850 -r 5642939d254e frontends/src/constants.py --- a/frontends/src/constants.py Fri Jan 03 21:25:07 2014 +0100 +++ b/frontends/src/constants.py Fri Dec 27 13:28:26 2013 +0100 @@ -18,7 +18,7 @@ # along with this program. If not, see . -from sat.core.i18n import _ +from sat.core.i18n import _, D_ try: from collections import OrderedDict # only available from python 2.7 @@ -56,7 +56,7 @@ MENU_NORMAL = "NORMAL" # from plugin_misc_text_syntaxes - _SYNTAX_XHTML = "XHTML" - _SYNTAX_CURRENT = "@CURRENT@" + SYNTAX_XHTML = "XHTML" + SYNTAX_CURRENT = "@CURRENT@" NO_SECURITY_LIMIT = -1 diff -r f89173f44850 -r 5642939d254e frontends/src/primitivus/primitivus --- a/frontends/src/primitivus/primitivus Fri Jan 03 21:25:07 2014 +0100 +++ b/frontends/src/primitivus/primitivus Fri Dec 27 13:28:26 2013 +0100 @@ -574,11 +574,11 @@ def onParam(self, menu): def success(params): - self.addWindow(XMLUI(self,xml_data=params)) + self.addWindow(XMLUI(self, xml_data=params)) + def failure(error): self.showPopUp(sat_widgets.Alert(_("Error"), _("Can't get parameters"), ok_cb=self.removePopUp)) - self.bridge.getParamsUI(profile_key=self.profile, callback=success, errback=failure) - + self.bridge.getParamsUI(app=Const.APP_NAME, profile_key=self.profile, callback=success, errback=failure) def onExitRequest(self, menu): QuickApp.onExit(self) diff -r f89173f44850 -r 5642939d254e frontends/src/wix/main_window.py --- a/frontends/src/wix/main_window.py Fri Jan 03 21:25:07 2014 +0100 +++ b/frontends/src/wix/main_window.py Fri Dec 27 13:28:26 2013 +0100 @@ -407,9 +407,7 @@ def onParam(self, e): debug(_("Param request")) - #xmlui = self.bridge.getParamsUI(profile_key=self.profile) - #XMLUI(self, xml_data = xmlui) - param=Param(self) + param = Param(self) def onAbout(self, e): about = wx.AboutDialogInfo() diff -r f89173f44850 -r 5642939d254e frontends/src/wix/param.py --- a/frontends/src/wix/param.py Fri Jan 03 21:25:07 2014 +0100 +++ b/frontends/src/wix/param.py Fri Dec 27 13:28:26 2013 +0100 @@ -25,6 +25,7 @@ from xml.dom import minidom from logging import debug, info, error from sat.tools.jid import JID +from sat_frontends.wix.constants import Const class Param(wx.Frame): @@ -104,6 +105,7 @@ cat_dom.unlink() self.host.bridge.getParamsForCategory(category, + app=Const.APP_NAME, profile_key=self.host.profile, callback=gotParams, errback=errorGettingParams) diff -r f89173f44850 -r 5642939d254e src/bridge/DBus.py --- a/src/bridge/DBus.py Fri Jan 03 21:25:07 2014 +0100 +++ b/src/bridge/DBus.py Fri Dec 27 13:28:26 2013 +0100 @@ -300,10 +300,10 @@ return self._callback("getParamA", unicode(name), unicode(category), unicode(attribute), unicode(profile_key)) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, - in_signature='is', out_signature='s', + in_signature='iss', out_signature='s', async_callbacks=('callback', 'errback')) - def getParams(self, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None): - return self._callback("getParams", security_limit, unicode(profile_key), callback=callback, errback=errback) + def getParams(self, security_limit=-1, app='', profile_key="@DEFAULT@", callback=None, errback=None): + return self._callback("getParams", security_limit, unicode(app), unicode(profile_key), callback=callback, errback=errback) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='', out_signature='as', @@ -312,16 +312,16 @@ return self._callback("getParamsCategories", ) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, - in_signature='sis', out_signature='s', + in_signature='siss', out_signature='s', async_callbacks=('callback', 'errback')) - def getParamsForCategory(self, category, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None): - return self._callback("getParamsForCategory", unicode(category), security_limit, unicode(profile_key), callback=callback, errback=errback) + def getParamsForCategory(self, category, security_limit=-1, app='', profile_key="@DEFAULT@", callback=None, errback=None): + return self._callback("getParamsForCategory", unicode(category), security_limit, unicode(app), unicode(profile_key), callback=callback, errback=errback) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, - in_signature='is', out_signature='s', + in_signature='iss', out_signature='s', async_callbacks=('callback', 'errback')) - def getParamsUI(self, security_limit=-1, profile_key="@DEFAULT@", callback=None, errback=None): - return self._callback("getParamsUI", security_limit, unicode(profile_key), callback=callback, errback=errback) + def getParamsUI(self, security_limit=-1, app='', profile_key="@DEFAULT@", callback=None, errback=None): + return self._callback("getParamsUI", security_limit, unicode(app), unicode(profile_key), callback=callback, errback=errback) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='s', out_signature='a{sa{s(sia{ss})}}', @@ -378,6 +378,12 @@ return self._callback("launchAction", unicode(callback_id), data, unicode(profile_key), callback=callback, errback=errback) @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, + in_signature='sis', out_signature='', + async_callbacks=None) + def paramsRegisterApp(self, xml, security_limit=-1, app=''): + return self._callback("paramsRegisterApp", unicode(xml), security_limit, unicode(app)) + + @dbus.service.method(const_INT_PREFIX+const_CORE_SUFFIX, in_signature='ssssi', out_signature='s', async_callbacks=None) def registerNewAccount(self, login, password, email, host, port=5222): diff -r f89173f44850 -r 5642939d254e src/bridge/bridge.py --- a/src/bridge/bridge.py Fri Jan 03 21:25:07 2014 +0100 +++ b/src/bridge/bridge.py Fri Dec 27 13:28:26 2013 +0100 @@ -59,7 +59,7 @@ def getParam(self, name, namespace): raise NotImplementedError - def getParams(self, security_limit, namespace): + def getParams(self, security_limit, app, namespace): raise NotImplementedError def getHistory(self, from_jid, to_jid, size): diff -r f89173f44850 -r 5642939d254e src/bridge/bridge_constructor/bridge_template.ini --- a/src/bridge/bridge_constructor/bridge_template.ini Fri Jan 03 21:25:07 2014 +0100 +++ b/src/bridge/bridge_constructor/bridge_template.ini Fri Dec 27 13:28:26 2013 +0100 @@ -447,38 +447,44 @@ async= type=method category=core -sig_in=is +sig_in=iss sig_out=s param_0_default=-1 -param_1_default="@DEFAULT@" -doc=Return a SàT XMLUI for parameters +param_1_default='' +param_2_default="@DEFAULT@" +doc=Return a SàT XMLUI for parameters, eventually restrict the result to the parameters concerning a given frontend doc_param_0=%(doc_security_limit)s -doc_param_1=%(doc_profile_key)s +doc_param_1=app: name of the frontend requesting the parameters, or '' to get all parameters +doc_param_2=%(doc_profile_key)s [getParams] async= type=method category=core -sig_in=is +sig_in=iss sig_out=s param_0_default=-1 -param_1_default="@DEFAULT@" -doc=Return XML of parameters +param_1_default='' +param_2_default="@DEFAULT@" +doc=Return XML of parameters, eventually restrict the result to the parameters concerning a given frontend doc_param_0=%(doc_security_limit)s -doc_param_1=%(doc_profile_key)s +doc_param_1=app: name of the frontend requesting the parameters, or '' to get all parameters +doc_param_2=%(doc_profile_key)s [getParamsForCategory] async= type=method category=core -sig_in=sis +sig_in=siss sig_out=s param_1_default=-1 -param_2_default="@DEFAULT@" -doc=Return a xml of all params in a category +param_2_default='' +param_3_default="@DEFAULT@" +doc=Return a xml of all params in a category, eventually restrict the result to the parameters concerning a given frontend doc_param_0=category: Category to get doc_param_1=%(doc_security_limit)s -doc_param_2=%(doc_profile_key)s +doc_param_2=app: name of the frontend requesting the parameters, or '' to get all parameters +doc_param_3=%(doc_profile_key)s [getParamsCategories] type=method @@ -488,6 +494,18 @@ doc=Get all categories currently existing in parameters doc_return=list of categories +[paramsRegisterApp] +type=method +category=core +sig_in=sis +sig_out= +param_1_default=-1 +param_2_default='' +doc=Register frontend's specific parameters +doc_param_0=xml: XML definition of the parameters to be added +doc_param_1=%(doc_security_limit)s +doc_param_2=app: name of the frontend registering the parameters + [getHistory] async= type=method diff -r f89173f44850 -r 5642939d254e src/core/sat_main.py --- a/src/core/sat_main.py Fri Jan 03 21:25:07 2014 +0100 +++ b/src/core/sat_main.py Fri Dec 27 13:28:26 2013 +0100 @@ -150,6 +150,7 @@ self.bridge.register("getParams", self.memory.getParams) self.bridge.register("getParamsForCategory", self.memory.getParamsForCategory) self.bridge.register("getParamsCategories", self.memory.getParamsCategories) + self.bridge.register("paramsRegisterApp", self.memory.paramsRegisterApp) self.bridge.register("getHistory", self.memory.getHistory) self.bridge.register("setPresence", self.setPresence) self.bridge.register("subscription", self.subscription) diff -r f89173f44850 -r 5642939d254e src/memory/memory.py --- a/src/memory/memory.py Fri Jan 03 21:25:07 2014 +0100 +++ b/src/memory/memory.py Fri Dec 27 13:28:26 2013 +0100 @@ -295,10 +295,40 @@ #the node is new return None - def updateParams(self, xml): + def updateParams(self, xml, security_limit=NO_SECURITY_LIMIT, app=''): """import xml in parameters, do nothing if the param already exist - @param xml: parameters in xml form""" - src_dom = minidom.parseString(xml.encode('utf-8')) + If security_limit is specified and greater than -1, the parameters + that have a security level lower than security_limit are skipped. + @param xml: parameters in xml form + @param security_limit: -1 means no security then the higher the most secure + @param app: name of the frontend registering the parameters or empty value + """ + src_parent = minidom.parseString(xml.encode('utf-8')).documentElement + + def pre_process_app_node(src_parent, security_limit, app): + """Parameters that are registered from a frontend must be checked""" + to_remove = [] + for type_node in src_parent.childNodes: + if type_node.nodeName != INDIVIDUAL: + to_remove.append(type_node) # accept individual parameters only + continue + for cat_node in type_node.childNodes: + if cat_node.nodeName != 'category': + to_remove.append(cat_node) + continue + to_remove_count = 0 # count the params to be removed from current category + for node in cat_node.childNodes: + if node.nodeName != "param" or not self.checkSecurityLimit(node, security_limit): + to_remove.append(node) + to_remove_count += 1 + continue + node.setAttribute('app', app) + if len(cat_node.childNodes) == to_remove_count: # remove empty category + for dummy in xrange(0, to_remove_count): + to_remove.pop() + to_remove.append(cat_node) + for node in to_remove: + node.parentNode.removeChild(node) def import_node(tgt_parent, src_parent): for child in src_parent.childNodes: @@ -315,7 +345,28 @@ # the node already exists, we recurse 1 more level import_node(node, child) - import_node(self.dom.documentElement, src_dom.documentElement) + if app: + pre_process_app_node(src_parent, security_limit, app) + import_node(self.dom.documentElement, src_parent) + + def paramsRegisterApp(self, xml, security_limit, app): + """Register frontend's specific parameters + If security_limit is specified and greater than -1, the parameters + that have a security level lower than security_limit are skipped. + @param xml: XML definition of the parameters to be added + @param security_limit: -1 means no security then the higher the most secure + @param app: name of the frontend registering the parameters + """ + if not app: + warning(_("Trying to register frontends parameters with no specified app: aborted")) + return + if not hasattr(self, "frontends_cache"): + self.frontends_cache = {} + if app in self.frontends_cache: + warning(_("Trying to register twice frontends parameters for %(app)s: aborted" % {"app": app})) + return + self.updateParams(xml, security_limit, app) + debug("Frontends parameters registered for %(app)s" % {'app': app}) def __default_ok(self, value, name, category): #FIXME: will not work with individual parameters @@ -471,12 +522,13 @@ return None return cache[(category, name)] - def __constructProfileXml(self, security_limit, profile): + def __constructProfileXml(self, security_limit, app, profile): """Construct xml for asked profile, filling values when needed /!\ as noticed in doc, don't forget to unlink the minidom.Document - @security_limit: NO_SECURITY_LIMIT (-1) to return all the params. + @param security_limit: NO_SECURITY_LIMIT (-1) to return all the params. Otherwise sole the params which have a security level defined *and* lower or equal to the specified value are returned. + @param app: name of the frontend requesting the parameters, or '' to get all parameters @param profile: profile name (not key !) @return: a deferred that fire a minidom.Document of the profile xml (cf warning above) """ @@ -518,6 +570,8 @@ name = param_node.getAttribute('name') if not self.checkSecurityLimit(param_node, security_limit): continue + if not self.checkApp(param_node, app): + continue if name not in dest_params: # this is reached when a previous category exists dest_params[name] = param_node.cloneNode(True) @@ -551,18 +605,31 @@ return d.addCallback(constructProfile, profile_cache) - def getParamsUI(self, security_limit, profile_key): - """Return a SàT XMLUI for parameters, with given profile""" + def getParamsUI(self, security_limit, app, profile_key): + """ + @param security_limit: NO_SECURITY_LIMIT (-1) to return all the params. + Otherwise sole the params which have a security level defined *and* + lower or equal to the specified value are returned. + @param app: name of the frontend requesting the parameters, or '' to get all parameters + @param profile_key: Profile key which can be either a magic (eg: @DEFAULT@) or the name of an existing profile. + @return: a SàT XMLUI for parameters + """ profile = self.getProfileName(profile_key) if not profile: error(_("Asking params for inexistant profile")) return "" - d = self.getParams(security_limit, profile) + d = self.getParams(security_limit, app, profile) return d.addCallback(lambda param_xml: paramsXml2xmlUI(param_xml)) - def getParams(self, security_limit, profile_key): - """Construct xml for asked profile - Take params xml as skeleton""" + def getParams(self, security_limit, app, profile_key): + """Construct xml for asked profile, take params xml as skeleton + @param security_limit: NO_SECURITY_LIMIT (-1) to return all the params. + Otherwise sole the params which have a security level defined *and* + lower or equal to the specified value are returned. + @param app: name of the frontend requesting the parameters, or '' to get all parameters + @param profile_key: Profile key which can be either a magic (eg: @DEFAULT@) or the name of an existing profile. + @return: XML of parameters + """ profile = self.getProfileName(profile_key) if not profile: error(_("Asking params for inexistant profile")) @@ -573,10 +640,18 @@ prof_xml.unlink() return '\n'.join((line for line in return_xml.split('\n') if line)) - return self.__constructProfileXml(security_limit, profile).addCallback(returnXML) + return self.__constructProfileXml(security_limit, app, profile).addCallback(returnXML) - def getParamsForCategory(self, category, security_limit, profile_key): - """Return node's xml for selected category""" + def getParamsForCategory(self, category, security_limit, app, profile_key): + """ + @param category: the desired category + @param security_limit: NO_SECURITY_LIMIT (-1) to return all the params. + Otherwise sole the params which have a security level defined *and* + lower or equal to the specified value are returned. + @param app: name of the frontend requesting the parameters, or '' to get all parameters + @param profile_key: Profile key which can be either a magic (eg: @DEFAULT@) or the name of an existing profile. + @return: node's xml for selected category + """ #TODO: manage category of general type (without existant profile) profile = self.getProfileName(profile_key) if not profile: @@ -593,7 +668,7 @@ prof_xml.unlink() return "" - d = self.__constructProfileXml(security_limit, profile) + d = self.__constructProfileXml(security_limit, app, profile) return d.addCallback(returnCategoryXml) def _getParamNode(self, name, category, type_="@ALL@"): # FIXME: is type_ useful ? @@ -680,6 +755,16 @@ return True return False + def checkApp(self, node, app): + """Check the given node against the given app. + @param node: parameter node + @param app: name of the frontend requesting the parameters, or '' to get all parameters + @return: True if this node concerns the given app. + """ + if not app or not node.hasAttribute("app"): + return True + return node.getAttribute("app") == app + class Memory(object): """This class manage all persistent informations""" @@ -1063,14 +1148,14 @@ def asyncGetStringParamA(self, name, category, attr="value", security_limit=NO_SECURITY_LIMIT, profile_key='@NONE@'): return self.params.asyncGetStringParamA(name, category, attr, security_limit, profile_key) - def getParamsUI(self, security_limit=NO_SECURITY_LIMIT, profile_key='@NONE@'): - return self.params.getParamsUI(security_limit, profile_key) + def getParamsUI(self, security_limit=NO_SECURITY_LIMIT, app='', profile_key='@NONE@'): + return self.params.getParamsUI(security_limit, app, profile_key) - def getParams(self, security_limit=NO_SECURITY_LIMIT, profile_key='@NONE@'): - return self.params.getParams(security_limit, profile_key) + def getParams(self, security_limit=NO_SECURITY_LIMIT, app='', profile_key='@NONE@'): + return self.params.getParams(security_limit, app, profile_key) - def getParamsForCategory(self, category, security_limit=NO_SECURITY_LIMIT, profile_key='@NONE@'): - return self.params.getParamsForCategory(category, security_limit, profile_key) + def getParamsForCategory(self, category, security_limit=NO_SECURITY_LIMIT, app='', profile_key='@NONE@'): + return self.params.getParamsForCategory(category, security_limit, app, profile_key) def getParamsCategories(self): return self.params.getParamsCategories() @@ -1081,5 +1166,8 @@ def updateParams(self, xml): return self.params.updateParams(xml) + def paramsRegisterApp(self, xml, security_limit=NO_SECURITY_LIMIT, app=''): + return self.params.paramsRegisterApp(xml, security_limit, app) + def setDefault(self, name, category, callback, errback=None): return self.params.setDefault(name, category, callback, errback)