mirror of
https://github.com/deadc0de6/catcli
synced 2024-11-13 07:10:26 +00:00
fix fzf find
This commit is contained in:
parent
f782078c3d
commit
d8a360d3b5
@ -20,6 +20,7 @@ from .catalog import Catalog
|
||||
from .walker import Walker
|
||||
from .noder import Noder
|
||||
from .utils import ask, edit
|
||||
from .exceptions import BadFormatException, CatcliException
|
||||
|
||||
NAME = 'catcli'
|
||||
CUR = os.path.dirname(os.path.abspath(__file__))
|
||||
@ -33,6 +34,7 @@ BANNER = f""" +-+-+-+-+-+-+
|
||||
|c|a|t|c|l|i|
|
||||
+-+-+-+-+-+-+ v{VERSION}"""
|
||||
|
||||
# TODO add grep format for output
|
||||
USAGE = f"""
|
||||
{BANNER}
|
||||
|
||||
@ -155,7 +157,7 @@ def cmd_ls(args, noder, top):
|
||||
|
||||
fmt = args['--format']
|
||||
if fmt.startswith('fzf'):
|
||||
raise Exception('fzf is not supported in ls')
|
||||
raise BadFormatException('fzf is not supported in ls, use find')
|
||||
found = noder.walk(top, path,
|
||||
rec=args['--recursive'],
|
||||
fmt=fmt,
|
||||
@ -188,9 +190,9 @@ def cmd_find(args, noder, top):
|
||||
raw = args['--raw-size']
|
||||
script = args['--script']
|
||||
search_for = args['<term>']
|
||||
return noder.find_name(top, search_for, script=script,
|
||||
startpath=startpath, directory=directory,
|
||||
parentfromtree=fromtree, fmt=fmt, raw=raw)
|
||||
noder.find_name(top, search_for, script=script,
|
||||
startpath=startpath, directory=directory,
|
||||
parentfromtree=fromtree, fmt=fmt, raw=raw)
|
||||
|
||||
|
||||
def cmd_tree(args, noder, top):
|
||||
@ -261,9 +263,9 @@ def print_supported_formats():
|
||||
"""print all supported formats to stdout"""
|
||||
print('"native" : native format')
|
||||
print('"csv" : CSV format')
|
||||
print(f' {Noder.CSV_HEADER}')
|
||||
print('"fzf-native" : fzf with native output for selected entries')
|
||||
print('"fzf-csv" : fzf with native output for selected entries')
|
||||
print(f' {Noder.CSV_HEADER}')
|
||||
print('"fzf-native" : fzf to native (only for find)')
|
||||
print('"fzf-csv" : fzf to csv (only for find)')
|
||||
|
||||
|
||||
def main():
|
||||
@ -331,7 +333,7 @@ def main():
|
||||
cmd_rename(args, catalog, top)
|
||||
elif args['edit']:
|
||||
cmd_edit(args, noder, catalog, top)
|
||||
except Exception as exc:
|
||||
except CatcliException as exc:
|
||||
Logger.out_err('ERROR ' + str(exc))
|
||||
return False
|
||||
|
||||
|
14
catcli/exceptions.py
Normal file
14
catcli/exceptions.py
Normal file
@ -0,0 +1,14 @@
|
||||
"""
|
||||
author: deadc0de6 (https://github.com/deadc0de6)
|
||||
Copyright (c) 2022, deadc0de6
|
||||
|
||||
Catcli exceptions
|
||||
"""
|
||||
|
||||
|
||||
class CatcliException(Exception):
|
||||
"""generic catcli exception"""
|
||||
|
||||
|
||||
class BadFormatException(CatcliException):
|
||||
"""use of bad format"""
|
102
catcli/noder.py
102
catcli/noder.py
@ -402,7 +402,6 @@ class Noder:
|
||||
Logger.dir(pre, name, depth=depth, attr=attr)
|
||||
elif node.type == self.TYPE_STORAGE:
|
||||
# node of type storage
|
||||
szfree = size_to_str(node.free, raw=raw)
|
||||
sztotal = size_to_str(node.total, raw=raw)
|
||||
szused = size_to_str(node.total - node.free, raw=raw)
|
||||
nbchildren = len(node.children)
|
||||
@ -438,7 +437,7 @@ class Noder:
|
||||
else:
|
||||
Logger.err(f'bad node encountered: {node}')
|
||||
|
||||
def print_tree(self, top, node,
|
||||
def print_tree(self, node,
|
||||
fmt='native',
|
||||
raw=False):
|
||||
"""
|
||||
@ -455,14 +454,11 @@ class Noder:
|
||||
self._print_node(thenode, pre=pre, withdepth=True, raw=raw)
|
||||
elif fmt == 'csv':
|
||||
# csv output
|
||||
self._to_csv(node, with_header=header, raw=raw)
|
||||
self._to_csv(node, raw=raw)
|
||||
elif fmt == 'csv-with-header':
|
||||
# csv output
|
||||
Logger.out(self.CSV_HEADER)
|
||||
self._to_csv(node, with_header=header, raw=raw)
|
||||
elif fmt.startswith('fzf'):
|
||||
# flat
|
||||
self._to_fzf(top, node, fmt)
|
||||
self._to_csv(node, raw=raw)
|
||||
|
||||
def _to_csv(self, node, raw=False):
|
||||
"""print the tree to csv"""
|
||||
@ -476,10 +472,9 @@ class Noder:
|
||||
selected = fzf.prompt(strings)
|
||||
return selected
|
||||
|
||||
def _to_fzf(self, top, node, fmt):
|
||||
def _to_fzf(self, node, fmt):
|
||||
"""
|
||||
print node to fzf
|
||||
@top: top node
|
||||
@node: node to start with
|
||||
@fmt: output format for selected nodes
|
||||
"""
|
||||
@ -503,7 +498,7 @@ class Noder:
|
||||
if path not in nodes:
|
||||
continue
|
||||
rend = nodes[path]
|
||||
self.print_tree(top, rend, fmt=subfmt)
|
||||
self.print_tree(rend, fmt=subfmt)
|
||||
|
||||
def to_dot(self, node, path='tree.dot'):
|
||||
"""export to dot for graphing"""
|
||||
@ -529,72 +524,81 @@ class Noder:
|
||||
@fmt: output format
|
||||
@raw: raw size output
|
||||
"""
|
||||
## TODO error with fzf
|
||||
self._debug(f'searching for \"{key}\"')
|
||||
if not key:
|
||||
# nothing to search for
|
||||
return None
|
||||
|
||||
# search for nodes based on path
|
||||
start = top
|
||||
if startpath:
|
||||
start = self.get_node(top, startpath)
|
||||
found = anytree.findall(start, filter_=self._callback_find_name(key))
|
||||
filterfunc = self._callback_find_name(key, directory)
|
||||
found = anytree.findall(start, filter_=filterfunc)
|
||||
nbfound = len(found)
|
||||
self._debug(f'found {nbfound} node(s)')
|
||||
|
||||
# compile found nodes
|
||||
paths = {}
|
||||
nodes = []
|
||||
for item in found:
|
||||
if item.type == self.TYPE_STORAGE:
|
||||
# ignore storage nodes
|
||||
continue
|
||||
if directory and item.type != self.TYPE_DIR:
|
||||
# ignore non directory
|
||||
continue
|
||||
nodes.append(item)
|
||||
|
||||
item = self._sanitize(item)
|
||||
if parentfromtree:
|
||||
paths[self._get_parents(item)] = item
|
||||
else:
|
||||
paths[item.relpath] = item
|
||||
|
||||
if fmt == 'native':
|
||||
for item in nodes:
|
||||
self._print_node(item, withpath=True,
|
||||
withdepth=True,
|
||||
withstorage=True,
|
||||
recalcparent=parentfromtree,
|
||||
raw=raw)
|
||||
elif fmt.startswith('csv'):
|
||||
if fmt == 'csv-with-header':
|
||||
Logger.out(self.CSV_HEADER)
|
||||
for item in nodes:
|
||||
self._node_to_csv(item, raw=raw)
|
||||
|
||||
elif fmt.startswith('fzf'):
|
||||
selected = self._fzf_prompt(paths)
|
||||
# handle fzf mode
|
||||
if fmt.startswith('fzf'):
|
||||
selected = self._fzf_prompt(paths.keys())
|
||||
newpaths = {}
|
||||
subfmt = fmt.replace('fzf-', '')
|
||||
for item in selected:
|
||||
if item not in paths:
|
||||
continue
|
||||
newpaths[item] = paths[item]
|
||||
self.print_tree(top, newpaths[item], fmt=subfmt)
|
||||
self.print_tree(newpaths[item], fmt=subfmt)
|
||||
paths = newpaths
|
||||
else:
|
||||
if fmt == 'native':
|
||||
for _, item in paths.items():
|
||||
self._print_node(item, withpath=True,
|
||||
withdepth=True,
|
||||
withstorage=True,
|
||||
recalcparent=parentfromtree,
|
||||
raw=raw)
|
||||
elif fmt.startswith('csv'):
|
||||
if fmt == 'csv-with-header':
|
||||
Logger.out(self.CSV_HEADER)
|
||||
for _, item in paths.items():
|
||||
self._node_to_csv(item, raw=raw)
|
||||
|
||||
# execute script if any
|
||||
if script:
|
||||
tmp = ['${source}/' + x for x in paths]
|
||||
tmpstr = ' '.join(tmp)
|
||||
cmd = f'op=file; source=/media/mnt; $op {tmpstr}'
|
||||
Logger.info(cmd)
|
||||
|
||||
return found
|
||||
|
||||
def _callback_find_name(self, term):
|
||||
def _callback_find_name(self, term, directory):
|
||||
"""callback for finding files"""
|
||||
def find_name(node):
|
||||
if node.type == self.TYPE_STORAGE:
|
||||
# ignore storage nodes
|
||||
return False
|
||||
if node.type == self.TYPE_TOP:
|
||||
# ignore top nodes
|
||||
return False
|
||||
if node.type == self.TYPE_META:
|
||||
# ignore meta nodes
|
||||
return False
|
||||
if directory and node.type != self.TYPE_DIR:
|
||||
# ignore non directory
|
||||
return False
|
||||
|
||||
# filter
|
||||
if not term:
|
||||
return True
|
||||
if term.lower() in node.name.lower():
|
||||
return True
|
||||
|
||||
# ignore
|
||||
return False
|
||||
return find_name
|
||||
|
||||
@ -623,7 +627,7 @@ class Noder:
|
||||
|
||||
if rec:
|
||||
# print the entire tree
|
||||
self.print_tree(top, found[0].parent, fmt=fmt, raw=raw)
|
||||
self.print_tree(found[0].parent, fmt=fmt, raw=raw)
|
||||
return found
|
||||
|
||||
# sort found nodes
|
||||
@ -650,7 +654,7 @@ class Noder:
|
||||
elif fmt.startswith('csv'):
|
||||
self._node_to_csv(item, raw=raw)
|
||||
elif fmt.startswith('fzf'):
|
||||
self._to_fzf(top, item, fmt)
|
||||
self._to_fzf(item, fmt)
|
||||
|
||||
except anytree.resolver.ChildResolverError:
|
||||
pass
|
||||
@ -732,6 +736,14 @@ class Noder:
|
||||
"""return md5 hash of node"""
|
||||
return md5sum(path)
|
||||
|
||||
def _sanitize(self, node):
|
||||
"""sanitize node string"""
|
||||
node.name = node.name.encode('utf-8',
|
||||
errors='ignore').decode('utf-8')
|
||||
node.relpath = node.relpath.encode('utf-8',
|
||||
errors='ignore').decode('utf-8')
|
||||
return node
|
||||
|
||||
def _debug(self, string):
|
||||
"""print debug"""
|
||||
if not self.debug:
|
||||
|
@ -78,7 +78,7 @@ class TestUpdate(unittest.TestCase):
|
||||
self.assertTrue(nod.md5 == f4_md5)
|
||||
|
||||
# print catalog
|
||||
noder.print_tree(top, top)
|
||||
noder.print_tree(top)
|
||||
|
||||
# add some files and directories
|
||||
new1 = create_rnd_file(dir1, 'newf1')
|
||||
@ -120,7 +120,7 @@ class TestUpdate(unittest.TestCase):
|
||||
|
||||
# print catalog
|
||||
# print(read_from_file(catalogpath))
|
||||
noder.print_tree(top, top)
|
||||
noder.print_tree(top)
|
||||
|
||||
# explore the top node to find all nodes
|
||||
self.assertTrue(len(top.children) == 1)
|
||||
|
Loading…
Reference in New Issue
Block a user