def render(self, grid: interfaces.renderers.TreeGrid) -> None: """Renders each row immediately to stdout. Args: grid: The TreeGrid object to render """ outfd = sys.stdout header_list = ['TreeDepth'] for column in grid.columns: # Ignore the type because namedtuples don't realize they have accessible attributes header_list.append(f"{column.name}") writer = csv.DictWriter(outfd, header_list) writer.writeheader() def visitor(node: interfaces.renderers.TreeNode, accumulator): # Nodes always have a path value, giving them a path_depth of at least 1, we use max just in case row = {'TreeDepth': str(max(0, node.path_depth - 1))} for column_index in range(len(grid.columns)): column = grid.columns[column_index] renderer = self._type_renderers.get( column.type, self._type_renderers['default']) row[f'{column.name}'] = renderer(node.values[column_index]) accumulator.writerow(row) return accumulator if not grid.populated: grid.populate(visitor, writer) else: grid.visit(node=None, function=visitor, initial_accumulator=writer) outfd.write("\n")
def render(self, grid: interfaces.renderers.TreeGrid): outfd = sys.stdout outfd.write("\n") final_output = ( {}, []) # type: Tuple[Dict[str, List[interfaces.renderers.TreeNode]], List[interfaces.renderers.TreeNode]] def visitor( node: interfaces.renderers.TreeNode, accumulator: Tuple[Dict[str, Dict[str, Any]], List[Dict[str, Any]]] ) -> Tuple[Dict[str, Dict[str, Any]], List[Dict[str, Any]]]: # Nodes always have a path value, giving them a path_depth of at least 1, we use max just in case acc_map, final_tree = accumulator node_dict = {'__children': []} # type: Dict[str, Any] for column_index in range(len(grid.columns)): column = grid.columns[column_index] renderer = self._type_renderers.get(column.type, self._type_renderers['default']) data = renderer(list(node.values)[column_index]) if isinstance(data, interfaces.renderers.BaseAbsentValue): data = None node_dict[column.name] = data if node.parent: acc_map[node.parent.path]['__children'].append(node_dict) else: final_tree.append(node_dict) acc_map[node.path] = node_dict return (acc_map, final_tree) if not grid.populated: grid.populate(visitor, final_output) else: grid.visit(node = None, function = visitor, initial_accumulator = final_output) self.output_result(outfd, final_output[1])
def render(self, grid: interfaces.renderers.TreeGrid) -> None: """Renders each row immediately to stdout. Args: grid: The TreeGrid object to render """ outfd = sys.stdout line = ['"TreeDepth"'] for column in grid.columns: # Ignore the type because namedtuples don't realize they have accessible attributes line.append("{}".format('"' + column.name + '"')) outfd.write(f"{','.join(line)}") def visitor(node: interfaces.renderers.TreeNode, accumulator): accumulator.write("\n") # Nodes always have a path value, giving them a path_depth of at least 1, we use max just in case accumulator.write(str(max(0, node.path_depth - 1)) + ",") line = [] for column_index in range(len(grid.columns)): column = grid.columns[column_index] renderer = self._type_renderers.get( column.type, self._type_renderers['default']) line.append(renderer(node.values[column_index])) accumulator.write(f"{','.join(line)}") return accumulator if not grid.populated: grid.populate(visitor, outfd) else: grid.visit(node=None, function=visitor, initial_accumulator=outfd) outfd.write("\n")
def render(self, grid: interfaces.renderers.TreeGrid) -> None: """Renders each column immediately to stdout. This does not format each line's width appropriately, it merely tab separates each field Args: grid: The TreeGrid object to render """ # TODO: Docstrings # TODO: Improve text output outfd = sys.stdout sys.stderr.write("Formatting...\n") display_alignment = ">" column_separator = " | " tree_indent_column = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(20)) max_column_widths = dict([(column.name, len(column.name)) for column in grid.columns]) def visitor( node: interfaces.renderers.TreeNode, accumulator: List[Tuple[int, Dict[interfaces.renderers.Column, bytes]]] ) -> List[Tuple[int, Dict[interfaces.renderers.Column, bytes]]]: # Nodes always have a path value, giving them a path_depth of at least 1, we use max just in case max_column_widths[tree_indent_column] = max(max_column_widths.get(tree_indent_column, 0), node.path_depth) line = {} for column_index in range(len(grid.columns)): column = grid.columns[column_index] renderer = self._type_renderers.get(column.type, self._type_renderers['default']) data = renderer(node.values[column_index]) max_column_widths[column.name] = max(max_column_widths.get(column.name, len(column.name)), len("{}".format(data))) line[column] = data accumulator.append((node.path_depth, line)) return accumulator final_output = [] # type: List[Tuple[int, Dict[interfaces.renderers.Column, bytes]]] if not grid.populated: grid.populate(visitor, final_output) else: grid.visit(node = None, function = visitor, initial_accumulator = final_output) # Always align the tree to the left format_string_list = ["{0:<" + str(max_column_widths.get(tree_indent_column, 0)) + "s}"] for column_index in range(len(grid.columns)): column = grid.columns[column_index] format_string_list.append("{" + str(column_index + 1) + ":" + display_alignment + str(max_column_widths[column.name]) + "s}") format_string = column_separator.join(format_string_list) + "\n" column_titles = [""] + [column.name for column in grid.columns] outfd.write(format_string.format(*column_titles)) for (depth, line) in final_output: outfd.write(format_string.format("*" * depth, *[line[column] for column in grid.columns]))
def render(self, grid: interfaces.renderers.TreeGrid) -> None: """Renders each column immediately to stdout. This does not format each line's width appropriately, it merely tab separates each field Args: grid: The TreeGrid object to render """ # TODO: Docstrings # TODO: Improve text output outfd = sys.stdout line = [] for column in grid.columns: # Ignore the type because namedtuples don't realize they have accessible attributes line.append(f"{column.name}") outfd.write("\n{}\n".format("\t".join(line))) def visitor(node: interfaces.renderers.TreeNode, accumulator): accumulator.write("\n") # Nodes always have a path value, giving them a path_depth of at least 1, we use max just in case accumulator.write("*" * max(0, node.path_depth - 1) + ("" if (node.path_depth <= 1) else " ")) line = [] for column_index in range(len(grid.columns)): column = grid.columns[column_index] renderer = self._type_renderers.get( column.type, self._type_renderers['default']) line.append(renderer(node.values[column_index])) accumulator.write("{}".format("\t".join(line))) accumulator.flush() return accumulator if not grid.populated: grid.populate(visitor, outfd) else: grid.visit(node=None, function=visitor, initial_accumulator=outfd) outfd.write("\n")