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))