From 49dd45e84c33d0f3a2a43f15b701ad298858e07d Mon Sep 17 00:00:00 2001 From: Matthew Walker Date: Tue, 16 Aug 2022 22:17:30 +1000 Subject: [PATCH] Add --raw-size (-s) option to print raw size When used the raw size in bytes will be printed, rather than a summary in human readable form. --- catcli/catcli.py | 16 ++++++++----- catcli/noder.py | 59 ++++++++++++++++++++++++++-------------------- catcli/utils.py | 6 ++--- tests/test_find.py | 2 +- tests/test_ls.py | 3 ++- tests/test_rm.py | 3 ++- tests/test_tree.py | 1 + 7 files changed, 53 insertions(+), 37 deletions(-) diff --git a/catcli/catcli.py b/catcli/catcli.py index ac39a23..2c9aa62 100755 --- a/catcli/catcli.py +++ b/catcli/catcli.py @@ -36,9 +36,9 @@ USAGE = """ {0} Usage: - {1} ls [--catalog=] [--format=] [-aBCrVS] [] - {1} find [--catalog=] [--format=] [-aBCbdVP] [--path=] - {1} tree [--catalog=] [--format=] [-aBCVSH] [] + {1} ls [--catalog=] [--format=] [-aBCrVSs] [] + {1} find [--catalog=] [--format=] [-aBCbdVsP] [--path=] + {1} tree [--catalog=] [--format=] [-aBCVSsH] [] {1} index [--catalog=] [--meta=...] [-aBCcfnV] {1} update [--catalog=] [-aBCcfnV] [--lpath=] {1} rm [--catalog=] [-BCfV] @@ -67,6 +67,7 @@ Options: -P --parent Ignore stored relpath [default: True]. -p --path= Start path. -r --recursive Recursive [default: False]. + -s --raw-size Print raw size rather than human readable [default: False]. -S --sortsize Sort by size, largest first [default: False]. -V --verbose Be verbose [default: False]. -v --version Show version. @@ -148,7 +149,8 @@ def cmd_ls(args, noder, top): path += WILD found = noder.walk(top, path, rec=args['--recursive'], - fmt=args['--format']) + fmt=args['--format'], + raw=args['--raw-size']) if not found: Logger.err('\"{}\": nothing found'.format(args[''])) return found @@ -171,15 +173,17 @@ def cmd_find(args, noder, top): directory = args['--directory'] startpath = args['--path'] fmt = args['--format'] + raw = args['--raw-size'] return noder.find_name(top, args[''], script=args['--script'], startpath=startpath, directory=directory, - parentfromtree=fromtree, fmt=fmt) + parentfromtree=fromtree, fmt=fmt, raw=raw) def cmd_tree(args, noder, top): path = args[''] fmt = args['--format'] hdr = args['--header'] + raw = args['--raw-size'] # find node to start with node = top @@ -188,7 +192,7 @@ def cmd_tree(args, noder, top): if node: # print the tree - noder.print_tree(node, fmt=fmt, header=hdr) + noder.print_tree(node, fmt=fmt, header=hdr, raw=raw) def cmd_graph(args, noder, top): diff --git a/catcli/noder.py b/catcli/noder.py index 7d0d112..4997b9c 100644 --- a/catcli/noder.py +++ b/catcli/noder.py @@ -283,10 +283,12 @@ class Noder: ############################################################### # printing ############################################################### - def _node_to_csv(self, node, sep=','): + def _node_to_csv(self, node, sep=',', raw=False): ''' print a node to csv @node: the node to consider + @sep: CSV separator character + @raw: print raw size rather than human readable ''' if not node: return '' @@ -300,13 +302,15 @@ class Noder: out.append(node.type) # type out.append('') # fake full path sz = self._rec_size(node, store=False) - out.append(utils.human(sz)) # size + out.append(utils.size_to_str(sz, raw=raw)) # size out.append(utils.epoch_to_str(node.ts)) # indexed_at out.append('') # fake maccess out.append('') # fake md5 out.append(str(len(node.children))) # nbfiles - out.append(utils.human(node.free)) # fake free_space - out.append(utils.human(node.total)) # fake total_space + # fake free_space + out.append(utils.size_to_str(node.free, raw=raw)) + # fake total_space + out.append(utils.size_to_str(node.total, raw=raw)) out.append(node.attr) # meta else: # handle other nodes @@ -317,7 +321,7 @@ class Noder: fullpath = os.path.join(storage.name, parents) out.append(fullpath.replace('"', '""')) # full path - out.append(utils.human(node.size)) # size + out.append(utils.size_to_str(node.size, raw=raw)) # size out.append(utils.epoch_to_str(storage.ts)) # indexed_at if self._has_attr(node, 'maccess'): out.append(utils.epoch_to_str(node.maccess)) # maccess @@ -341,7 +345,7 @@ class Noder: def _print_node(self, node, pre='', withpath=False, withdepth=False, withstorage=False, - recalcparent=False): + recalcparent=False, raw=False): ''' print a node @node: the node to print @@ -350,6 +354,7 @@ class Noder: @withdepth: print the node depth info @withstorage: print the node storage it belongs to @recalcparent: get relpath from tree instead of relpath field + @raw: print raw size rather than human readable ''' if node.type == self.TYPE_TOP: # top node @@ -368,7 +373,8 @@ class Noder: attr = '' if node.md5: attr = ', md5:{}'.format(node.md5) - compl = 'size:{}{}'.format(utils.human(node.size), attr) + sz = utils.size_to_str(node.size, raw=raw) + compl = 'size:{}{}'.format(sz, attr) if withstorage: compl += ', storage:{}'.format(Logger.bold(storage.name)) Logger.file(pre, name, compl) @@ -388,14 +394,14 @@ class Noder: storage = self._get_storage(node) attr = [] if node.size: - attr.append(['totsize', utils.human(node.size)]) + attr.append(['totsize', utils.size_to_str(node.size, raw=raw)]) if withstorage: attr.append(['storage', Logger.bold(storage.name)]) Logger.dir(pre, name, depth=depth, attr=attr) elif node.type == self.TYPE_STORAGE: # node of type storage - hf = utils.human(node.free) - ht = utils.human(node.total) + hf = utils.size_to_str(node.free, raw=raw) + ht = utils.size_to_str(node.total, raw=raw) nbchildren = len(node.children) freepercent = '{:.1f}%'.format( node.free * 100 / node.total @@ -408,7 +414,7 @@ class Noder: ds = '' # the children size sz = self._rec_size(node, store=False) - sz = utils.human(sz) + sz = utils.size_to_str(sz, raw=raw) ds = 'totsize:' + '{}'.format(sz) # format the output name = '{}'.format(node.name) @@ -430,28 +436,29 @@ class Noder: Logger.err('bad node encountered: {}'.format(node)) def print_tree(self, node, style=anytree.ContRoundStyle(), - fmt='native', header=False): + fmt='native', header=False, raw=False): ''' print the tree similar to unix tool "tree" @node: start node @style: when fmt=native, defines the tree style @fmt: output format @header: when fmt=csv, print the header + @raw: print the raw size rather than human readable ''' if fmt == 'native': rend = anytree.RenderTree(node, childiter=self._sort_tree) for pre, fill, node in rend: - self._print_node(node, pre=pre, withdepth=True) + self._print_node(node, pre=pre, withdepth=True, raw=raw) elif fmt == 'csv': - self._to_csv(node, with_header=header) + self._to_csv(node, with_header=header, raw=raw) - def _to_csv(self, node, with_header=False): + def _to_csv(self, node, with_header=False, raw=False): '''print the tree to csv''' rend = anytree.RenderTree(node, childiter=self._sort_tree) if with_header: Logger.out(self.CSV_HEADER) for _, _, node in rend: - self._node_to_csv(node) + self._node_to_csv(node, raw=raw) def to_dot(self, node, path='tree.dot'): '''export to dot for graphing''' @@ -465,7 +472,7 @@ class Noder: def find_name(self, root, key, script=False, directory=False, startpath=None, parentfromtree=False, - fmt='native'): + fmt='native', raw=False): ''' find files based on their names @script: output script @@ -494,9 +501,10 @@ class Noder: self._print_node(f, withpath=True, withdepth=True, withstorage=True, - recalcparent=parentfromtree) + recalcparent=parentfromtree, + raw=raw) elif fmt == 'csv': - self._node_to_csv(f) + self._node_to_csv(f, raw=raw) if parentfromtree: paths.append(self._get_parents(f)) @@ -519,7 +527,7 @@ class Noder: ############################################################### # climbing ############################################################### - def walk(self, root, path, rec=False, fmt='native'): + def walk(self, root, path, rec=False, fmt='native', raw=False): ''' walk the tree for ls based on names @root: start node @@ -538,7 +546,7 @@ class Noder: if rec: # print the entire tree - self.print_tree(found[0].parent, fmt=fmt) + self.print_tree(found[0].parent, fmt=fmt, raw=raw) return found # sort found nodes @@ -547,18 +555,19 @@ class Noder: # print the parent if fmt == 'native': self._print_node(found[0].parent, - withpath=False, withdepth=True) + withpath=False, withdepth=True, raw=raw) elif fmt == 'csv': - self._node_to_csv(found[0].parent) + self._node_to_csv(found[0].parent, raw=raw) # print all found nodes for f in found: if fmt == 'native': self._print_node(f, withpath=False, pre='- ', - withdepth=True) + withdepth=True, + raw=raw) elif fmt == 'csv': - self._node_to_csv(f) + self._node_to_csv(f, raw=raw) except anytree.resolver.ChildResolverError: pass diff --git a/catcli/utils.py b/catcli/utils.py index aa41421..fce54e8 100644 --- a/catcli/utils.py +++ b/catcli/utils.py @@ -37,11 +37,11 @@ def md5sum(path): return None -def human(size): - '''human readable size''' +def size_to_str(size, raw=True): + '''convert size to string, optionally human readable''' div = 1024. suf = ['B', 'K', 'M', 'G', 'T', 'P'] - if size < div: + if raw or size < div: return '{}'.format(size) for i in suf: if size < div: diff --git a/tests/test_find.py b/tests/test_find.py index 5daff0a..15d4ff6 100644 --- a/tests/test_find.py +++ b/tests/test_find.py @@ -25,7 +25,7 @@ class TestFind(unittest.TestCase): args = {'': '7544G', '--script': True, '--verbose': True, '--parent': False, '--directory': False, '--path': None, - '--format': 'native'} + '--format': 'native', '--raw-size': False} # try to find something found = cmd_find(args, noder, top) diff --git a/tests/test_ls.py b/tests/test_ls.py index 5446531..a6c0736 100644 --- a/tests/test_ls.py +++ b/tests/test_ls.py @@ -26,7 +26,8 @@ class TestWalking(unittest.TestCase): # create fake args args = {'': '', '--recursive': False, '--verbose': True, - '--format': 'native'} + '--format': 'native', + '--raw-size': False} # list root args[''] = '' diff --git a/tests/test_rm.py b/tests/test_rm.py index 356bc62..0a20dc1 100644 --- a/tests/test_rm.py +++ b/tests/test_rm.py @@ -26,7 +26,8 @@ class TestRm(unittest.TestCase): # create fake args dict args = {'': '', '--recursive': False, '--verbose': True, - '--format': 'native'} + '--format': 'native', + '--raw-size': False} # list files and make sure there are children args[''] = '' diff --git a/tests/test_tree.py b/tests/test_tree.py index 46cfe4f..61fbb2f 100644 --- a/tests/test_tree.py +++ b/tests/test_tree.py @@ -29,6 +29,7 @@ class TestTree(unittest.TestCase): '--verbose': True, '--format': 'native', '--header': False, + '--raw-size': False, } # print tree and wait for any errors