diff --git a/weboob/tools/application/console.py b/weboob/tools/application/console.py index c0c3f56d..badc314d 100644 --- a/weboob/tools/application/console.py +++ b/weboob/tools/application/console.py @@ -154,22 +154,20 @@ class ConsoleApplication(BaseApplication): logging.error(errors) return 1 - # Process result - if isinstance(command_result, Results): - self.format(command_result) - return 0 - elif isinstance(command_result, (str, unicode)): + self._formatter.flush() + + # Process result if value is returned by command + if isinstance(command_result, (str, unicode)): print command_result - return 0 elif isinstance(command_result, int): return command_result - elif command_result is None: - return 0 else: try: print unicode(command_result) except ValueError: - raise Exception('command_result type not expected: %s' % type(command_result)) + raise Exception(u'Command result type not expected: %s' % type(command_result)) + + return 0 _commands = [] def register_command(f, doc_string, register_to=_commands): @@ -200,9 +198,7 @@ class ConsoleApplication(BaseApplication): def format(self, result): try: - result = self._formatter.format(result, selected_fields=self.selected_fields, condition=self.condition) - if result is not None: - print result + self._formatter.format(result, selected_fields=self.selected_fields, condition=self.condition) except ResultsConditionException, e: logging.error(e) diff --git a/weboob/tools/application/formatters/__init__.py b/weboob/tools/application/formatters/__init__.py index 572e43ac..b7aa8e10 100644 --- a/weboob/tools/application/formatters/__init__.py +++ b/weboob/tools/application/formatters/__init__.py @@ -17,6 +17,7 @@ from .multiline import MultilineFormatter from .simple import SimpleFormatter +from .table import TableFormatter __all__ = ['formatters'] @@ -25,4 +26,6 @@ __all__ = ['formatters'] formatters = dict( multiline=MultilineFormatter(), simple=SimpleFormatter(), + table=TableFormatter(), + htmltable=TableFormatter(result_funcname='get_html_string'), ) diff --git a/weboob/tools/application/formatters/iformatter.py b/weboob/tools/application/formatters/iformatter.py index 52a1d11d..76b1fd6c 100644 --- a/weboob/tools/application/formatters/iformatter.py +++ b/weboob/tools/application/formatters/iformatter.py @@ -23,7 +23,16 @@ __all__ = ['IFormatter'] class IFormatter(object): - def format(self, obj, selected_fields=None, condition=None): + def __init__(self, display_keys=True): + self.display_keys = display_keys + + def after_format(self, formatted): + raise NotImplementedError() + + def flush(self): + raise NotImplementedError() + + def format(self, obj, selected_fields=None, condition=None, return_only=False): """ Format an object to be human-readable. An object has fields which can be selected, and the objects @@ -32,23 +41,25 @@ class IFormatter(object): call it. It can be used to specify the fields order. @param obj [object] object to format - @param selected_fields [list] fields to display + @param selected_fields [list] fields to display. If None, all fields are selected. @param condition [Condition] condition to objects to display @return a string of the formatted object """ item = self.to_dict(obj, condition) - if selected_fields is None: - selected_fields = sorted(item) - return self.format_dict(item=item, selected_fields=selected_fields) + if selected_fields is not None: + item = dict((k, v) for k, v in item.iteritems() if k in selected_fields) + formatted = self.format_dict(item=item) + if not return_only and formatted: + self.after_format(formatted) + return formatted - def format_dict(self, item, selected_fields): + def format_dict(self, item): """ - Format an dict to be human-readable. + Format an dict to be human-readable. The dict is already simplified if user provides selected fields. Called by format(). This method has to be overridden in child classes. @param item [dict] item to format - @param selected_fields [list] fields to display @return a string of the formatted dict """ raise NotImplementedError() diff --git a/weboob/tools/application/formatters/multiline.py b/weboob/tools/application/formatters/multiline.py index ec86232c..9d069414 100644 --- a/weboob/tools/application/formatters/multiline.py +++ b/weboob/tools/application/formatters/multiline.py @@ -23,12 +23,15 @@ __all__ = ['MultilineFormatter'] class MultilineFormatter(IFormatter): - def __init__(self, key_value_separator=u': ', after_item=u'\n', display_keys=True): + def __init__(self, key_value_separator=u': ', after_item=u'\n'): self.key_value_separator = key_value_separator self.after_item = after_item - self.display_keys = display_keys - def format_dict(self, item, selected_fields): - result_str = u'\n'.join(u'%s%s' % ((u'%s%s' % (k, self.key_value_separator) if self.display_keys else ''), - unicode(item[k])) for k in selected_fields) + self.after_item - return result_str + def after_format(self, formatted): + print formatted.encode('utf-8') + + def flush(self): + pass + + def format_dict(self, item): + return u'\n'.join(u'%s%s' % ((u'%s%s' % (k, self.key_value_separator) if self.display_keys else ''), v) for k, v in item.iteritems()) + self.after_item diff --git a/weboob/tools/application/formatters/simple.py b/weboob/tools/application/formatters/simple.py index 8a033b13..69c27562 100644 --- a/weboob/tools/application/formatters/simple.py +++ b/weboob/tools/application/formatters/simple.py @@ -23,12 +23,16 @@ __all__ = ['SimpleFormatter'] class SimpleFormatter(IFormatter): - def __init__(self, field_separator=u'\t', key_value_separator=u'=', display_keys=True): + def __init__(self, field_separator=u'\t', key_value_separator=u'='): + IFormatter.__init__(self) self.field_separator = field_separator self.key_value_separator = key_value_separator - self.display_keys = display_keys - def format_dict(self, item, selected_fields): - result_str = self.field_separator.join(u'%s%s' % ((u'%s%s' % ( - k, self.key_value_separator) if self.display_keys else ''), unicode(item[k])) for k in selected_fields) - return result_str + def after_format(self, formatted): + print formatted.encode('utf-8') + + def flush(self): + pass + + def format_dict(self, item): + return self.field_separator.join(u'%s%s' % ((u'%s%s' % (k, self.key_value_separator) if self.display_keys else ''), v) for k, v in item.iteritems()) diff --git a/weboob/tools/application/formatters/table.py b/weboob/tools/application/formatters/table.py new file mode 100644 index 00000000..6e6f1143 --- /dev/null +++ b/weboob/tools/application/formatters/table.py @@ -0,0 +1,49 @@ +# -*- coding: utf-8 -*- + +# Copyright(C) 2010 Christophe Benz +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, version 3 of the License. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +from prettytable import PrettyTable + +from .iformatter import IFormatter + + +__all__ = ['TableFormatter'] + + +class TableFormatter(IFormatter): + column_headers = None + queue = [] + + def __init__(self, result_funcname='get_string'): + self.result_funcname = result_funcname + + def after_format(self, formatted): + if self.column_headers is None: + self.column_headers = formatted.keys() + self.queue.append(formatted.values()) + + def flush(self): + table = PrettyTable(self.column_headers) + for column_header in self.column_headers: + table.set_field_align(column_header, 'l') + for line in self.queue: + table.add_row(line) + print getattr(table, self.result_funcname)().encode('utf-8') + + def format_dict(self, item): + # format is done in self.flush() by prettytable + return item