enhance select command, add condition command

This commit is contained in:
Christophe Benz 2010-09-23 01:03:02 +02:00 committed by Romain Bignon
commit 13a1f2a8a5
2 changed files with 67 additions and 25 deletions

View file

@ -90,7 +90,7 @@ class ReplApplication(cmd.Cmd, BaseApplication):
self._parser.description += help_str self._parser.description += help_str
results_options = OptionGroup(self._parser, 'Results Options') results_options = OptionGroup(self._parser, 'Results Options')
results_options.add_option('-c', '--condition', help='filter result items to display given a boolean condition') results_options.add_option('-c', '--condition', help='filter result items to display given a boolean expression')
results_options.add_option('-n', '--count', default='10', type='int', results_options.add_option('-n', '--count', default='10', type='int',
help='get a maximum number of results (all backends merged)') help='get a maximum number of results (all backends merged)')
results_options.add_option('-s', '--select', help='select result item keys to display (comma separated)') results_options.add_option('-s', '--select', help='select result item keys to display (comma separated)')
@ -161,9 +161,9 @@ class ReplApplication(cmd.Cmd, BaseApplication):
if kwargs.pop('backends', None) is None: if kwargs.pop('backends', None) is None:
kwargs['backends'] = self.enabled_backends kwargs['backends'] = self.enabled_backends
fields = self.selected_fields fields = self.selected_fields
if fields == ['direct']: if fields == '$direct':
fields = None fields = None
elif fields == ['full']: elif fields == '$full':
fields = [k for k, v in iter_fields(obj)] fields = [k for k, v in iter_fields(obj)]
try: try:
for values in self.weboob.do(self._complete, self.options.count, fields, function, *args, **kwargs): for values in self.weboob.do(self._complete, self.options.count, fields, function, *args, **kwargs):
@ -192,7 +192,7 @@ class ReplApplication(cmd.Cmd, BaseApplication):
if self.options.select: if self.options.select:
self.selected_fields = self.options.select.split(',') self.selected_fields = self.options.select.split(',')
else: else:
self.selected_fields = ['direct'] self.selected_fields = '$direct'
if self.options.condition: if self.options.condition:
self.condition = ResultsCondition(self.options.condition) self.condition = ResultsCondition(self.options.condition)
@ -373,14 +373,37 @@ class ReplApplication(cmd.Cmd, BaseApplication):
if choices is not None: if choices is not None:
return ['%s ' % choice for choice in choices if choice.startswith(text)] if text else choices return ['%s ' % choice for choice in choices if choice.startswith(text)] if text else choices
def do_condition(self, line):
"""
condition [EXPRESSION] | off
If an argument is given, set the condition expression used to filter the results.
If the "off" value is given, conditional filtering is disabled.
If no argument is given, print the current condition expression.
"""
if line:
if line == 'off':
self.condition = None
else:
try:
self.condition = ResultsCondition(line)
except ResultsConditionException, e:
print e
else:
if self.condition is None:
print 'No condition is set.'
else:
print str(self.condition)
def do_count(self, line): def do_count(self, line):
""" """
count [NUMBER] count [NUMBER]
If an argument is given, set the maximum number of results fetched. If an argument is given, set the maximum number of results fetched.
Otherwise, display the current setting.
Count must be at least 1, or negative for infinite. Count must be at least 1, or negative for infinite.
If no argument is given, print the current count value.
""" """
if line: if line:
try: try:
@ -396,10 +419,23 @@ class ReplApplication(cmd.Cmd, BaseApplication):
def do_select(self, line): def do_select(self, line):
""" """
select [FIELD_NAME]... | "direct" | "full" select [FIELD_NAME]... | "$direct" | "$full"
If an argument is given, set the selected fields.
$direct selects all fields loaded in one http request.
$full selects all fields using as much http requests as necessary.
If no argument is given, print the currently selected fields.
""" """
if line: if line:
self.selected_fields = line.split() split = line.split()
if len(split) == 1 and split[0] in ('$direct', '$full'):
self.selected_fields = split[0]
else:
self.selected_fields = split
else:
if isinstance(self.selected_fields, basestring):
print self.selected_fields
else: else:
print ' '.join(self.selected_fields) print ' '.join(self.selected_fields)
@ -467,7 +503,7 @@ class ReplApplication(cmd.Cmd, BaseApplication):
def format(self, result): def format(self, result):
fields = self.selected_fields fields = self.selected_fields
if fields == ['direct'] or fields == ['full']: if fields in ('$direct', '$full'):
fields = None fields = None
try: try:
self.formatter.format(obj=result, selected_fields=fields, condition=self.condition) self.formatter.format(obj=result, selected_fields=fields, condition=self.condition)

View file

@ -68,12 +68,13 @@ class Results(object):
class ResultsCondition(object): class ResultsCondition(object):
condition_str = None
def __init__(self, condition_str): def __init__(self, condition_str):
condition_str = condition_str.replace('OR', 'or') \ condition_str = condition_str.replace('OR', 'or') \
.replace('AND', 'and') \ .replace('AND', 'and') \
.replace('NOT', 'not') .replace('NOT', 'not')
or_list = [] or_list = []
try:
for _or in condition_str.split('or'): for _or in condition_str.split('or'):
and_dict = {} and_dict = {}
for _and in _or.split('and'): for _and in _or.split('and'):
@ -84,11 +85,10 @@ class ResultsCondition(object):
k, v = _and.split('=') k, v = _and.split('=')
else: else:
raise ResultsConditionException(u'Could not find = or != operator in sub-expression "%s"' % _and) raise ResultsConditionException(u'Could not find = or != operator in sub-expression "%s"' % _and)
and_dict[k] = v and_dict[k.strip()] = v.strip()
or_list.append(and_dict) or_list.append(and_dict)
except:
raise ResultsConditionException(u'Could not parse condition expression "%s"' % condition_str)
self.condition = or_list self.condition = or_list
self.condition_str = condition_str
def is_valid(self, d): def is_valid(self, d):
for _or in self.condition: for _or in self.condition:
@ -109,6 +109,12 @@ class ResultsCondition(object):
raise ResultsConditionException(u'Field "%s" is not valid.' % k) raise ResultsConditionException(u'Field "%s" is not valid.' % k)
return True return True
def __str__(self):
return unicode(self).encode('utf-8')
def __unicode__(self):
return self.condition_str
class ResultsConditionException(Exception): class ResultsConditionException(Exception):
pass pass