core (params): jids_list type management

This commit is contained in:
Goffi 2015-08-20 18:35:27 +02:00
commit a39e66b598

View file

@ -27,8 +27,13 @@ from sat.core.log import getLogger
log = getLogger(__name__)
from twisted.internet import defer
from twisted.python.failure import Failure
from twisted.words.protocols.jabber import jid
from sat.tools.xml_tools import paramsXML2XMLUI
# TODO: params should be rewritten using Twisted directly instead of minidom
# general params should be linked to sat.conf and kept synchronised
# this need an overall simplification to make maintenance easier
class Params(object):
"""This class manage parameters with xml"""
@ -77,7 +82,6 @@ class Params(object):
'new_account_label': D_("Register new account"),
'autoconnect_label': D_('Connect on frontend startup'),
'autodisconnect_label': D_('Disconnect on frontend closure'),
'category_misc': D_("Misc"),
}
def load_default_params(self):
@ -113,22 +117,28 @@ class Params(object):
def loadGenParams(self):
"""Load general parameters data from storage
@return: deferred triggered once params are loaded"""
@return: deferred triggered once params are loaded
"""
return self.storage.loadGenParams(self.params_gen)
def loadIndParams(self, profile, cache=None):
"""Load individual parameters
set self.params cache or a temporary cache
@param profile: profile to load (*must exist*)
@param cache: if not None, will be used to store the value, as a short time cache
@return: deferred triggered once params are loaded"""
@return: deferred triggered once params are loaded
"""
if cache is None:
self.params[profile] = {}
return self.storage.loadIndParams(self.params[profile] if cache is None else cache, profile)
def purgeProfile(self, profile):
"""Remove cache data of a profile
@param profile: %(doc_profile)s"""
@param profile: %(doc_profile)s
"""
try:
del self.params[profile]
except KeyError:
@ -149,6 +159,7 @@ class Params(object):
def asyncCreateProfile(self, profile):
"""Create a new profile
@param profile: name of the profile
@param callback: called when the profile actually exists in database and memory
@return: a Deferred instance
@ -210,6 +221,7 @@ class Params(object):
def __get_unique_node(self, parent, tag, name):
"""return node with given tag
@param parent: parent of nodes to check (e.g. documentElement)
@param tag: tag to check (e.g. "category")
@param name: name to check (e.g. "JID")
@ -224,12 +236,14 @@ class Params(object):
def updateParams(self, xml, security_limit=C.NO_SECURITY_LIMIT, app=''):
"""import xml in parameters, update if the param already exists
If security_limit is specified and greater than -1, the parameters
that have a security level greater than security_limit are skipped.
@param xml: parameters in xml form
@param security_limit: -1 means no security, 0 is the maximum security then the higher the less secure
@param app: name of the frontend registering the parameters or empty value
"""
# TODO: should word with domish.Element
src_parent = minidom.parseString(xml.encode('utf-8')).documentElement
def pre_process_app_node(src_parent, security_limit, app):
@ -278,6 +292,7 @@ class Params(object):
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 greater than security_limit are skipped.
@param xml: XML definition of the parameters to be added
@ -305,6 +320,7 @@ class Params(object):
def setDefault(self, name, category, callback, errback=None):
"""Set default value of parameter
'default_cb' attibute of parameter must be set to 'yes'
@param name: name of the parameter
@param category: category of the parameter
@ -341,7 +357,7 @@ class Params(object):
if attr == 'value':
value_to_use = value if value is not None else node.getAttribute(attr) # we use value (user defined) if it exist, else we use node's default value
if node.getAttribute('type') == 'bool':
return value_to_use.lower() not in ('false', '0', 'no')
return C.bool(value_to_use)
if node.getAttribute('type') == 'int':
return int(value_to_use)
elif node.getAttribute('type') == 'list':
@ -360,6 +376,18 @@ class Params(object):
else:
log.error(_(u'Parameter (%(cat)s, %(param)s) of type list has more than one default option!') % {'cat': cat, 'param': param})
raise exceptions.DataError
elif node.getAttribute('type') == 'jids_list':
jids = value.split('\t')
to_delete = []
for idx, value in enumerate(jids):
try:
jids[idx] = jid.JID(value)
except jid.InvalidFormat:
log.warning(u"Incorrect jid value found in jids list: [{}]".format(value))
to_delete.append(value)
for value in to_delete:
jids.remove(value)
return jids
return value_to_use
return node.getAttribute(attr)
@ -367,11 +395,10 @@ class Params(object):
"""Get attribute value (synchronous).
/!\ This method can not be used to retrieve password values.
@param node: XML param node
@param attr: name of the attribute to get (e.g.: 'value' or 'type')
@param value: user defined value
@return: str
@return (unicode, bool, int, list): value to retrieve
"""
if attr == 'value' and node.getAttribute('type') == 'password':
raise exceptions.InternalError('To retrieve password values, use _asyncGetAttr instead of _getAttr')
@ -382,12 +409,11 @@ class Params(object):
Profile passwords are returned hashed (if not empty),
other passwords are returned decrypted (if not empty).
@param node: XML param node
@param attr: name of the attribute to get (e.g.: 'value' or 'type')
@param value: user defined value
@param profile: %(doc_profile)s
@return: a deferred str
@return (unicode, bool, int, list): Deferred value to retrieve
"""
value = self._getAttr_internal(node, attr, value)
if attr != 'value' or node.getAttribute('type') != 'password':
@ -424,13 +450,12 @@ class Params(object):
/!\ This method would return encrypted password values,
to get the plain values you have to use _asyncGetParamA.
@param name: name of the parameter
@param category: category of the parameter
@param attr: name of the attribute (default: "value")
@param profile: owner of the param (@ALL@ for everyone)
@return: attribute
"""
@param name: name of the parameter
@param category: category of the parameter
@param attr: name of the attribute (default: "value")
@param profile: owner of the param (@ALL@ for everyone)
@return: attribute
"""
#FIXME: looks really dirty and buggy, need to be reviewed/refactored
node = self._getParamNode(name, category)
if not node:
@ -466,6 +491,7 @@ class Params(object):
def asyncGetParamA(self, name, category, attr="value", security_limit=C.NO_SECURITY_LIMIT, profile_key=C.PROF_KEY_NONE):
"""Helper method to get a specific attribute.
@param name: name of the parameter
@param category: category of the parameter
@param attr: name of the attribute (default: "value")
@ -504,6 +530,7 @@ class Params(object):
def _getParam(self, category, name, type_=C.INDIVIDUAL, cache=None, profile=C.PROF_KEY_NONE):
"""Return the param, or None if it doesn't exist
@param category: param category
@param name: param name
@param type_: GENERAL or INDIVIDUAL
@ -515,7 +542,7 @@ class Params(object):
if (category, name) in self.params_gen:
return self.params_gen[(category, name)]
return None # This general param has the default value
assert (type_ == C.INDIVIDUAL)
assert type_ == C.INDIVIDUAL
if profile == C.PROF_KEY_NONE:
raise exceptions.ProfileNotSetError
if profile in self.params:
@ -527,8 +554,9 @@ class Params(object):
return None
return cache[(category, name)]
def __constructProfileXml(self, security_limit, app, 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
@param security_limit: NO_SECURITY_LIMIT (-1) to return all the params.
Otherwise sole the params which have a security level defined *and*
@ -601,6 +629,12 @@ class Params(object):
option.removeAttribute('selected')
except NotFoundErr:
pass
elif dest_params[name].getAttribute('type') == 'jids_list':
jids = profile_value.split('\t') # FIXME: it's not good to use tabs as separator !
for jid_ in jids:
jid_elt = prof_xml.createElement('jid')
jid_elt.appendChild(prof_xml.createTextNode(jid_))
dest_params[name].appendChild(jid_elt)
else:
dest_params[name].setAttribute('value', profile_value)
if new_node:
@ -643,6 +677,7 @@ class Params(object):
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.
@ -660,7 +695,7 @@ class Params(object):
prof_xml.unlink()
return '\n'.join((line for line in return_xml.split('\n') if line))
return self.__constructProfileXml(security_limit, app, profile).addCallback(returnXML)
return self._constructProfileXml(security_limit, app, profile).addCallback(returnXML)
def getParamsForCategory(self, category, security_limit, app, profile_key):
"""
@ -688,7 +723,7 @@ class Params(object):
prof_xml.unlink()
return "<category />"
d = self.__constructProfileXml(security_limit, app, profile)
d = self._constructProfileXml(security_limit, app, profile)
return d.addCallback(returnCategoryXml)
def _getParamNode(self, name, category, type_="@ALL@"): # FIXME: is type_ useful ?
@ -783,8 +818,8 @@ class Params(object):
self.host.trigger.point("paramUpdateTrigger", name, value, category, node[0], profile)
return defer.succeed(None)
assert (node[0] == C.INDIVIDUAL)
assert (profile_key != C.PROF_KEY_NONE)
assert node[0] == C.INDIVIDUAL
assert profile_key != C.PROF_KEY_NONE
d_list = []
if type_ == "button":