mirror of
https://github.com/YunoHost/moulinette.git
synced 2024-09-03 20:06:31 +02:00
Remove the 'global argument' mechanism ... we only use it for --version and it's just batshit overly complicated for what this achieves...
This commit is contained in:
parent
5258f22985
commit
50b19a95c6
4 changed files with 2 additions and 142 deletions
|
@ -18,7 +18,7 @@ from moulinette.core import (
|
||||||
MoulinetteLock,
|
MoulinetteLock,
|
||||||
MoulinetteValidationError,
|
MoulinetteValidationError,
|
||||||
)
|
)
|
||||||
from moulinette.interfaces import BaseActionsMapParser, TO_RETURN_PROP
|
from moulinette.interfaces import BaseActionsMapParser
|
||||||
from moulinette.utils.log import start_action_logging
|
from moulinette.utils.log import start_action_logging
|
||||||
from moulinette.utils.filesystem import read_yaml
|
from moulinette.utils.filesystem import read_yaml
|
||||||
|
|
||||||
|
@ -515,10 +515,6 @@ class ActionsMap:
|
||||||
tid = arguments.pop("_tid")
|
tid = arguments.pop("_tid")
|
||||||
arguments = self.extraparser.parse_args(tid, arguments)
|
arguments = self.extraparser.parse_args(tid, arguments)
|
||||||
|
|
||||||
# Return immediately if a value is defined
|
|
||||||
if TO_RETURN_PROP in arguments:
|
|
||||||
return arguments.get(TO_RETURN_PROP)
|
|
||||||
|
|
||||||
# Retrieve action information
|
# Retrieve action information
|
||||||
if len(tid) == 4:
|
if len(tid) == 4:
|
||||||
namespace, category, subcategory, action = tid
|
namespace, category, subcategory, action = tid
|
||||||
|
@ -626,9 +622,6 @@ class ActionsMap:
|
||||||
self.enable_lock = _global.get("lock", True)
|
self.enable_lock = _global.get("lock", True)
|
||||||
self.default_authentication = _global["authentication"][interface_type]
|
self.default_authentication = _global["authentication"][interface_type]
|
||||||
|
|
||||||
if top_parser.has_global_parser():
|
|
||||||
top_parser.add_global_arguments(_global["arguments"])
|
|
||||||
|
|
||||||
# category_name is stuff like "user", "domain", "hooks"...
|
# category_name is stuff like "user", "domain", "hooks"...
|
||||||
# category_values is the values of this category (like actions)
|
# category_values is the values of this category (like actions)
|
||||||
for category_name, category_values in actionsmap.items():
|
for category_name, category_values in actionsmap.items():
|
||||||
|
|
|
@ -14,10 +14,6 @@ from moulinette.core import MoulinetteError
|
||||||
|
|
||||||
logger = logging.getLogger("moulinette.interface")
|
logger = logging.getLogger("moulinette.interface")
|
||||||
|
|
||||||
# FIXME : are these even used for anything useful ...
|
|
||||||
TO_RETURN_PROP = "_to_return"
|
|
||||||
CALLBACKS_PROP = "_callbacks"
|
|
||||||
|
|
||||||
|
|
||||||
# Base Class -----------------------------------------------------------
|
# Base Class -----------------------------------------------------------
|
||||||
|
|
||||||
|
@ -148,95 +144,10 @@ class BaseActionsMapParser:
|
||||||
"derived class '%s' must override this method" % self.__class__.__name__
|
"derived class '%s' must override this method" % self.__class__.__name__
|
||||||
)
|
)
|
||||||
|
|
||||||
# Arguments helpers
|
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def prepare_action_namespace(tid, namespace=None):
|
|
||||||
"""Prepare the namespace for a given action"""
|
|
||||||
# Validate tid and namespace
|
|
||||||
if not isinstance(tid, tuple) and (
|
|
||||||
namespace is None or not hasattr(namespace, TO_RETURN_PROP)
|
|
||||||
):
|
|
||||||
raise MoulinetteError("invalid_usage")
|
|
||||||
elif not tid:
|
|
||||||
tid = "_global"
|
|
||||||
|
|
||||||
# Prepare namespace
|
|
||||||
if namespace is None:
|
|
||||||
namespace = argparse.Namespace()
|
|
||||||
namespace._tid = tid
|
|
||||||
|
|
||||||
return namespace
|
|
||||||
|
|
||||||
|
|
||||||
# Argument parser ------------------------------------------------------
|
# Argument parser ------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
class _CallbackAction(argparse.Action):
|
|
||||||
def __init__(
|
|
||||||
self,
|
|
||||||
option_strings,
|
|
||||||
dest,
|
|
||||||
nargs=0,
|
|
||||||
callback={},
|
|
||||||
default=argparse.SUPPRESS,
|
|
||||||
help=None,
|
|
||||||
):
|
|
||||||
if not callback or "method" not in callback:
|
|
||||||
raise ValueError("callback must be provided with at least " "a method key")
|
|
||||||
super(_CallbackAction, self).__init__(
|
|
||||||
option_strings=option_strings,
|
|
||||||
dest=dest,
|
|
||||||
nargs=nargs,
|
|
||||||
default=default,
|
|
||||||
help=help,
|
|
||||||
)
|
|
||||||
self.callback_method = callback.get("method")
|
|
||||||
self.callback_kwargs = callback.get("kwargs", {})
|
|
||||||
self.callback_return = callback.get("return", False)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def callback(self):
|
|
||||||
if not hasattr(self, "_callback"):
|
|
||||||
self._retrieve_callback()
|
|
||||||
return self._callback
|
|
||||||
|
|
||||||
def _retrieve_callback(self):
|
|
||||||
# Attempt to retrieve callback method
|
|
||||||
mod_name, func_name = (self.callback_method).rsplit(".", 1)
|
|
||||||
try:
|
|
||||||
mod = __import__(mod_name, globals=globals(), level=0, fromlist=[func_name])
|
|
||||||
func = getattr(mod, func_name)
|
|
||||||
except (AttributeError, ImportError):
|
|
||||||
import traceback
|
|
||||||
|
|
||||||
traceback.print_exc()
|
|
||||||
raise ValueError("unable to import method {}".format(self.callback_method))
|
|
||||||
self._callback = func
|
|
||||||
|
|
||||||
def __call__(self, parser, namespace, values, option_string=None):
|
|
||||||
parser.enqueue_callback(namespace, self, values)
|
|
||||||
if self.callback_return:
|
|
||||||
setattr(namespace, TO_RETURN_PROP, {})
|
|
||||||
|
|
||||||
def execute(self, namespace, values):
|
|
||||||
try:
|
|
||||||
# Execute callback and get returned value
|
|
||||||
value = self.callback(namespace, values, **self.callback_kwargs)
|
|
||||||
except Exception as e:
|
|
||||||
error_message = "cannot get value from callback method " "'{}': {}".format(
|
|
||||||
self.callback_method, e
|
|
||||||
)
|
|
||||||
logger.exception(error_message)
|
|
||||||
raise MoulinetteError(error_message, raw_msg=True)
|
|
||||||
else:
|
|
||||||
if value:
|
|
||||||
if self.callback_return:
|
|
||||||
setattr(namespace, TO_RETURN_PROP, value)
|
|
||||||
else:
|
|
||||||
setattr(namespace, self.dest, value)
|
|
||||||
|
|
||||||
|
|
||||||
class _ExtendedSubParsersAction(argparse._SubParsersAction):
|
class _ExtendedSubParsersAction(argparse._SubParsersAction):
|
||||||
|
|
||||||
"""Subparsers with extended properties for argparse
|
"""Subparsers with extended properties for argparse
|
||||||
|
@ -319,35 +230,8 @@ class ExtendedArgumentParser(argparse.ArgumentParser):
|
||||||
)
|
)
|
||||||
|
|
||||||
# Register additional actions
|
# Register additional actions
|
||||||
self.register("action", "callback", _CallbackAction)
|
|
||||||
self.register("action", "parsers", _ExtendedSubParsersAction)
|
self.register("action", "parsers", _ExtendedSubParsersAction)
|
||||||
|
|
||||||
def enqueue_callback(self, namespace, callback, values):
|
|
||||||
queue = self._get_callbacks_queue(namespace)
|
|
||||||
queue.append((callback, values))
|
|
||||||
|
|
||||||
def dequeue_callbacks(self, namespace):
|
|
||||||
queue = self._get_callbacks_queue(namespace, False)
|
|
||||||
for _i in range(len(queue)):
|
|
||||||
c, v = queue.popleft()
|
|
||||||
# FIXME: break dequeue if callback returns
|
|
||||||
c.execute(namespace, v)
|
|
||||||
try:
|
|
||||||
delattr(namespace, CALLBACKS_PROP)
|
|
||||||
except AttributeError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _get_callbacks_queue(self, namespace, create=True):
|
|
||||||
try:
|
|
||||||
queue = getattr(namespace, CALLBACKS_PROP)
|
|
||||||
except AttributeError:
|
|
||||||
if create:
|
|
||||||
queue = deque()
|
|
||||||
setattr(namespace, CALLBACKS_PROP, queue)
|
|
||||||
else:
|
|
||||||
queue = list()
|
|
||||||
return queue
|
|
||||||
|
|
||||||
def add_arguments(
|
def add_arguments(
|
||||||
self, arguments, extraparser, format_arg_names=None, validate_extra=True
|
self, arguments, extraparser, format_arg_names=None, validate_extra=True
|
||||||
):
|
):
|
||||||
|
|
|
@ -235,9 +235,6 @@ class _HTTPArgumentParser:
|
||||||
|
|
||||||
return self._parser.parse_args(arg_strings, namespace)
|
return self._parser.parse_args(arg_strings, namespace)
|
||||||
|
|
||||||
def dequeue_callbacks(self, *args, **kwargs):
|
|
||||||
return self._parser.dequeue_callbacks(*args, **kwargs)
|
|
||||||
|
|
||||||
def _error(self, message):
|
def _error(self, message):
|
||||||
raise MoulinetteValidationError(message, raw_msg=True)
|
raise MoulinetteValidationError(message, raw_msg=True)
|
||||||
|
|
||||||
|
@ -671,7 +668,6 @@ class ActionsMapParser(BaseActionsMapParser):
|
||||||
|
|
||||||
# TODO: Catch errors?
|
# TODO: Catch errors?
|
||||||
ret = parser.parse_args(args, ret)
|
ret = parser.parse_args(args, ret)
|
||||||
parser.dequeue_callbacks(ret)
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
# Private methods
|
# Private methods
|
||||||
|
|
|
@ -388,15 +388,6 @@ class ActionsMapParser(BaseActionsMapParser):
|
||||||
hide_in_help=hide_in_help,
|
hide_in_help=hide_in_help,
|
||||||
)
|
)
|
||||||
|
|
||||||
def add_global_arguments(self, arguments):
|
|
||||||
for argument_name, argument_options in arguments.items():
|
|
||||||
# will adapt arguments name for cli or api context
|
|
||||||
names = self.format_arg_names(
|
|
||||||
str(argument_name), argument_options.pop("full", None)
|
|
||||||
)
|
|
||||||
|
|
||||||
self.global_parser.add_argument(*names, **argument_options)
|
|
||||||
|
|
||||||
def auth_method(self, args):
|
def auth_method(self, args):
|
||||||
# FIXME? idk .. this try/except is duplicated from parse_args below
|
# FIXME? idk .. this try/except is duplicated from parse_args below
|
||||||
# Just to be able to obtain the tid
|
# Just to be able to obtain the tid
|
||||||
|
@ -433,7 +424,7 @@ class ActionsMapParser(BaseActionsMapParser):
|
||||||
|
|
||||||
def parse_args(self, args, **kwargs):
|
def parse_args(self, args, **kwargs):
|
||||||
try:
|
try:
|
||||||
ret = self._parser.parse_args(args)
|
return self._parser.parse_args(args)
|
||||||
except SystemExit:
|
except SystemExit:
|
||||||
raise
|
raise
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -443,10 +434,6 @@ class ActionsMapParser(BaseActionsMapParser):
|
||||||
)
|
)
|
||||||
logger.exception(error_message)
|
logger.exception(error_message)
|
||||||
raise MoulinetteValidationError(error_message, raw_msg=True)
|
raise MoulinetteValidationError(error_message, raw_msg=True)
|
||||||
else:
|
|
||||||
self.prepare_action_namespace(getattr(ret, "_tid", None), ret)
|
|
||||||
self._parser.dequeue_callbacks(ret)
|
|
||||||
return ret
|
|
||||||
|
|
||||||
|
|
||||||
class Interface:
|
class Interface:
|
||||||
|
|
Loading…
Add table
Reference in a new issue