Beispiel #1
0
 def __init__(self, args, table=None):
     if args.color == 'auto':
         self.table = MultiTable(initial_section=False,
                                 column_separator='|')
     elif args.color == 'off':
         styler = Styler()
         self.table = MultiTable(initial_section=False,
                                 column_separator='|', styler=styler)
     elif args.color == 'on':
         styler = ColorizedStyler()
         self.table = MultiTable(initial_section=False,
                                 column_separator='|', styler=styler)
     else:
         raise ValueError("Unknown color option: %s" % args.color)
 def setUp(self):
     styler = Styler()
     self.table = MultiTable(initial_section=False,
                             column_separator='|', styler=styler,
                             auto_reformat=False)
     self.formatter = TableFormatter(Object(color='off'))
     self.formatter.table = self.table
     self.stream = six.StringIO()
Beispiel #3
0
class TestVerticalTableConversion(unittest.TestCase):
    def setUp(self):
        self.table = MultiTable()

    def test_convert_section_to_vertical(self):
        self.table.add_title("foo")
        self.table.add_row_header(["key1", "key2", "key3"])
        self.table.add_row(["val1", "val2", "val3"])
        convert_to_vertical_table(self.table._sections)
        # To convert to a vertical table, there should be no headers:
        section = self.table._sections[0]
        self.assertEqual(section.headers, [])
        # Then we should create a two column row with key val pairs.
        self.assertEqual(section.rows, [["key1", "val1"], ["key2", "val2"], ["key3", "val3"]])
Beispiel #4
0
 def __init__(self, args, table=None):
     super(TableFormatter, self).__init__(args)
     if args.color == 'auto':
         self.table = MultiTable(initial_section=False,
                                 column_separator='|')
     elif args.color == 'off':
         styler = Styler()
         self.table = MultiTable(initial_section=False,
                                 column_separator='|', styler=styler)
     elif args.color == 'on':
         styler = ColorizedStyler()
         self.table = MultiTable(initial_section=False,
                                 column_separator='|', styler=styler)
     else:
         raise ValueError("Unknown color option: %s" % args.color)
Beispiel #5
0
class TestVerticalTableConversion(unittest.TestCase):
    def setUp(self):
        self.table = MultiTable()

    def test_convert_section_to_vertical(self):
        self.table.add_title('foo')
        self.table.add_row_header(['key1', 'key2', 'key3'])
        self.table.add_row(['val1', 'val2', 'val3'])
        convert_to_vertical_table(self.table._sections)
        # To convert to a vertical table, there should be no headers:
        section = self.table._sections[0]
        self.assertEqual(section.headers, [])
        # Then we should create a two column row with key val pairs.
        self.assertEqual(
            section.rows,
            [['key1', 'val1'], ['key2', 'val2'], ['key3', 'val3']])
Beispiel #6
0
def tabulate(operation, data):
    """
    Formats a data structure as a table
    :param operation: the title of the table
    :param data: list or dict to print
    """
    if data is None:
        return ""
    table = MultiTable(initial_section=False,
                       column_separator='|',
                       styler=Styler(),
                       auto_reformat=False)

    formatter = TableFormatter(
        type('dummy', (object, ), {
            "color": "on",
            "query": None
        }))
    formatter.table = table
    stream = six.StringIO()
    formatter(operation, data, stream=stream)
    return stream.getvalue()
Beispiel #7
0
 def setUp(self):
     self.table = MultiTable()
Beispiel #8
0
class TestMultiTable(unittest.TestCase):
    def setUp(self):
        self.table = MultiTable()

    def test_max_width_calculation(self):
        self.table.add_title('foo')
        self.table.add_row_header(['one', 'two', 'three'])
        self.table.add_row(['one', 'two', 'three'])
        self.table.new_section('bar')
        self.table.add_row_header(['one', 'two'])
        self.table.add_row(['12345', '1234567'])
Beispiel #9
0
class TableFormatter(FullyBufferedFormatter):
    """Pretty print a table from a given response.

    The table formatter is able to take any generic response
    and generate a pretty printed table.  It does this without
    using the output definition from the model.

    """
    def __init__(self, args, table=None):
        super(TableFormatter, self).__init__(args)
        if args.color == 'auto':
            self.table = MultiTable(initial_section=False,
                                    column_separator='|')
        elif args.color == 'off':
            styler = Styler()
            self.table = MultiTable(initial_section=False,
                                    column_separator='|',
                                    styler=styler)
        elif args.color == 'on':
            styler = ColorizedStyler()
            self.table = MultiTable(initial_section=False,
                                    column_separator='|',
                                    styler=styler)
        else:
            raise ValueError("Unknown color option: %s" % args.color)

    def _format_response(self, command_name, response, stream):
        if self._build_table(command_name, response):
            try:
                self.table.render(stream)
            except IOError:
                # If they're piping stdout to another process which exits before
                # we're done writing all of our output, we'll get an error about a
                # closed pipe which we can safely ignore.
                pass

    def _build_table(self, title, current, indent_level=0):
        if not current:
            return False
        if title is not None:
            self.table.new_section(title, indent_level=indent_level)
        if isinstance(current, list):
            if isinstance(current[0], dict):
                self._build_sub_table_from_list(current, indent_level, title)
            else:
                for item in current:
                    if self._scalar_type(item):
                        self.table.add_row([item])
                    elif all(self._scalar_type(el) for el in item):
                        self.table.add_row(item)
                    else:
                        self._build_table(title=None, current=item)
        if isinstance(current, dict):
            # Render a single row section with keys as header
            # and the row as the values, unless the value
            # is a list.
            self._build_sub_table_from_dict(current, indent_level)
        return True

    def _build_sub_table_from_dict(self, current, indent_level):
        # Render a single row section with keys as header
        # and the row as the values, unless the value
        # is a list.
        headers, more = self._group_scalar_keys(current)
        if len(headers) == 1:
            # Special casing if a dict has a single scalar key/value pair.
            self.table.add_row([headers[0], current[headers[0]]])
        elif headers:
            self.table.add_row_header(headers)
            self.table.add_row([current[k] for k in headers])
        for remaining in more:
            self._build_table(remaining,
                              current[remaining],
                              indent_level=indent_level + 1)

    def _build_sub_table_from_list(self, current, indent_level, title):
        headers, more = self._group_scalar_keys_from_list(current)
        self.table.add_row_header(headers)
        first = True
        for element in current:
            if not first and more:
                self.table.new_section(title, indent_level=indent_level)
                self.table.add_row_header(headers)
            first = False
            # Use .get() to account for the fact that sometimes an element
            # may not have all the keys from the header.
            self.table.add_row([element.get(header, '') for header in headers])
            for remaining in more:
                # Some of the non scalar attributes may not necessarily
                # be in every single element of the list, so we need to
                # check this condition before recursing.
                if remaining in element:
                    self._build_table(remaining,
                                      element[remaining],
                                      indent_level=indent_level + 1)

    def _scalar_type(self, element):
        return not isinstance(element, (list, dict))

    def _group_scalar_keys_from_list(self, list_of_dicts):
        # We want to make sure we catch all the keys in the list of dicts.
        # Most of the time each list element has the same keys, but sometimes
        # a list element will have keys not defined in other elements.
        headers = set()
        more = set()
        for item in list_of_dicts:
            current_headers, current_more = self._group_scalar_keys(item)
            headers.update(current_headers)
            more.update(current_more)
        headers = list(sorted(headers))
        more = list(sorted(more))
        return headers, more

    def _group_scalar_keys(self, current):
        # Given a dict, separate the keys into those whose values are
        # scalar, and those whose values aren't.  Return two lists,
        # one is the scalar value keys, the second is the remaining keys.
        more = []
        headers = []
        for element in current:
            if self._scalar_type(current[element]):
                headers.append(element)
            else:
                more.append(element)
        headers.sort()
        more.sort()
        return headers, more
Beispiel #10
0
class TableFormatter(FullyBufferedFormatter):
    """Pretty print a table from a given response.

    The table formatter is able to take any generic response
    and generate a pretty printed table.  It does this without
    using the output definition from the model.

    """
    def __init__(self, args, table=None):
        super(TableFormatter, self).__init__(args)
        if args.color == 'auto':
            self.table = MultiTable(initial_section=False,
                                    column_separator='|')
        elif args.color == 'off':
            styler = Styler()
            self.table = MultiTable(initial_section=False,
                                    column_separator='|', styler=styler)
        elif args.color == 'on':
            styler = ColorizedStyler()
            self.table = MultiTable(initial_section=False,
                                    column_separator='|', styler=styler)
        else:
            raise ValueError("Unknown color option: %s" % args.color)

    def _format_response(self, operation, response, stream):
        if self._build_table(operation.name, response):
            try:
                self.table.render(stream)
            except IOError:
                # If they're piping stdout to another process which exits before
                # we're done writing all of our output, we'll get an error about a
                # closed pipe which we can safely ignore.
                pass

    def _build_table(self, title, current, indent_level=0):
        if not current:
            return False
        if title is not None:
            self.table.new_section(title, indent_level=indent_level)
        if isinstance(current, list):
            if isinstance(current[0], dict):
                self._build_sub_table_from_list(current, indent_level, title)
            else:
                for item in current:
                    if self._scalar_type(item):
                        self.table.add_row([item])
                    elif all(self._scalar_type(el) for el in item):
                        self.table.add_row(item)
                    else:
                        self._build_table(title=None, current=item)
        if isinstance(current, dict):
            # Render a single row section with keys as header
            # and the row as the values, unless the value
            # is a list.
            self._build_sub_table_from_dict(current, indent_level)
        return True

    def _build_sub_table_from_dict(self, current, indent_level):
        # Render a single row section with keys as header
        # and the row as the values, unless the value
        # is a list.
        headers, more = self._group_scalar_keys(current)
        if len(headers) == 1:
            # Special casing if a dict has a single scalar key/value pair.
            self.table.add_row([headers[0], current[headers[0]]])
        elif headers:
            self.table.add_row_header(headers)
            self.table.add_row([current[k] for k in headers])
        for remaining in more:
            self._build_table(remaining, current[remaining],
                              indent_level=indent_level + 1)

    def _build_sub_table_from_list(self, current, indent_level, title):
        headers, more = self._group_scalar_keys_from_list(current)
        self.table.add_row_header(headers)
        first = True
        for element in current:
            if not first and more:
                self.table.new_section(title,
                                       indent_level=indent_level)
                self.table.add_row_header(headers)
            first = False
            # Use .get() to account for the fact that sometimes an element
            # may not have all the keys from the header.
            self.table.add_row([element.get(header, '') for header in headers])
            for remaining in more:
                # Some of the non scalar attributes may not necessarily
                # be in every single element of the list, so we need to
                # check this condition before recursing.
                if remaining in element:
                    self._build_table(remaining, element[remaining],
                                    indent_level=indent_level + 1)

    def _scalar_type(self, element):
        return not isinstance(element, (list, dict))

    def _group_scalar_keys_from_list(self, list_of_dicts):
        # We want to make sure we catch all the keys in the list of dicts.
        # Most of the time each list element has the same keys, but sometimes
        # a list element will have keys not defined in other elements.
        headers = set()
        more = set()
        for item in list_of_dicts:
            current_headers, current_more = self._group_scalar_keys(item)
            headers.update(current_headers)
            more.update(current_more)
        headers = list(sorted(headers))
        more = list(sorted(more))
        return headers, more

    def _group_scalar_keys(self, current):
        # Given a dict, separate the keys into those whose values are
        # scalar, and those whose values aren't.  Return two lists,
        # one is the scalar value keys, the second is the remaining keys.
        more = []
        headers = []
        for element in current:
            if self._scalar_type(current[element]):
                headers.append(element)
            else:
                more.append(element)
        headers.sort()
        more.sort()
        return headers, more
Beispiel #11
0
class TableFormatter(Formatter):
    """Pretty print a table from a given response.

    The table formatter is able to take any generic response
    and generate a pretty printed table.  It does this without
    using the output definition from the model.

    """
    def __init__(self, args, table=None):
        if args.color == 'auto':
            self.table = MultiTable(initial_section=False,
                                    column_separator='|')
        elif args.color == 'off':
            styler = Styler()
            self.table = MultiTable(initial_section=False,
                                    column_separator='|', styler=styler)
        elif args.color == 'on':
            styler = ColorizedStyler()
            self.table = MultiTable(initial_section=False,
                                    column_separator='|', styler=styler)
        else:
            raise ValueError("Unknown color option: %s" % args.color)

    def __call__(self, operation, response, stream=None):
        if stream is None:
            # Retrieve stdout on invocation instead of at import time
            # so that if anything wraps stdout we'll pick up those changes
            # (specifically colorama on windows wraps stdout).
            stream = sys.stdout
        self._build_table(operation.name, response)
        try:
            self.table.render(stream)
        except IOError:
            # If they're piping stdout to another process which exits before
            # we're done writing all of our output, we'll get an error about a
            # closed pipe which we can safely ignore.
            pass


    def _build_table(self, title, current, indent_level=0):
        if not current:
            return
        self.table.new_section(title, indent_level=indent_level)
        if isinstance(current, list):
            if isinstance(current[0], dict):
                self._build_sub_table_from_list(current, indent_level, title)
            else:
                for item in current:
                    self.table.add_row([item])
        if isinstance(current, dict):
            # Render a single row section with keys as header
            # and the row as the values, unless the value
            # is a list.
            self._build_sub_table_from_dict(current, indent_level)

    def _build_sub_table_from_dict(self, current, indent_level):
        # Render a single row section with keys as header
        # and the row as the values, unless the value
        # is a list.
        headers, more = self._group_scalar_keys(current)
        if len(headers) == 1:
            # Special casing if a dict has a single scalar key/value pair.
            self.table.add_row([headers[0], current[headers[0]]])
        elif headers:
            self.table.add_row_header(headers)
            self.table.add_row([current[k] for k in headers])
        for remaining in more:
            self._build_table(remaining, current[remaining],
                              indent_level=indent_level + 1)

    def _build_sub_table_from_list(self, current, indent_level, title):
        headers, more = self._group_scalar_keys(current[0])
        self.table.add_row_header(headers)
        first = True
        for element in current:
            if not first and more:
                self.table.new_section(title,
                                       indent_level=indent_level)
                self.table.add_row_header(headers)
            first = False
            self.table.add_row([element[header] for header in headers])
            for remaining in more:
                # Some of the non scalar attributes may not necessarily
                # be in every single element of the list, so we need to
                # check this condition before recursing.
                if remaining in element:
                    self._build_table(remaining, element[remaining],
                                    indent_level=indent_level + 1)

    def _scalar_type(self, element):
        return not isinstance(element, (list, dict))

    def _group_scalar_keys(self, current):
        # Given a dict, separate the keys into those whose values are
        # scalar, and those whose values aren't.  Return two lists,
        # one is the scalar value keys, the second is the remaining keys.
        more = []
        headers = []
        for element in current:
            if self._scalar_type(current[element]):
                headers.append(element)
            else:
                more.append(element)
        headers.sort()
        more.sort()
        return headers, more
Beispiel #12
0
 def setUp(self):
     self.table = MultiTable()
Beispiel #13
0
class TestMultiTable(unittest.TestCase):
    def setUp(self):
        self.table = MultiTable()

    def test_max_width_calculation(self):
        self.table.add_title("foo")
        self.table.add_row_header(["one", "two", "three"])
        self.table.add_row(["one", "two", "three"])
        self.table.new_section("bar")
        self.table.add_row_header(["one", "two"])
        self.table.add_row(["12345", "1234567"])
Beispiel #14
0
class TestMultiTable(unittest.TestCase):
    def setUp(self):
        self.table = MultiTable()

    def test_max_width_calculation(self):
        self.table.add_title('foo')
        self.table.add_row_header(['one', 'two', 'three'])
        self.table.add_row(['one', 'two', 'three'])
        self.table.new_section('bar')
        self.table.add_row_header(['one', 'two'])
        self.table.add_row(['12345', '1234567'])
Beispiel #15
0
from awscli.compat import six
from awscli.formatter import TableFormatter
from awscli.table import MultiTable, ColorizedStyler
import sys
import json


class Object(object):
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)
        self.query = None

stream = six.StringIO()
styler = ColorizedStyler()
table = MultiTable(initial_section=False,
                   column_separator='|', styler=styler)
formatter = TableFormatter(Object(color='on'))
formatter.table = table


DATA = []

for line in sys.stdin.readlines():
    if line.strip():
        DATA.append(json.loads(line))

formatter(sys.argv[1], DATA, stream=stream)
output = stream.getvalue()
if output: print(output)