将标记列表显示为缩进树网格

时间:2014-07-11 08:18:19

标签: list tree treeview

我正在编写一个记录条目级别的记录器。 为简单起见,我们说它会记录<level> <message>之类的条目。 我现在正在尝试编写一个日志查看器来格式化日志文件&#34;很好地&#34;作为缩进的树格。 例如,原始日志文件包含:

0 entry1
0 entry2
1 entry3
2 entry4
3 entry5
2 entry6
0 entry7

应输出:

entry1
entry2
└entry3
 ├entry4
 │└entry5
 └entry6
entry7

我的第一步是

  1. 将列表转换为树
  2. 递归打印树
  3. 这只有一个例外:我无法弄清楚如何在entry5符号之前传递信息 - 参考示例 - 以显示前一级别继续子水平。 所以任何提示,如何从列表到所需的输出都是受欢迎的。

1 个答案:

答案 0 :(得分:0)

终于明白了:

class LogViewer(LogFile):
    """
    Formats raw log file contents nicely 
    and thus makes it human-readable
    """
    __down = False

    class EntryTreeNode():
        """
        A minimal entry wrapper
        """
        def __init__(self, string):
            """
            Constructor
            """
            lst = string.split(LogEntry.colsep())
            if len(lst) != 6:
                raise Exception('Invalid entry: ' + string)
            else:
                self.DATE = datetime.strptime(lst[0], LogEntry.timeformat())
                self.ERRLVL = ErrLvlType(lst[1])
                self.USER = lst[2]
                self.CALLER = lst[3]
                self.OFFSET = int(lst[4])
                self.MSG = lst[5]

                self.tag = self.OFFSET
                self.children = []
                self.pre = '[' + datetime.strftime(self.DATE, LogEntry.timeformat()) + ']\t' \
                    + str(self.ERRLVL) + '\t' \
                    + str(self.USER) + '\t'
                self.post = str(self.CALLER) + '       \t' + str(self.MSG)

        def __repr__(self):
            return str(self.tag)


    def __init__(self, path):
        """
        Constructor
        """
        super().__init__(path)

    @property
    def __sym_last(self):
        """
        Returns the symbol for a last entry
        """
        return '┌' if self.__down else '└'

    @property
    def __sym_mid(self):
        """
        Returns the symbol for a middle entry
        """
        return '├'

    @property
    def __sym_follow(self):
        """
        Returns the symbol for a following entry
        """
        return '│'

    def __mktree(self, lst):
        """
        Converts a log entry list into a tree
        """
        roots = []

        def children(root, lst):
            result = []
            while lst:
                curr = lst.pop()
                if curr.tag == root.tag + 1:
                    curr.children = children(curr, lst)
                    result.append(curr)
                else:
                    lst.append(curr)
                    break
            return result

        while lst:
            curr = lst.pop()
            if curr.tag == 0:
                curr.children = children(curr, lst)
                roots.append(curr)
        return roots


    def __print_tree(self, root, offset='', prefix='', last=True):
        """
        Prints a log entry tree
        """
        print(root.pre + offset + prefix + root.post)
        if last:
            offset += ' '
        else:
            offset += self.__sym_follow
        for i in range(0, len(root.children)):
            if i == len(root.children)-1:
                prefix = self.__sym_last
                last = True
            else:
                prefix = self.__sym_mid
                last = False
            self.__print_tree(root.children[i], offset, prefix, last)

    def display(self, reverse=False):
        """
        Displays the log file nicely
        """
        self.__down = reverse
        entries = reversed(self.dump()) if reverse else self.dump()
        entries = [self.EntryTreeNode(e) for e in entries]

        tree = self.__mktree(entries)
        for root in tree:
            self.__print_tree(root)