import re from src.colors import RED, YELLOW, GREEN, CYAN , BLUE, PURPLE from src.tree import NerdTree class NerdTreeFind(NerdTree): ''' @param startpath string: the startpath from which to generate the json_tree member (the tree representation) @param opts dict: the opts for the tree representation ''' def __init__(self, startpath, opts={}, find_opts={}): self.item_name = '' self.re_item_name = None self.results = [] ## computed tree for find self.json_tree_find = {} self.find_opts = find_opts NerdTree.__init__(self, startpath, opts=opts) def find_node_recursively(self, node): # if node['name'] == self.item_name: if self.re_item_name.match(node['name']): node_copy = node.copy() node_copy.update({'color_formatter' : YELLOW, 'found' : 1}) self.results.append(node_copy) children = node.get('children') or [] for item_child in children: if item_child['type'] == 'd': self.find_node_recursively(item_child) else: # if item_child['name'] == self.item_name: if self.re_item_name.match(item_child['name']): item_child_copy = item_child.copy() item_child_copy.update({'color_formatter' : YELLOW, 'found' : 1}) self.results.append(item_child_copy) def find_node(self): self.find_node_recursively(self.json_tree) return self.results def find_children(self, tree, item_abs_path): ''' It returns a tuple: first value True if father of node with item_abs_path is found, second value represents the children of parent node with item_abs_path ''' if tree['abs_path'] == item_abs_path: if not tree.get('children'): tree['children'] = [] return (True, tree['children']) children = tree.get('children') or [] if not children: return (False, []) for child in children: found, fchildren = self.find_children(child, item_abs_path) if found: return (True, fchildren) return (False, []) def find_tree_struct(self): ''' ''' results = self.find_node() ## remove from this level the option if not results: return {} # if dont_show_children_nodes: # for result in results: # children = result.get('children') or [] # result['nchildren'] = len(children) # result['children'] = [] dont_show_children_nodes = self.find_opts['dont_show_children_nodes'] if self.find_opts.get('dont_show_children_nodes') is not None else False self.opts['dont_show_children_nodes'] = dont_show_children_nodes tree_struct = {} for node in results: path = node['path'] for n,p in enumerate(path): pcopy = p.copy() pname = p['name'] if pname == './': if tree_struct: continue tree_struct = pcopy tree_struct['children'] = [] continue parent = path[n-1] found, children = self.find_children(tree_struct, parent['abs_path']) if not found: raise Exception('Bug!!!') if p['abs_path'] in [c['abs_path'] for c in children]: continue islastpath = True if (n== len(path)-1) else False if not islastpath: children.append(pcopy) else : children.append(node) # key size is lost in preceding code!!!!!!!!!!!! self.compute_aggregate_recursively(tree_struct) return tree_struct def reset(self, new_item_name, new_opts): self.find_opts = new_opts self.results = [] self.item_name = new_item_name print('Regexp: %s' % (new_item_name,)) try: self.re_item_name = re.compile(r'^%s$' % (new_item_name,)) except re.error: raise Exception('Can\'t compile regexp %s, exit' % (new_item_name,)) self.json_tree_find = {} def print(self, item_name='', opts={}): if not item_name and not self.item_name: print('Please use a valid search string') return if item_name != self.item_name or self.find_opts != opts: self.reset(item_name, opts) self.json_tree_find = self.find_tree_struct() if not self.json_tree_find: print('No results') return print(self.tree_from_struct(self.json_tree_find)) def find(self, item_name, opts={}): ''' @param item_name the string to search in the tree @param opts dict for the find option ''' return self.print(item_name, opts=opts)