File indexing completed on 2024-06-23 04:27:59
0001 # 0002 # SPDX-License-Identifier: GPL-3.0-or-later 0003 # 0004 0005 from itertools import chain 0006 from pathlib import Path 0007 0008 0009 def iterPre(node, maxDepth=-1): 0010 """ 0011 Visit nodes in pre order. 0012 0013 Parameters 0014 ---------- 0015 node: Node 0016 maxDepth: int 0017 Maximum depth level at which traversal will stop. 0018 0019 Returns 0020 ------- 0021 out: iter(Node) 0022 """ 0023 0024 def go(nodes, depth=0): 0025 for n in nodes: 0026 yield n 0027 # recursively call the generator if depth < maxDepth 0028 it = go(n.children, depth + 1) if maxDepth == -1 or depth < maxDepth else iter() 0029 yield from it 0030 0031 return go([node]) 0032 0033 0034 def iterLevel(node, maxDepth=-1): 0035 """ 0036 Visit nodes in level order. 0037 0038 Parameters 0039 ---------- 0040 node: Node 0041 maxDepth: int 0042 Maximum depth level at which traversal will stop. 0043 0044 Returns 0045 ------- 0046 out: iter(Node) 0047 """ 0048 0049 def go(nodes, depth=0): 0050 yield from nodes 0051 it = map(lambda n: go(n.children, depth + 1), nodes) 0052 it = chain(*it) if maxDepth == -1 or depth < maxDepth else iter() 0053 yield from it 0054 0055 return go([node]) 0056 0057 0058 def iterLevelGroup(node, maxDepth=-1): 0059 """ 0060 Visit nodes in level order just like `iterLevel`, but group nodes per level in an iterator. 0061 0062 Parameters 0063 ---------- 0064 node: Node 0065 maxDepth: int 0066 Maximum depth level at which traversal will stop. 0067 0068 Returns 0069 ------- 0070 out: iter(iter(Node)) 0071 Returns an iterator that holds an iterator for each depth level. 0072 """ 0073 0074 def go(nodes, depth=0): 0075 yield iter(nodes) 0076 it = map(lambda n: go(n.children, depth + 1), nodes) 0077 it = chain(*it) if maxDepth == -1 or depth < maxDepth else iter() 0078 yield from filter(None, it) 0079 0080 return go([node]) 0081 0082 0083 def iterPost(node, maxDepth=-1): 0084 """ 0085 Visit nodes in post order. 0086 0087 Parameters 0088 ---------- 0089 node: Node 0090 maxDepth: int 0091 Maximum depth level at which traversal will stop. 0092 0093 Returns 0094 ------- 0095 out: iter(Node) 0096 """ 0097 0098 def go(nodes, depth=0): 0099 for n in nodes: 0100 it = go(n.children, depth + 1) if maxDepth == -1 or depth < maxDepth else iter() 0101 yield from it 0102 yield n 0103 0104 return go([node]) 0105 0106 0107 def path(node): 0108 """ 0109 Get the path of the given node. 0110 0111 Parameters 0112 ---------- 0113 node: Node 0114 0115 Return 0116 ------ 0117 out: list(Node) 0118 The path of nodes going through all the parents to the given node. 0119 """ 0120 0121 def go(n, acc=[]): 0122 acc += [n] 0123 n.parent and go(n.parent, acc) 0124 return reversed(acc) 0125 0126 return list(go(node)) 0127 0128 0129 def pathFS(node): 0130 """ 0131 Get the path of the given node just like `path`, but returns a OS filesystem path based on 0132 node names. 0133 0134 Parameters 0135 ---------- 0136 node: Node 0137 A node that has a `name` method. 0138 0139 Return 0140 ------ 0141 out: str 0142 The path of nodes going through all the parents to the given node in filesystem-compatile 0143 string format. 0144 """ 0145 it = filter(lambda n: n.parent, path(node)) 0146 it = map(lambda n: n.name, it) 0147 return Path("").joinpath(*it) 0148 0149 0150 def iterDirs(node): 0151 it = iterPre(node) 0152 it = filter(lambda n: n.isGroupLayer(), it) 0153 it = filter( 0154 lambda n: any(i.isExportable() for i in chain(*map(lambda c: iterPre(c), n.children))), it 0155 ) 0156 it = map(pathFS, it) 0157 return it