From 332a5c2553db41de777473a1e1be9cd1522c9496 Mon Sep 17 00:00:00 2001 From: Emmanuel Gil Peyrot Date: Thu, 31 Mar 2016 18:54:41 +0100 Subject: Move the src directory to poezio, for better cython compatibility. --- poezio/decorators.py | 139 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 139 insertions(+) create mode 100644 poezio/decorators.py (limited to 'poezio/decorators.py') diff --git a/poezio/decorators.py b/poezio/decorators.py new file mode 100644 index 00000000..c4ea6563 --- /dev/null +++ b/poezio/decorators.py @@ -0,0 +1,139 @@ +""" +Module containing various decorators +""" + +import common + +class RefreshWrapper(object): + def __init__(self): + self.core = None + + def conditional(self, func): + """ + Decorator to refresh the UI if the wrapped function + returns True + """ + def wrap(*args, **kwargs): + ret = func(*args, **kwargs) + if self.core and ret: + self.core.refresh_window() + return ret + return wrap + + def always(self, func): + """ + Decorator that refreshs the UI no matter what after the function + """ + def wrap(*args, **kwargs): + ret = func(*args, **kwargs) + if self.core: + self.core.refresh_window() + return ret + return wrap + + def update(self, func): + """ + Decorator that only updates the screen + """ + def wrap(*args, **kwargs): + ret = func(*args, **kwargs) + if self.core: + self.core.doupdate() + return ret + return wrap + +refresh_wrapper = RefreshWrapper() + +class CommandArgParser(object): + """Modify the string argument of the function into a list of strings + containing the right number of extracted arguments, or None if we don’t + have enough. + """ + @staticmethod + def raw(func): + """Just call the function with a single string, which is the original string + untouched + """ + def wrap(self, args, *a, **kw): + return func(self, args, *a, **kw) + return wrap + + @staticmethod + def ignored(func): + """ + Call the function without any argument + """ + def wrap(self, args, *a, **kw): + return func(self, *a, **kw) + return wrap + + @staticmethod + def quoted(mandatory, optional=0, defaults=[], + ignore_trailing_arguments=False): + + """The function receives a list with a number of arguments that is between + the numbers `mandatory` and `optional`. + + If the string doesn’t contain at least `mandatory` arguments, we return + None because the given arguments are invalid. + + If there are any remaining arguments after `mandatory` and `optional` + arguments have been found (and “ignore_trailing_arguments" is not True), + we happen them to the last argument of the list. + + An argument is a string (with or without whitespaces) between to quotes + ("), or a whitespace separated word (if not inside quotes). + + The argument `defaults` is a list of strings that are used when an + optional argument is missing. For example if we accept one optional + argument, zero is available but we have one value in the `defaults` + list, we use that string inplace. The `defaults` list can only + replace missing optional arguments, not mandatory ones. And it + should not contain more than `mandatory` values. Also you cannot + + Example: + This method needs at least one argument, and accepts up to 3 + arguments + + >> @command_args_parser.quoted(1, 2, ['default for first arg'], False) + >> def f(args): + >> print(args) + + >> f('coucou les amis') # We have one mandatory and two optional + ['coucou', 'les', 'amis'] + >> f('"coucou les amis" "PROUT PROUT"') # One mandator and only one optional, + # no default for the second + ['coucou les amis', 'PROUT PROUT'] + >> f('') # Not enough args for mandatory number + None + >> f('"coucou les potes"') # One mandatory, and use the default value + # for the first optional + ['coucou les potes, 'default for first arg'] + >> f('"un et demi" deux trois quatre cinq six') # We have three trailing arguments + ['un et demi', 'deux', 'trois quatre cinq six'] + + """ + def first(func): + def second(self, args, *a, **kw): + default_args = defaults + args = common.shell_split(args) + if len(args) < mandatory: + return func(self, None, *a, **kw) + res, args = args[:mandatory], args[mandatory:] + if optional == -1: + opt_args = args[:] + else: + opt_args = args[:optional] + + if opt_args: + res += opt_args + args = args[len(opt_args):] + default_args = default_args[len(opt_args):] + res += default_args + if args and res and not ignore_trailing_arguments: + res[-1] += " " + " ".join(args) + return func(self, res, *a, **kw) + return second + return first + +command_args_parser = CommandArgParser() -- cgit v1.2.3