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.
| 195 | |
| 196 | |
| 197 | class TableFormatter(FullyBufferedFormatter): |
| 198 | """Pretty print a table from a given response. |
| 199 | |
| 200 | The table formatter is able to take any generic response |
| 201 | and generate a pretty printed table. It does this without |
| 202 | using the output definition from the model. |
| 203 | |
| 204 | """ |
| 205 | |
| 206 | def __init__(self, args, table=None): |
| 207 | super(TableFormatter, self).__init__(args) |
| 208 | if args.color == 'auto': |
| 209 | self.table = MultiTable( |
| 210 | initial_section=False, column_separator='|' |
| 211 | ) |
| 212 | elif args.color == 'off': |
| 213 | styler = Styler() |
| 214 | self.table = MultiTable( |
| 215 | initial_section=False, column_separator='|', styler=styler |
| 216 | ) |
| 217 | elif args.color == 'on': |
| 218 | styler = ColorizedStyler() |
| 219 | self.table = MultiTable( |
| 220 | initial_section=False, column_separator='|', styler=styler |
| 221 | ) |
| 222 | else: |
| 223 | raise ValueError("Unknown color option: %s" % args.color) |
| 224 | |
| 225 | def _format_response(self, command_name, response, stream): |
| 226 | if self._build_table(command_name, response): |
| 227 | try: |
| 228 | self.table.render(stream) |
| 229 | except OSError: |
| 230 | # If they're piping stdout to another process which exits |
| 231 | # before we're done writing all of our output, we'll get an |
| 232 | # error about a closed pipe which we can safely ignore. |
| 233 | pass |
| 234 | |
| 235 | def _build_table(self, title, current, indent_level=0): |
| 236 | if not current: |
| 237 | return False |
| 238 | if title is not None: |
| 239 | self.table.new_section(title, indent_level=indent_level) |
| 240 | if isinstance(current, list): |
| 241 | if isinstance(current[0], dict): |
| 242 | self._build_sub_table_from_list(current, indent_level, title) |
| 243 | else: |
| 244 | for item in current: |
| 245 | if self._scalar_type(item): |
| 246 | self.table.add_row([item]) |
| 247 | elif all(self._scalar_type(el) for el in item): |
| 248 | self.table.add_row(item) |
| 249 | else: |
| 250 | self._build_table(title=None, current=item) |
| 251 | if isinstance(current, dict): |
| 252 | # Render a single row section with keys as header |
| 253 | # and the row as the values, unless the value |
| 254 | # is a list. |