mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
[enh] Manage extra parameters inside the parser to add 'required' parameter
This commit is contained in:
parent
790eaf0783
commit
203c8fb511
3 changed files with 88 additions and 31 deletions
|
@ -14,6 +14,7 @@
|
||||||
"ldap_operation_error" : "An error occured during LDAP operation",
|
"ldap_operation_error" : "An error occured during LDAP operation",
|
||||||
"ldap_attribute_already_exists" : "Attribute already exists: '{:s}={:s}'",
|
"ldap_attribute_already_exists" : "Attribute already exists: '{:s}={:s}'",
|
||||||
|
|
||||||
|
"argument_required" : "Argument {:s} is required",
|
||||||
"password" : "Password",
|
"password" : "Password",
|
||||||
"invalid_password" : "Invalid password",
|
"invalid_password" : "Invalid password",
|
||||||
"confirm" : "Confirm",
|
"confirm" : "Confirm",
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
"ldap_operation_error" : "Une erreur est survenue lors de l'opération LDAP",
|
"ldap_operation_error" : "Une erreur est survenue lors de l'opération LDAP",
|
||||||
"ldap_attribute_already_exists" : "L'attribut existe déjà : '{:s}={:s}'",
|
"ldap_attribute_already_exists" : "L'attribut existe déjà : '{:s}={:s}'",
|
||||||
|
|
||||||
|
"argument_required" : "L'argument {:s} est requis",
|
||||||
"password" : "Mot de passe",
|
"password" : "Mot de passe",
|
||||||
"invalid_password" : "Mot de passe incorrect",
|
"invalid_password" : "Mot de passe incorrect",
|
||||||
"confirm" : "Confirmez",
|
"confirm" : "Confirmez",
|
||||||
|
|
|
@ -11,6 +11,9 @@ from collections import OrderedDict
|
||||||
from moulinette.core import (MoulinetteError, MoulinetteLock)
|
from moulinette.core import (MoulinetteError, MoulinetteLock)
|
||||||
from moulinette.interfaces import BaseActionsMapParser
|
from moulinette.interfaces import BaseActionsMapParser
|
||||||
|
|
||||||
|
GLOBAL_ARGUMENT = '_global'
|
||||||
|
|
||||||
|
|
||||||
## Extra parameters ----------------------------------------------------
|
## Extra parameters ----------------------------------------------------
|
||||||
|
|
||||||
# Extra parameters definition
|
# Extra parameters definition
|
||||||
|
@ -156,12 +159,34 @@ class PatternParameter(_ExtraParameter):
|
||||||
raise TypeError("Invalid type of 'pattern' extra parameter for '%s' argument" % arg_name)
|
raise TypeError("Invalid type of 'pattern' extra parameter for '%s' argument" % arg_name)
|
||||||
return value
|
return value
|
||||||
|
|
||||||
|
class RequiredParameter(_ExtraParameter):
|
||||||
|
"""
|
||||||
|
Check if a required argument is defined or not.
|
||||||
|
|
||||||
|
The value of this parameter must be a boolean which is set to False by
|
||||||
|
default.
|
||||||
|
"""
|
||||||
|
name = 'required'
|
||||||
|
|
||||||
|
def __call__(self, required, arg_name, arg_value):
|
||||||
|
if required and (arg_value is None or arg_value == ''):
|
||||||
|
raise MoulinetteError(errno.EINVAL, m18n.g('argument_required',
|
||||||
|
arg_name))
|
||||||
|
return arg_value
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def validate(value, arg_name):
|
||||||
|
if not isinstance(value, bool):
|
||||||
|
raise TypeError("Invalid type of 'required' extra parameter for '%s' argument" % arg_name)
|
||||||
|
return value
|
||||||
|
|
||||||
"""
|
"""
|
||||||
The list of available extra parameters classes. It will keep to this list
|
The list of available extra parameters classes. It will keep to this list
|
||||||
order on argument parsing.
|
order on argument parsing.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
extraparameters_list = [AskParameter, PasswordParameter, PatternParameter]
|
extraparameters_list = [ AskParameter, PasswordParameter, RequiredParameter,
|
||||||
|
PatternParameter ]
|
||||||
|
|
||||||
# Extra parameters argument Parser
|
# Extra parameters argument Parser
|
||||||
|
|
||||||
|
@ -176,6 +201,7 @@ class ExtraArgumentParser(object):
|
||||||
def __init__(self, iface):
|
def __init__(self, iface):
|
||||||
self.iface = iface
|
self.iface = iface
|
||||||
self.extra = OrderedDict()
|
self.extra = OrderedDict()
|
||||||
|
self._extra_params = { GLOBAL_ARGUMENT: {} }
|
||||||
|
|
||||||
# Append available extra parameters for the current interface
|
# Append available extra parameters for the current interface
|
||||||
for klass in extraparameters_list:
|
for klass in extraparameters_list:
|
||||||
|
@ -204,34 +230,62 @@ class ExtraArgumentParser(object):
|
||||||
|
|
||||||
return parameters
|
return parameters
|
||||||
|
|
||||||
def parse(self, arg_name, arg_value, parameters):
|
def add_argument(self, tid, arg_name, parameters, validate=True):
|
||||||
"""
|
"""
|
||||||
Parse argument with extra parameters
|
Add extra parameters to apply on an action argument
|
||||||
|
|
||||||
Keyword arguments:
|
Keyword arguments:
|
||||||
|
- tid -- The tuple identifier of the action or GLOBAL_ARGUMENT
|
||||||
|
for global extra parameters
|
||||||
- arg_name -- The argument name
|
- arg_name -- The argument name
|
||||||
- arg_value -- The argument value
|
|
||||||
- parameters -- A dict of extra parameters with their values
|
- parameters -- A dict of extra parameters with their values
|
||||||
|
- validate -- False to not validate extra parameters values
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# Iterate over available parameters
|
if validate:
|
||||||
for p, klass in self.extra.items():
|
parameters = self.validate(arg_name, parameters)
|
||||||
if p not in parameters.keys():
|
try:
|
||||||
|
self._extra_params[tid][arg_name] = parameters
|
||||||
|
except KeyError:
|
||||||
|
self._extra_params[tid] = { arg_name: parameters }
|
||||||
|
|
||||||
|
def parse_args(self, tid, args):
|
||||||
|
"""
|
||||||
|
Parse arguments for an action with extra parameters
|
||||||
|
|
||||||
|
Keyword arguments:
|
||||||
|
- tid -- The tuple identifier of the action
|
||||||
|
- args -- A dict of argument name associated to their value
|
||||||
|
|
||||||
|
"""
|
||||||
|
extra_args = self._extra_params.get(GLOBAL_ARGUMENT, {})
|
||||||
|
extra_args.update(self._extra_params.get(tid, {}))
|
||||||
|
|
||||||
|
# Iterate over action arguments with extra parameters
|
||||||
|
for arg_name, extra_params in extra_args.items():
|
||||||
|
# Iterate over available extra parameters
|
||||||
|
for p, cls in self.extra.items():
|
||||||
|
try:
|
||||||
|
extra_value = extra_params[p]
|
||||||
|
except KeyError:
|
||||||
continue
|
continue
|
||||||
|
arg_value = args.get(arg_name, None)
|
||||||
|
|
||||||
# Initialize the extra parser
|
# Initialize the extra parser
|
||||||
parser = klass(self.iface)
|
parser = cls(self.iface)
|
||||||
|
|
||||||
# Parse the argument
|
# Parse the argument
|
||||||
if isinstance(arg_value, list):
|
if isinstance(arg_value, list):
|
||||||
for v in arg_value:
|
for v in arg_value:
|
||||||
r = parser(parameters[p], arg_name, v)
|
r = parser(extra_value, arg_name, v)
|
||||||
if r not in arg_value:
|
if r not in arg_value:
|
||||||
arg_value.append(r)
|
arg_value.append(r)
|
||||||
else:
|
else:
|
||||||
arg_value = parser(parameters[p], arg_name, arg_value)
|
arg_value = parser(extra_value, arg_name, arg_value)
|
||||||
|
|
||||||
return arg_value
|
# Update argument value
|
||||||
|
args[arg_name] = arg_value
|
||||||
|
return args
|
||||||
|
|
||||||
|
|
||||||
## Main class ----------------------------------------------------------
|
## Main class ----------------------------------------------------------
|
||||||
|
@ -328,11 +382,13 @@ class ActionsMap(object):
|
||||||
"""
|
"""
|
||||||
# Parse arguments
|
# Parse arguments
|
||||||
arguments = vars(self.parser.parse_args(args, **kwargs))
|
arguments = vars(self.parser.parse_args(args, **kwargs))
|
||||||
for an, parameters in (arguments.pop('_extra', {})).items():
|
|
||||||
arguments[an] = self.extraparser.parse(an, arguments[an], parameters)
|
# Retrieve tid and parse arguments with extra parameters
|
||||||
|
tid = arguments.pop('_tid')
|
||||||
|
arguments = self.extraparser.parse_args(tid, arguments)
|
||||||
|
|
||||||
# Retrieve action information
|
# Retrieve action information
|
||||||
namespace, category, action = arguments.pop('_tid')
|
namespace, category, action = tid
|
||||||
func_name = '%s_%s' % (category, action.replace('-', '_'))
|
func_name = '%s_%s' % (category, action.replace('-', '_'))
|
||||||
|
|
||||||
# Lock the moulinette for the namespace
|
# Lock the moulinette for the namespace
|
||||||
|
@ -414,13 +470,12 @@ class ActionsMap(object):
|
||||||
"""
|
"""
|
||||||
## Get extra parameters
|
## Get extra parameters
|
||||||
if not self.use_cache:
|
if not self.use_cache:
|
||||||
_get_extra = lambda an, e: self.extraparser.validate(an, e)
|
validate_extra = True
|
||||||
else:
|
else:
|
||||||
_get_extra = lambda an, e: e
|
validate_extra = False
|
||||||
|
|
||||||
## Add arguments to the parser
|
## Add arguments to the parser
|
||||||
def _add_arguments(parser, arguments):
|
def _add_arguments(tid, parser, arguments):
|
||||||
extras = {}
|
|
||||||
for argn, argp in arguments.items():
|
for argn, argp in arguments.items():
|
||||||
names = top_parser.format_arg_names(argn,
|
names = top_parser.format_arg_names(argn,
|
||||||
argp.pop('full', None))
|
argp.pop('full', None))
|
||||||
|
@ -430,12 +485,11 @@ class ActionsMap(object):
|
||||||
try:
|
try:
|
||||||
extra = argp.pop('extra')
|
extra = argp.pop('extra')
|
||||||
arg_dest = (parser.add_argument(*names, **argp)).dest
|
arg_dest = (parser.add_argument(*names, **argp)).dest
|
||||||
extras[arg_dest] = _get_extra(arg_dest, extra)
|
self.extraparser.add_argument(tid, arg_dest, extra,
|
||||||
|
validate_extra)
|
||||||
except KeyError:
|
except KeyError:
|
||||||
# No extra parameters
|
# No extra parameters
|
||||||
parser.add_argument(*names, **argp)
|
parser.add_argument(*names, **argp)
|
||||||
if extras:
|
|
||||||
parser.set_defaults(_extra=extras)
|
|
||||||
|
|
||||||
# Instantiate parser
|
# Instantiate parser
|
||||||
top_parser = self._parser_class()
|
top_parser = self._parser_class()
|
||||||
|
@ -460,7 +514,8 @@ class ActionsMap(object):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
# Add arguments
|
# Add arguments
|
||||||
_add_arguments(parser, _global['arguments'])
|
_add_arguments(GLOBAL_ARGUMENT, parser,
|
||||||
|
_global['arguments'])
|
||||||
|
|
||||||
# -- Parse categories
|
# -- Parse categories
|
||||||
for cn, cp in actionsmap.items():
|
for cn, cp in actionsmap.items():
|
||||||
|
@ -497,7 +552,7 @@ class ActionsMap(object):
|
||||||
else:
|
else:
|
||||||
# Store action identifier and add arguments
|
# Store action identifier and add arguments
|
||||||
parser.set_defaults(_tid=tid)
|
parser.set_defaults(_tid=tid)
|
||||||
_add_arguments(parser, args)
|
_add_arguments(tid, parser, args)
|
||||||
_set_conf(cat_parser)
|
_set_conf(cat_parser)
|
||||||
|
|
||||||
return top_parser
|
return top_parser
|
||||||
|
|
Loading…
Add table
Reference in a new issue