From 57b2243adaaf4216d194752ddaab47b790e9bfd7 Mon Sep 17 00:00:00 2001 From: Christophe Benz Date: Sat, 15 May 2010 04:55:30 +0200 Subject: [PATCH] implement where condition --- weboob/tools/application/console.py | 21 ++++++--- .../tools/application/formatters/__init__.py | 8 ++++ weboob/tools/application/formatters/simple.py | 18 ++++++-- weboob/tools/application/results.py | 46 ++++++++++++++++++- 4 files changed, 82 insertions(+), 11 deletions(-) diff --git a/weboob/tools/application/console.py b/weboob/tools/application/console.py index 18c42419..2ef94773 100644 --- a/weboob/tools/application/console.py +++ b/weboob/tools/application/console.py @@ -28,17 +28,13 @@ import weboob from weboob.modules import BackendsConfig from .base import BaseApplication -from .formatters import SimpleFormatter -from .results import Results +from .formatters import formatters_classes, SimpleFormatter +from .results import Results, WhereCondition, WhereConditionException __all__ = ['ConsoleApplication'] -formatters_classes = dict( - simple=SimpleFormatter, -) - class ConsoleApplication(BaseApplication): SYNOPSIS = 'Usage: %prog [options (-h for help)] command [parameters...]' @@ -61,6 +57,7 @@ class ConsoleApplication(BaseApplication): self._parser.add_option('-f', '--formatter', default='simple', choices=formatters_classes.keys(), help='select output formatter (%s)' % u','.join(formatters_classes.keys())) self._parser.add_option('-s', '--select', help='select result item key(s) to display (comma-separated)') + self._parser.add_option('-w', '--where', help='filter results to display with boolean condition') def _handle_app_options(self): self._formatter = formatters_classes[self.options.formatter] @@ -70,6 +67,11 @@ class ConsoleApplication(BaseApplication): else: self.selected_fields = None + if self.options.where: + self.where_condition = WhereCondition(self.options.where) + else: + self.where_condition = None + def _get_completions(self): return set(name for name, arguments, doc_string in self._commands) @@ -197,7 +199,12 @@ class ConsoleApplication(BaseApplication): return partial(f, doc_string=doc_string) def format(self, result): - return self._formatter.format(result, selected_fields=self.selected_fields) + try: + result = self._formatter.format(result, selected_fields=self.selected_fields, where_condition=self.where_condition) + if result is not None: + print result + except WhereConditionException, e: + logging.error(e) register_command = staticmethod(register_command) command = staticmethod(command) diff --git a/weboob/tools/application/formatters/__init__.py b/weboob/tools/application/formatters/__init__.py index 0007ceea..abcc67c9 100644 --- a/weboob/tools/application/formatters/__init__.py +++ b/weboob/tools/application/formatters/__init__.py @@ -16,3 +16,11 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. from .simple import SimpleFormatter + + +__all__ = ['formatters_classes'] + + +formatters_classes = dict( + simple=SimpleFormatter, +) diff --git a/weboob/tools/application/formatters/simple.py b/weboob/tools/application/formatters/simple.py index dd4ca485..f96a0dc4 100644 --- a/weboob/tools/application/formatters/simple.py +++ b/weboob/tools/application/formatters/simple.py @@ -16,12 +16,15 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +from ..results import WhereCondition, WhereConditionException + + __all__ = ['SimpleFormatter'] class SimpleFormatter(object): @classmethod - def format(cls, obj, selected_fields=None): + def format(cls, obj, selected_fields=None, where_condition=None): def iter_fields(obj): import types for attribute_name in dir(obj): @@ -38,7 +41,16 @@ class SimpleFormatter(object): d = dict((k, v) for k, v in fields_iterator) + if where_condition is not None: + if not where_condition.is_valid(d): + d = None + + if not d: + return None + if selected_fields is None: - return u'\n'.join(u'%s: %s' % (k, unicode(d[k])) for k in sorted(d)) + u'\n' + result = u'\n'.join(u'%s: %s' % (k, unicode(d[k])) for k in sorted(d)) + u'\n' else: - return u'\t'.join(unicode(d[k]) for k in selected_fields if d[k] is not None) + result = u'\t'.join(unicode(d[k]) for k in selected_fields if d[k] is not None) + + return result diff --git a/weboob/tools/application/results.py b/weboob/tools/application/results.py index 95afc228..367bfe2d 100644 --- a/weboob/tools/application/results.py +++ b/weboob/tools/application/results.py @@ -16,7 +16,7 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -__all__ = ['Results'] +__all__ = ['Results', 'WhereCondition', 'WhereConditionException'] class Results(object): @@ -65,3 +65,47 @@ class Results(object): def iter_groups(self): return iter(self._groups) + + +class WhereCondition(object): + def __init__(self, where_condition_str): + where_condition_str.replace('OR', 'or') + where_condition_str.replace('AND', 'and') + where_condition_str.replace('NOT', 'not') + or_list = [] + for _or in where_condition_str.split('or'): + and_dict = {} + for _and in _or.split('and'): + if '!=' in _and: + k, v = _and.split('!=') + k += '!' + elif '=' in _and: + k, v = _and.split('=') + else: + raise WhereConditionException(u'Could not find = or != operator in sub-expression "%s"' % _and) + and_dict[k] = v + or_list.append(and_dict) + self.where_condition = or_list + + def is_valid(self, d): + for _or in self.where_condition: + for k, v in _or.iteritems(): + if k.endswith('!'): + k = k[:-1] + different = True + else: + different = False + if k in d: + if different: + if d[k] == v: + return False + else: + if d[k] != v: + return False + else: + raise WhereConditionException(u'Field "%s" is not valid.' % k) + return True + + +class WhereConditionException(Exception): + pass