Source code for sequana.utils.tree

import fnmatch
from pathlib import Path


[docs] class HTMLDirectory: def __init__(self, path=".", skip_pattern=[], pattern=None): self.path = path self.skip_pattern = skip_pattern self.pattern = pattern
[docs] def get_html(self): paths = DisplayablePath.make_tree(Path(self.path)) html = """ <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">' <style type="text/css"> <!-- BODY { font-family : ariel, monospace, sans-serif; } P { font-weight: normal; font-family : ariel, monospace, sans-serif; color: black; background-color: transparent;} B { font-weight: normal; color: black; background-color: transparent;} A:visited { font-weight : normal; text-decoration : none; background-color : transparent; margin : 0px 0px 0px 0px; padding : 0px 0px 0px 0px; display: inline; } A:link { font-weight : normal; text-decoration : none; margin : 0px 0px 0px 0px; padding : 0px 0px 0px 0px; display: inline; } A:hover { color : #000000; font-weight : normal; text-decoration : underline; background-color : yellow; margin : 0px 0px 0px 0px; padding : 0px 0px 0px 0px; display: inline; } A:active { color : #000000; font-weight: normal; background-color : transparent; margin : 0px 0px 0px 0px; padding : 0px 0px 0px 0px; display: inline; } .VERSION { font-size: small; font-family : arial, sans-serif; } .NORM { color: black; background-color: transparent;} .FIFO { color: purple; background-color: transparent;} .CHAR { color: yellow; background-color: transparent;} .DIR { color: blue; background-color: transparent;} .BLOCK { color: yellow; background-color: transparent;} .LINK { color: aqua; background-color: transparent;} .SOCK { color: fuchsia;background-color: transparent;} .EXEC { color: green; background-color: transparent;} --> </style> </head><body><p>\n""" for path in paths: realpath = path.path name = path.displayable() if self.pattern: if fnmatch.fnmatch(path.path.name, self.pattern): html += '<a href="{}">{}</a><br>'.format(realpath, name) + "\n" else: S = [item in name for item in self.skip_pattern] if sum(S) == 0: html += '<a href="{}">{}</a><br>'.format(realpath, name) + "\n" html += "</p></body></html>\n" return html
[docs] class DisplayablePath(object): """ :: paths = DisplayablePath.make_tree(Path('doc')) for path in paths: print(path.displayable()) Inspired from https://stackoverflow.com/questions/9727673/list-directory-tree-structure-in-python """ display_filename_prefix_middle = "\u251c\u2500" display_filename_prefix_last = "\u2514\u2500\u2500" display_parent_prefix_middle = " " display_parent_prefix_last = "\u2502 " def __init__(self, path, parent_path, is_last): self.path = Path(str(path)) self.parent = parent_path self.is_last = is_last if self.parent: self.depth = self.parent.depth + 1 else: self.depth = 0 @property def displayname(self): if self.path.is_dir(): return self.path.name + "/" return self.path.name
[docs] @classmethod def make_tree(cls, root, parent=None, is_last=False, criteria=None): root = Path(str(root)) criteria = criteria or cls._default_criteria displayable_root = cls(root, parent, is_last) yield displayable_root children = sorted(list(path for path in root.iterdir() if criteria(path)), key=lambda s: str(s).lower()) count = 1 for path in children: is_last = count == len(children) if path.is_dir(): yield from cls.make_tree(path, parent=displayable_root, is_last=is_last, criteria=criteria) else: yield cls(path, displayable_root, is_last) count += 1
@classmethod def _default_criteria(cls, path): return True
[docs] def displayable(self): if self.parent is None: return self.displayname _filename_prefix = self.display_filename_prefix_last if self.is_last else self.display_filename_prefix_middle parts = ["{!s} {!s}".format(_filename_prefix, self.displayname)] parent = self.parent while parent and parent.parent is not None: parts.append(self.display_parent_prefix_middle if parent.is_last else self.display_parent_prefix_last) parent = parent.parent return "".join(reversed(parts))