139 lines
4.8 KiB
Python
139 lines
4.8 KiB
Python
"""
|
||
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()
|