vFW and vDNS support added to azure-plugin
[multicloud/azure.git] / azure / aria / aria-extension-cloudify / src / aria / aria / cli / table.py
1 # Licensed to the Apache Software Foundation (ASF) under one or more
2 # contributor license agreements.  See the NOTICE file distributed with
3 # this work for additional information regarding copyright ownership.
4 # The ASF licenses this file to You under the Apache License, Version 2.0
5 # (the "License"); you may not use this file except in compliance with
6 # the License.  You may obtain a copy of the License at
7 #
8 #     http://www.apache.org/licenses/LICENSE-2.0
9 #
10 # Unless required by applicable law or agreed to in writing, software
11 # distributed under the License is distributed on an "AS IS" BASIS,
12 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 # See the License for the specific language governing permissions and
14 # limitations under the License.
15
16 """
17 Tabular formatting utilities.
18 """
19
20 import os
21 from datetime import datetime
22
23 from prettytable import PrettyTable
24
25 from .env import logger
26
27
28 def print_data(columns, items, header_text,
29                column_formatters=None, col_max_width=None, defaults=None):
30     """
31     Prints data in a tabular form.
32
33     :param columns: columns of the table, e.g. ``['id','name']``
34     :type columns: iterable of basestring
35     :param items: each element must have keys or attributes corresponding to the ``columns`` items,
36      e.g. ``[{'id':'123', 'name':'Pete'}]``
37     :type data: [{:obj:`basestring`: :obj:`basestring`}]
38     :param column_formatters: maps column name to formatter, a function that may manipulate the
39      string values printed for this column, e.g. ``{'created_at': timestamp_formatter}``
40     :type column_formatters: {:obj:`basestring`: :obj:`function`}
41     :param col_max_width: maximum width of table
42     :type col_max_width: int
43     :param defaults: default values for keys that don't exist in the data itself, e.g.
44      ``{'serviceId':'123'}``
45     :type defaults: {:obj:`basestring`: :obj:`basestring`}
46     """
47     if items is None:
48         items = []
49     elif not isinstance(items, list):
50         items = [items]
51
52     pretty_table = _generate(columns, data=items, column_formatters=column_formatters,
53                              defaults=defaults)
54     if col_max_width:
55         pretty_table.max_width = col_max_width
56     _log(header_text, pretty_table)
57
58
59 def _log(title, table):
60     logger.info('{0}{1}{0}{2}{0}'.format(os.linesep, title, table))
61
62
63 def _generate(cols, data, column_formatters=None, defaults=None):
64     """
65     Return a new PrettyTable instance representing the list.
66
67     :param cols: columns of the table, e.g. ``['id','name']``
68     :type cols: iterable of :obj:`basestring`
69     :param data: each element must have keys or attributes corresponding to the ``cols`` items,
70      e.g. ``[{'id':'123', 'name':'Pete'}]``
71     :type data: [{:obj:`basestring`: :obj:`basestring`}]
72     :param column_formatters: maps column name to formatter, a function that may manipulate the
73      string values printed for this column, e.g. ``{'created_at': timestamp_formatter}``
74     :type column_formatters: {:obj:`basestring`: :obj:`function`}
75     :param defaults: default values for keys that don't exist in the data itself, e.g.
76      ``{'serviceId':'123'}``
77     :type defaults: {:obj:`basestring`: :obj:`basestring`}
78     """
79     def get_values_per_column(column, row_data):
80         if hasattr(row_data, column) or (isinstance(row_data, dict) and column in row_data):
81             val = row_data[column] if isinstance(row_data, dict) else getattr(row_data, column)
82
83             if val and isinstance(val, list):
84                 val = [str(element) for element in val]
85                 val = ','.join(val)
86             elif val is None or isinstance(val, list):
87                 # don't print `[]` or `None` (but do print `0`, `False`, etc.)
88                 val = ''
89
90             if column in column_formatters:
91                 # calling the user's column formatter to manipulate the value
92                 val = column_formatters[column](val)
93
94             return val
95         else:
96             return defaults.get(column)
97
98     column_formatters = column_formatters or dict()
99     defaults = defaults or dict()
100     pretty_table = PrettyTable(list(cols))
101
102     for datum in data:
103         values_row = []
104         for col in cols:
105             values_row.append(get_values_per_column(col, datum))
106         pretty_table.add_row(values_row)
107
108     return pretty_table
109
110
111 def timestamp_formatter(value):
112     try:
113         datetime.strptime(value[:10], '%Y-%m-%d')
114         return value.replace('T', ' ').replace('Z', ' ')
115     except ValueError:
116         # not a timestamp
117         return value
118
119
120 def trim_formatter_generator(max_length):
121     def trim_formatter(value):
122         if len(value) >= max_length:
123             value = '{0}..'.format(value[:max_length - 2])
124         return value
125     return trim_formatter