diff --git a/frontends/src/bridge/DBus.py b/frontends/src/bridge/DBus.py
index 4b1bbcee..8f10d2f1 100644
--- a/frontends/src/bridge/DBus.py
+++ b/frontends/src/bridge/DBus.py
@@ -152,17 +152,17 @@ class DBusBridgeFrontend(BridgeFrontend):
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 @@ class DBusBridgeFrontend(BridgeFrontend):
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 --git a/frontends/src/constants.py b/frontends/src/constants.py
index d283bf47..0c5fb072 100644
--- a/frontends/src/constants.py
+++ b/frontends/src/constants.py
@@ -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 @@ class Const(object):
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 --git a/frontends/src/primitivus/primitivus b/frontends/src/primitivus/primitivus
index 9ac57820..f89feb8d 100755
--- a/frontends/src/primitivus/primitivus
+++ b/frontends/src/primitivus/primitivus
@@ -574,11 +574,11 @@ class PrimitivusApp(QuickApp, InputHistory):
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 --git a/frontends/src/wix/main_window.py b/frontends/src/wix/main_window.py
index 639ee680..dbf421d5 100644
--- a/frontends/src/wix/main_window.py
+++ b/frontends/src/wix/main_window.py
@@ -407,9 +407,7 @@ class MainWindow(wx.Frame, QuickApp):
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 --git a/frontends/src/wix/param.py b/frontends/src/wix/param.py
index d5c80324..99f667a4 100644
--- a/frontends/src/wix/param.py
+++ b/frontends/src/wix/param.py
@@ -25,6 +25,7 @@ import pdb
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 @@ class Param(wx.Frame):
cat_dom.unlink()
self.host.bridge.getParamsForCategory(category,
+ app=Const.APP_NAME,
profile_key=self.host.profile,
callback=gotParams,
errback=errorGettingParams)
diff --git a/src/bridge/DBus.py b/src/bridge/DBus.py
index 7c9b3969..6d183c25 100755
--- a/src/bridge/DBus.py
+++ b/src/bridge/DBus.py
@@ -300,10 +300,10 @@ class DbusObject(dbus.service.Object):
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 @@ class DbusObject(dbus.service.Object):
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})}}',
@@ -377,6 +377,12 @@ class DbusObject(dbus.service.Object):
def launchAction(self, callback_id, data, profile_key="@DEFAULT@", callback=None, errback=None):
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)
diff --git a/src/bridge/bridge.py b/src/bridge/bridge.py
index bc00b2f1..5330d350 100755
--- a/src/bridge/bridge.py
+++ b/src/bridge/bridge.py
@@ -59,7 +59,7 @@ class Bridge(object):
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 --git a/src/bridge/bridge_constructor/bridge_template.ini b/src/bridge/bridge_constructor/bridge_template.ini
index 1bf2f9eb..5dc934eb 100644
--- a/src/bridge/bridge_constructor/bridge_template.ini
+++ b/src/bridge/bridge_constructor/bridge_template.ini
@@ -447,38 +447,44 @@ doc_param_4=%(doc_profile_key)s
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 @@ sig_out=as
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 --git a/src/core/sat_main.py b/src/core/sat_main.py
index ed15dd92..f5da7d27 100644
--- a/src/core/sat_main.py
+++ b/src/core/sat_main.py
@@ -150,6 +150,7 @@ class SAT(service.Service):
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 --git a/src/memory/memory.py b/src/memory/memory.py
index 87785c19..402efbdb 100644
--- a/src/memory/memory.py
+++ b/src/memory/memory.py
@@ -295,10 +295,40 @@ class Params(object):
#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 @@ class Params(object):
# 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 @@ class Params(object):
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 @@ class Params(object):
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 @@ class Params(object):
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 @@ class Params(object):
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 @@ class Params(object):
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 @@ class Params(object):
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 @@ class Memory(object):
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 @@ class Memory(object):
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)