Adding upstream version 1.6.4.
Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
parent
a5555eb4a1
commit
d5b8e0af0d
42 changed files with 3857 additions and 0 deletions
65
examples/family_tree.py
Normal file
65
examples/family_tree.py
Normal file
|
@ -0,0 +1,65 @@
|
|||
#!/usr/bin/env python
|
||||
# Example usage of treelib
|
||||
#
|
||||
# Author: chenxm
|
||||
#
|
||||
__author__ = "chenxm"
|
||||
|
||||
from treelib import Tree
|
||||
|
||||
|
||||
def create_family_tree():
|
||||
# Create the family tree
|
||||
tree = Tree()
|
||||
tree.create_node("Harry", "harry") # root node
|
||||
tree.create_node("Jane", "jane", parent="harry")
|
||||
tree.create_node("Bill", "bill", parent="harry")
|
||||
tree.create_node("Diane", "diane", parent="jane")
|
||||
tree.create_node("Mary", "mary", parent="diane")
|
||||
tree.create_node("Mark", "mark", parent="jane")
|
||||
return tree
|
||||
|
||||
|
||||
def example(desp):
|
||||
sep = "-" * 20 + "\n"
|
||||
print(sep + desp)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
tree = create_family_tree()
|
||||
|
||||
example("Tree of the whole family:")
|
||||
tree.show(key=lambda x: x.tag, reverse=True, line_type="ascii-em")
|
||||
|
||||
example("All family members in DEPTH mode:")
|
||||
print(",".join([tree[node].tag for node in tree.expand_tree()]))
|
||||
|
||||
example("All family members (with identifiers) but Diane's sub-family:")
|
||||
tree.show(idhidden=False, filter=lambda x: x.identifier != "diane")
|
||||
|
||||
example("Let me introduce Diane family only:")
|
||||
sub_t = tree.subtree("diane")
|
||||
sub_t.show()
|
||||
|
||||
example("Children of Diane:")
|
||||
for child in tree.is_branch("diane"):
|
||||
print(tree[child].tag)
|
||||
|
||||
example("New members join Jill's family:")
|
||||
new_tree = Tree()
|
||||
new_tree.create_node("n1", 1) # root node
|
||||
new_tree.create_node("n2", 2, parent=1)
|
||||
new_tree.create_node("n3", 3, parent=1)
|
||||
tree.paste("bill", new_tree)
|
||||
tree.show()
|
||||
|
||||
example("They leave after a while:")
|
||||
tree.remove_node(1)
|
||||
tree.show()
|
||||
|
||||
example("Now Mary moves to live with grandfather Harry:")
|
||||
tree.move_node("mary", "harry")
|
||||
tree.show()
|
||||
|
||||
example("A big family for Mark to send message to the oldest Harry:")
|
||||
print(",".join([tree[node].tag for node in tree.rsearch("mark")]))
|
207
examples/folder_tree.py
Normal file
207
examples/folder_tree.py
Normal file
|
@ -0,0 +1,207 @@
|
|||
#!/usr/bin/env python
|
||||
# A file folder scanner contributed by @holger
|
||||
#
|
||||
# You can spicify the scanned folder and file pattern by changing rootPath
|
||||
# and pattern variables
|
||||
#
|
||||
|
||||
__author__ = "holger"
|
||||
|
||||
from treelib import tree
|
||||
|
||||
import fnmatch
|
||||
import os
|
||||
import zlib
|
||||
import argparse
|
||||
|
||||
DEBUG = 0
|
||||
FILECOUNT = 0
|
||||
DIRCOUNT = 0
|
||||
DIR_ERRORLIST = []
|
||||
FILE_ERRORLIST = []
|
||||
|
||||
|
||||
# Time Profiling
|
||||
PROFILING = 0
|
||||
# 0 - nothing
|
||||
# 1 - time
|
||||
# 2 - cProfile
|
||||
|
||||
if PROFILING == 1:
|
||||
import timeit
|
||||
if PROFILING == 2:
|
||||
import cProfile
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Scan the given folder and print its structure in a tree."
|
||||
)
|
||||
parser.add_argument("abspath", type=str, help="An absolute path to be scanned.")
|
||||
parser.add_argument(
|
||||
"pattern", type=str, help="File name pattern to filtered, e.g. *.pdf"
|
||||
)
|
||||
|
||||
args = parser.parse_args()
|
||||
rootPath = args.abspath
|
||||
pattern = args.pattern
|
||||
|
||||
folder_blacklist = []
|
||||
|
||||
dir_tree = tree.Tree()
|
||||
dir_tree.create_node("Root", rootPath) # root node
|
||||
|
||||
|
||||
def crc32(data):
|
||||
data = bytes(data, "UTF-8")
|
||||
|
||||
if DEBUG:
|
||||
print("++++++ CRC32 ++++++")
|
||||
print("input: " + str(data))
|
||||
print("crc32: " + hex(zlib.crc32(data) & 0xFFFFFFFF))
|
||||
print("+++++++++++++++++++")
|
||||
return hex(
|
||||
zlib.crc32(data) & 0xFFFFFFFF
|
||||
) # crc32 returns a signed value, &-ing it will match py3k
|
||||
|
||||
|
||||
parent = rootPath
|
||||
i = 1
|
||||
|
||||
# calculating start depth
|
||||
start_depth = rootPath.count("/")
|
||||
|
||||
|
||||
def get_noteid(depth, root, dir):
|
||||
"""get_noteid returns
|
||||
- depth contains the current depth of the folder hierarchy
|
||||
- dir contains the current directory
|
||||
|
||||
Function returns a string containing the current depth, the folder name and unique ID build by hashing the
|
||||
absolute path of the directory. All spaces are replaced by '_'
|
||||
|
||||
<depth>_<dirname>+++<crc32>
|
||||
e.g. 2_Folder_XYZ_1+++<crc32>
|
||||
"""
|
||||
return (
|
||||
str(str(depth) + "_" + dir).replace(" ", "_")
|
||||
+ "+++"
|
||||
+ crc32(os.path.join(root, dir))
|
||||
)
|
||||
|
||||
|
||||
# TODO: Verzeichnistiefe pruefen: Was ist mit sowas /mp3/
|
||||
|
||||
|
||||
def get_parentid(current_depth, root, dir):
|
||||
# special case for the 'root' of the tree
|
||||
# because we don't want a cryptic root-name
|
||||
if current_depth == 0:
|
||||
return root
|
||||
|
||||
# looking for parent directory
|
||||
# e.g. /home/user1/mp3/folder1/parent_folder/current_folder
|
||||
# get 'parent_folder'
|
||||
|
||||
search_string = os.path.join(root, dir)
|
||||
pos2 = search_string.rfind("/")
|
||||
pos1 = search_string.rfind("/", 0, pos2)
|
||||
parent_dir = search_string[pos1 + 1 : pos2] # noqa: E203
|
||||
parentid = (
|
||||
str(current_depth - 1)
|
||||
+ "_"
|
||||
+ parent_dir.replace(" ", "_")
|
||||
+ "+++"
|
||||
+ crc32(root)
|
||||
)
|
||||
return parentid
|
||||
# TODO: catch error
|
||||
|
||||
|
||||
def print_node(dir, node_id, parent_id):
|
||||
print("#############################")
|
||||
print("node created")
|
||||
print(" dir: " + dir)
|
||||
print(" note_id: " + node_id)
|
||||
print(" parent: " + parent_id)
|
||||
|
||||
|
||||
def crawler():
|
||||
global DIRCOUNT
|
||||
global FILECOUNT
|
||||
|
||||
for root, dirs, files in os.walk(rootPath):
|
||||
# +++ DIRECTORIES +++
|
||||
for dir in dirs:
|
||||
# calculating current depth
|
||||
current_depth = os.path.join(root, dir).count("/") - start_depth
|
||||
|
||||
if DEBUG:
|
||||
print("current: " + os.path.join(root, dir))
|
||||
|
||||
node_id = get_noteid(current_depth, root, dir)
|
||||
parent_id = str(get_parentid(current_depth, root, dir))
|
||||
|
||||
if parent_id == str(None):
|
||||
DIR_ERRORLIST.append(os.path.join(root, dir))
|
||||
|
||||
if DEBUG:
|
||||
print_node(dir, node_id, parent_id)
|
||||
|
||||
# create node
|
||||
dir_tree.create_node(dir, node_id, parent_id)
|
||||
DIRCOUNT += 1
|
||||
|
||||
# +++ FILES +++
|
||||
for filename in fnmatch.filter(files, pattern):
|
||||
if dir in folder_blacklist:
|
||||
continue
|
||||
|
||||
# calculating current depth
|
||||
current_depth = os.path.join(root, filename).count("/") - start_depth
|
||||
|
||||
if DEBUG:
|
||||
print("current: " + os.path.join(root, filename))
|
||||
|
||||
node_id = get_noteid(current_depth, root, filename)
|
||||
parent_id = str(get_parentid(current_depth, root, filename))
|
||||
|
||||
if parent_id == str(None):
|
||||
FILE_ERRORLIST.append(os.path.join(root, dir))
|
||||
|
||||
if DEBUG:
|
||||
print_node(filename, node_id, parent_id)
|
||||
|
||||
# create node
|
||||
dir_tree.create_node(filename, node_id, parent_id)
|
||||
FILECOUNT += 1
|
||||
|
||||
|
||||
if PROFILING == 0:
|
||||
crawler()
|
||||
if PROFILING == 1:
|
||||
t1 = timeit.Timer("crawler()", "from __main__ import crawler")
|
||||
print("time: " + str(t1.timeit(number=1)))
|
||||
if PROFILING == 2:
|
||||
cProfile.run("crawler()")
|
||||
|
||||
|
||||
print("filecount: " + str(FILECOUNT))
|
||||
print("dircount: " + str(DIRCOUNT))
|
||||
|
||||
if DIR_ERRORLIST:
|
||||
for item in DIR_ERRORLIST:
|
||||
print(item)
|
||||
else:
|
||||
print("no directory errors")
|
||||
|
||||
print("\n\n\n")
|
||||
|
||||
if FILE_ERRORLIST:
|
||||
for item in FILE_ERRORLIST:
|
||||
print(item)
|
||||
else:
|
||||
print("no file errors")
|
||||
|
||||
print("nodes: " + str(len(dir_tree.nodes)))
|
||||
|
||||
dir_tree.show()
|
89
examples/recursive_dirtree_generator.py
Normal file
89
examples/recursive_dirtree_generator.py
Normal file
|
@ -0,0 +1,89 @@
|
|||
#!/usr/bin/env python
|
||||
|
||||
"""
|
||||
Example of treelib usage to generate recursive tree of directories.
|
||||
It could be useful to implement Directory Tree data structure
|
||||
|
||||
2016 samuelsh
|
||||
"""
|
||||
|
||||
import treelib
|
||||
import random
|
||||
import hashlib
|
||||
from string import digits, letters
|
||||
import sys
|
||||
|
||||
|
||||
MAX_FILES_PER_DIR = 10
|
||||
|
||||
|
||||
def range2(stop):
|
||||
if sys.version_info[0] < 3:
|
||||
return xrange(stop) # noqa: F821
|
||||
else:
|
||||
return range(stop)
|
||||
|
||||
|
||||
def get_random_string(length):
|
||||
return "".join(random.choice(digits + letters) for _ in range2(length))
|
||||
|
||||
|
||||
def build_recursive_tree(tree, base, depth, width):
|
||||
"""
|
||||
Args:
|
||||
tree: Tree
|
||||
base: Node
|
||||
depth: int
|
||||
width: int
|
||||
|
||||
Returns:
|
||||
|
||||
"""
|
||||
if depth >= 0:
|
||||
depth -= 1
|
||||
for i in range2(width):
|
||||
directory = Directory()
|
||||
tree.create_node(
|
||||
"{0}".format(directory.name),
|
||||
"{0}".format(hashlib.md5(directory.name)),
|
||||
parent=base.identifier,
|
||||
data=directory,
|
||||
) # node identifier is md5 hash of it's name
|
||||
dirs_nodes = tree.children(base.identifier)
|
||||
for dir in dirs_nodes:
|
||||
newbase = tree.get_node(dir.identifier)
|
||||
build_recursive_tree(tree, newbase, depth, width)
|
||||
else:
|
||||
return
|
||||
|
||||
|
||||
class Directory(object):
|
||||
def __init__(self):
|
||||
self._name = get_random_string(64)
|
||||
self._files = [
|
||||
File() for _ in range2(MAX_FILES_PER_DIR)
|
||||
] # Each directory contains 1000 files
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def files(self):
|
||||
return self._files
|
||||
|
||||
|
||||
class File(object):
|
||||
def __init__(self):
|
||||
self._name = get_random_string(64)
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
return self._name
|
||||
|
||||
|
||||
tree = treelib.Tree()
|
||||
base = tree.create_node("Root", "root")
|
||||
build_recursive_tree(tree, base, 2, 10)
|
||||
|
||||
tree.show()
|
12
examples/save_tree_2_file.py
Normal file
12
examples/save_tree_2_file.py
Normal file
|
@ -0,0 +1,12 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
|
||||
from treelib import Tree
|
||||
|
||||
tree = Tree()
|
||||
tree.create_node("Harry", "harry") # root node
|
||||
tree.create_node("Jane", "jane", parent="harry")
|
||||
tree.create_node("Bill", "bill", parent="harry")
|
||||
tree.create_node("Diane", "diane", parent="jane")
|
||||
tree.create_node("Mary", "mary", parent="diane")
|
||||
tree.create_node("Mark", "mark", parent="jane")
|
||||
tree.save2file("tree.txt")
|
Loading…
Add table
Add a link
Reference in a new issue