linting and f-string

pull/29/head
deadc0de6 2 years ago
parent 2176ac6127
commit cf3e465525

@ -54,11 +54,11 @@ class Catalog:
if d and not os.path.exists(d): if d and not os.path.exists(d):
os.makedirs(d) os.makedirs(d)
elif os.path.exists(self.path) and not self.force: elif os.path.exists(self.path) and not self.force:
if not utils.ask('Update catalog \"{}\"'.format(self.path)): if not utils.ask(f'Update catalog \"{self.path}\"'):
Logger.info('Catalog not saved') Logger.info('Catalog not saved')
return False return False
if d and not os.path.exists(d): if d and not os.path.exists(d):
Logger.err('Cannot write to \"{}\"'.format(d)) Logger.err(f'Cannot write to \"{d}\"')
return False return False
if self.metanode: if self.metanode:
self.metanode.parent = node self.metanode.parent = node
@ -74,13 +74,13 @@ class Catalog:
def _save_pickle(self, node): def _save_pickle(self, node):
'''pickle the catalog''' '''pickle the catalog'''
pickle.dump(node, open(self.path, 'wb')) pickle.dump(node, open(self.path, 'wb'))
self._debug('Catalog saved to pickle \"{}\"'.format(self.path)) self._debug(f'Catalog saved to pickle \"{self.path}\"')
return True return True
def _restore_pickle(self): def _restore_pickle(self):
'''restore the pickled tree''' '''restore the pickled tree'''
root = pickle.load(open(self.path, 'rb')) root = pickle.load(open(self.path, 'rb'))
m = 'Catalog imported from pickle \"{}\"'.format(self.path) m = f'Catalog imported from pickle \"{self.path}\"'
self._debug(m) self._debug(m)
return root return root
@ -89,12 +89,12 @@ class Catalog:
exp = JsonExporter(indent=2, sort_keys=True) exp = JsonExporter(indent=2, sort_keys=True)
with open(self.path, 'w') as f: with open(self.path, 'w') as f:
exp.write(node, f) exp.write(node, f)
self._debug('Catalog saved to json \"{}\"'.format(self.path)) self._debug(f'Catalog saved to json \"{self.path}\"')
return True return True
def _restore_json(self, string): def _restore_json(self, string):
'''restore the tree from json''' '''restore the tree from json'''
imp = JsonImporter() imp = JsonImporter()
root = imp.import_(string) root = imp.import_(string)
self._debug('Catalog imported from json \"{}\"'.format(self.path)) self._debug(f'Catalog imported from json \"{self.path}\"')
return root return root

@ -23,36 +23,36 @@ from .utils import ask, edit
NAME = 'catcli' NAME = 'catcli'
CUR = os.path.dirname(os.path.abspath(__file__)) CUR = os.path.dirname(os.path.abspath(__file__))
CATALOGPATH = '{}.catalog'.format(NAME) CATALOGPATH = f'{NAME}.catalog'
GRAPHPATH = '/tmp/{}.dot'.format(NAME) GRAPHPATH = f'/tmp/{NAME}.dot'
SEPARATOR = '/' SEPARATOR = '/'
WILD = '*' WILD = '*'
FORMATS = ['native', 'csv', 'fzf-native', 'fzf-csv'] FORMATS = ['native', 'csv', 'fzf-native', 'fzf-csv']
BANNER = """ +-+-+-+-+-+-+ BANNER = f""" +-+-+-+-+-+-+
|c|a|t|c|l|i| |c|a|t|c|l|i|
+-+-+-+-+-+-+ v{}""".format(VERSION) +-+-+-+-+-+-+ v{VERSION}"""
USAGE = """ USAGE = f"""
{0} {BANNER}
Usage: Usage:
{1} ls [--catalog=<path>] [--format=<fmt>] [-aBCrVSs] [<path>] {NAME} ls [--catalog=<path>] [--format=<fmt>] [-aBCrVSs] [<path>]
{1} find [--catalog=<path>] [--format=<fmt>] [-aBCbdVsP] [--path=<path>] [<term>] {NAME} find [--catalog=<path>] [--format=<fmt>] [-aBCbdVsP] [--path=<path>] [<term>]
{1} tree [--catalog=<path>] [-aBCVSsH] [<path>] {NAME} tree [--catalog=<path>] [-aBCVSsH] [<path>]
{1} index [--catalog=<path>] [--meta=<meta>...] [-aBCcfnV] <name> <path> {NAME} index [--catalog=<path>] [--meta=<meta>...] [-aBCcfnV] <name> <path>
{1} update [--catalog=<path>] [-aBCcfnV] [--lpath=<path>] <name> <path> {NAME} update [--catalog=<path>] [-aBCcfnV] [--lpath=<path>] <name> <path>
{1} rm [--catalog=<path>] [-BCfV] <storage> {NAME} rm [--catalog=<path>] [-BCfV] <storage>
{1} rename [--catalog=<path>] [-BCfV] <storage> <name> {NAME} rename [--catalog=<path>] [-BCfV] <storage> <name>
{1} edit [--catalog=<path>] [-BCfV] <storage> {NAME} edit [--catalog=<path>] [-BCfV] <storage>
{1} graph [--catalog=<path>] [-BCV] [<path>] {NAME} graph [--catalog=<path>] [-BCV] [<path>]
{1} print_supported_formats {NAME} print_supported_formats
{1} help {NAME} help
{1} --help {NAME} --help
{1} --version {NAME} --version
Options: Options:
--catalog=<path> Path to the catalog [default: {2}]. --catalog=<path> Path to the catalog [default: {CATALOGPATH}].
--meta=<meta> Additional attribute to store [default: ]. --meta=<meta> Additional attribute to store [default: ].
-a --archive Handle archive file [default: False]. -a --archive Handle archive file [default: False].
-B --no-banner Do not display the banner [default: False]. -B --no-banner Do not display the banner [default: False].
@ -73,7 +73,7 @@ Options:
-V --verbose Be verbose [default: False]. -V --verbose Be verbose [default: False].
-v --version Show version. -v --version Show version.
-h --help Show this screen. -h --help Show this screen.
""".format(BANNER, NAME, CATALOGPATH) # nopep8 """ # nopep8
def cmd_index(args, noder, catalog, top): def cmd_index(args, noder, catalog, top):
@ -83,12 +83,12 @@ def cmd_index(args, noder, catalog, top):
debug = args['--verbose'] debug = args['--verbose']
subsize = not args['--no-subsize'] subsize = not args['--no-subsize']
if not os.path.exists(path): if not os.path.exists(path):
Logger.err('\"{}\" does not exist'.format(path)) Logger.err(f'\"{path}\" does not exist')
return return
if name in noder.get_storage_names(top): if name in noder.get_storage_names(top):
try: try:
if not ask('Overwrite storage \"{}\"'.format(name)): if not ask(f'Overwrite storage \"{name}\"'):
Logger.err('storage named \"{}\" already exist'.format(name)) Logger.err(f'storage named \"{name}\" already exist')
return return
except KeyboardInterrupt: except KeyboardInterrupt:
Logger.err('aborted') Logger.err('aborted')
@ -104,7 +104,8 @@ def cmd_index(args, noder, catalog, top):
if subsize: if subsize:
noder.rec_size(root) noder.rec_size(root)
stop = datetime.datetime.now() stop = datetime.datetime.now()
Logger.info('Indexed {} file(s) in {}'.format(cnt, stop - start)) diff = stop - start
Logger.info(f'Indexed {cnt} file(s) in {diff}')
if cnt > 0: if cnt > 0:
catalog.save(top) catalog.save(top)
@ -117,11 +118,11 @@ def cmd_update(args, noder, catalog, top):
debug = args['--verbose'] debug = args['--verbose']
subsize = not args['--no-subsize'] subsize = not args['--no-subsize']
if not os.path.exists(path): if not os.path.exists(path):
Logger.err('\"{}\" does not exist'.format(path)) Logger.err(f'\"{path}\" does not exist')
return return
root = noder.get_storage_node(top, name, path=path) root = noder.get_storage_node(top, name, path=path)
if not root: if not root:
Logger.err('storage named \"{}\" does not exist'.format(name)) Logger.err(f'storage named \"{name}\" does not exist')
return return
start = datetime.datetime.now() start = datetime.datetime.now()
walker = Walker(noder, hash=hash, debug=debug, walker = Walker(noder, hash=hash, debug=debug,
@ -130,7 +131,8 @@ def cmd_update(args, noder, catalog, top):
if subsize: if subsize:
noder.rec_size(root) noder.rec_size(root)
stop = datetime.datetime.now() stop = datetime.datetime.now()
Logger.info('updated {} file(s) in {}'.format(cnt, stop - start)) diff = stop - start
Logger.info(f'updated {cnt} file(s) in {diff}')
if cnt > 0: if cnt > 0:
catalog.save(top) catalog.save(top)
@ -141,7 +143,7 @@ def cmd_ls(args, noder, top):
path = SEPARATOR path = SEPARATOR
if not path.startswith(SEPARATOR): if not path.startswith(SEPARATOR):
path = SEPARATOR + path path = SEPARATOR + path
pre = '{}{}'.format(SEPARATOR, noder.TOPNAME) pre = f'{SEPARATOR}{noder.TOPNAME}'
if not path.startswith(pre): if not path.startswith(pre):
path = pre + path path = pre + path
if not path.endswith(SEPARATOR): if not path.endswith(SEPARATOR):
@ -153,7 +155,8 @@ def cmd_ls(args, noder, top):
fmt=args['--format'], fmt=args['--format'],
raw=args['--raw-size']) raw=args['--raw-size'])
if not found: if not found:
Logger.err('\"{}\": nothing found'.format(args['<path>'])) path = args['<path>']
Logger.err(f'\"{path}\": nothing found')
return found return found
@ -163,9 +166,9 @@ def cmd_rm(args, noder, catalog, top):
if node: if node:
node.parent = None node.parent = None
if catalog.save(top): if catalog.save(top):
Logger.info('Storage \"{}\" removed'.format(name)) Logger.info(f'Storage \"{name}\" removed')
else: else:
Logger.err('Storage named \"{}\" does not exist'.format(name)) Logger.err(f'Storage named \"{name}\" does not exist')
return top return top
@ -202,7 +205,7 @@ def cmd_graph(args, noder, top):
if not path: if not path:
path = GRAPHPATH path = GRAPHPATH
cmd = noder.to_dot(top, path) cmd = noder.to_dot(top, path)
Logger.info('create graph with \"{}\" (you need graphviz)'.format(cmd)) Logger.info(f'create graph with \"{cmd}\" (you need graphviz)')
def cmd_rename(args, noder, catalog, top): def cmd_rename(args, noder, catalog, top):
@ -213,10 +216,10 @@ def cmd_rename(args, noder, catalog, top):
node = next(filter(lambda x: x.name == storage, top.children)) node = next(filter(lambda x: x.name == storage, top.children))
node.name = new node.name = new
if catalog.save(top): if catalog.save(top):
m = 'Storage \"{}\" renamed to \"{}\"'.format(storage, new) m = f'Storage \"{storage}\" renamed to \"{new}\"'
Logger.info(m) Logger.info(m)
else: else:
Logger.err('Storage named \"{}\" does not exist'.format(storage)) Logger.err(f'Storage named \"{storage}\" does not exist')
return top return top
@ -231,9 +234,9 @@ def cmd_edit(args, noder, catalog, top):
new = edit(attr) new = edit(attr)
node.attr = noder.format_storage_attr(new) node.attr = noder.format_storage_attr(new)
if catalog.save(top): if catalog.save(top):
Logger.info('Storage \"{}\" edited'.format(storage)) Logger.info(f'Storage \"{storage}\" edited')
else: else:
Logger.err('Storage named \"{}\" does not exist'.format(storage)) Logger.err(f'Storage named \"{storage}\" does not exist')
return top return top
@ -245,7 +248,7 @@ def banner():
def print_supported_formats(): def print_supported_formats():
print('"native" : native format') print('"native" : native format')
print('"csv" : CSV format') print('"csv" : CSV format')
print(' {}'.format(Noder.CSV_HEADER)) print(f' {Noder.CSV_HEADER}')
print('"fzf-native" : fzf with native output for selected entries') print('"fzf-native" : fzf with native output for selected entries')
print('"fzf-csv" : fzf with native output for selected entries') print('"fzf-csv" : fzf with native output for selected entries')
@ -264,7 +267,7 @@ def main():
# check format # check format
fmt = args['--format'] fmt = args['--format']
if fmt not in FORMATS: if fmt not in FORMATS:
Logger.err('bad format: {}'.format(fmt)) Logger.err(f'bad format: {fmt}')
print_supported_formats() print_supported_formats()
return False return False

@ -49,40 +49,38 @@ class Logger:
'''print a storage node''' '''print a storage node'''
end = '' end = ''
if attr: if attr:
end = ' {}({}){}'.format(Logger.GRAY, attr, Logger.RESET) end = f' {Logger.GRAY}({attr}){Logger.RESET}'
s = '{}{}{}{}:'.format(pre, Logger.UND, Logger.STORAGE, Logger.RESET) s = f'{pre}{Logger.UND}{Logger.STORAGE}{Logger.RESET}:'
s += ' {}{}{}{}\n'.format(Logger.PURPLE, s += ' ' + Logger.PURPLE + Logger.fix_badchars(name) + \
Logger.fix_badchars(name), Logger.RESET + end + '\n'
Logger.RESET, end) s += f' {Logger.GRAY}{args}{Logger.RESET}'
s += ' {}{}{}'.format(Logger.GRAY, args, Logger.RESET) sys.stdout.write(f'{s}\n')
sys.stdout.write('{}\n'.format(s))
def file(pre, name, attr): def file(pre, name, attr):
'''print a file node''' '''print a file node'''
s = '{}{}'.format(pre, Logger.fix_badchars(name)) nobad = Logger.fix_badchars(name)
s += ' {}[{}]{}'.format(Logger.GRAY, attr, Logger.RESET) s = f'{pre}{nobad}'
sys.stdout.write('{}\n'.format(s)) s += f' {Logger.GRAY}[{attr}]{Logger.RESET}'
sys.stdout.write(f'{s}\n')
def dir(pre, name, depth='', attr=None): def dir(pre, name, depth='', attr=None):
'''print a directory node''' '''print a directory node'''
end = [] end = []
if depth != '': if depth != '':
end.append('{}:{}'.format(Logger.NBFILES, depth)) end.append(f'{Logger.NBFILES}:{depth}')
if attr: if attr:
end.append(' '.join(['{}:{}'.format(x, y) for x, y in attr])) end.append(' '.join([f'{x}:{y}' for x, y in attr]))
if end: if end:
end = ' [{}]'.format(', '.join(end)) endstring = ', '.join(end)
s = '{}{}{}{}'.format(pre, Logger.BLUE, end = f' [{endstring}]'
Logger.fix_badchars(name), Logger.RESET) s = pre + Logger.BLUE + Logger.fix_badchars(name) + Logger.RESET
s += '{}{}{}'.format(Logger.GRAY, end, Logger.RESET) s += f'{Logger.GRAY}{end}{Logger.RESET}'
sys.stdout.write('{}\n'.format(s)) sys.stdout.write(f'{s}\n')
def arc(pre, name, archive): def arc(pre, name, archive):
s = '{}{}{}{}'.format(pre, Logger.YELLOW, s = pre + Logger.YELLOW + Logger.fix_badchars(name) + Logger.RESET
Logger.fix_badchars(name), Logger.RESET) s += f' {Logger.GRAY}[{Logger.ARCHIVE}:{archive}]{Logger.RESET}'
s += ' {}[{}:{}]{}'.format(Logger.GRAY, Logger.ARCHIVE, sys.stdout.write(f'{s}\n')
archive, Logger.RESET)
sys.stdout.write('{}\n'.format(s))
###################################################################### ######################################################################
# generic output # generic output
@ -90,40 +88,40 @@ class Logger:
def out(string): def out(string):
'''to stdout no color''' '''to stdout no color'''
string = Logger.fix_badchars(string) string = Logger.fix_badchars(string)
sys.stdout.write('{}\n'.format(string)) sys.stdout.write(f'{string}\n')
def out_err(string): def out_err(string):
'''to stderr no color''' '''to stderr no color'''
string = Logger.fix_badchars(string) string = Logger.fix_badchars(string)
sys.stderr.write('{}\n'.format(string)) sys.stderr.write(f'{string}\n')
def debug(string): def debug(string):
'''to stderr no color''' '''to stderr no color'''
string = Logger.fix_badchars(string) string = Logger.fix_badchars(string)
sys.stderr.write('[DBG] {}\n'.format(string)) sys.stderr.write(f'[DBG] {string}\n')
def info(string): def info(string):
'''to stdout in color''' '''to stdout in color'''
string = Logger.fix_badchars(string) string = Logger.fix_badchars(string)
s = '{}{}{}'.format(Logger.MAGENTA, string, Logger.RESET) s = f'{Logger.MAGENTA}{string}{Logger.RESET}'
sys.stdout.write('{}\n'.format(s)) sys.stdout.write(f'{s}\n')
def err(string): def err(string):
'''to stderr in RED''' '''to stderr in RED'''
string = Logger.fix_badchars(string) string = Logger.fix_badchars(string)
s = '{}{}{}'.format(Logger.RED, string, Logger.RESET) s = f'{Logger.RED}{string}{Logger.RESET}'
sys.stderr.write('{}\n'.format(s)) sys.stderr.write(f'{s}\n')
def progr(string): def progr(string):
'''print progress''' '''print progress'''
string = Logger.fix_badchars(string) string = Logger.fix_badchars(string)
sys.stderr.write('{}\r'.format(string)) sys.stderr.write(f'{string}\r')
sys.stderr.flush() sys.stderr.flush()
def bold(string): def bold(string):
'''make it bold''' '''make it bold'''
string = Logger.fix_badchars(string) string = Logger.fix_badchars(string)
return '{}{}{}'.format(Logger.BOLD, string, Logger.RESET) return f'{Logger.BOLD}{string}{Logger.RESET}'
def flog(path, string, append=True): def flog(path, string, append=True):
string = Logger.fix_badchars(string) string = Logger.fix_badchars(string)

@ -6,16 +6,16 @@ Class that represents a node in the catalog tree
""" """
import os import os
import anytree
import shutil import shutil
import time import time
import anytree
from pyfzf.pyfzf import FzfPrompt from pyfzf.pyfzf import FzfPrompt
# local imports # local imports
from . import __version__ as VERSION
import catcli.utils as utils import catcli.utils as utils
from catcli.logger import Logger from catcli.logger import Logger
from catcli.decomp import Decomp from catcli.decomp import Decomp
from . import __version__ as VERSION
''' '''
There are 4 types of node: There are 4 types of node:
@ -83,7 +83,7 @@ class Noder:
return r.get(top, p) return r.get(top, p)
except anytree.resolver.ChildResolverError: except anytree.resolver.ChildResolverError:
if not quiet: if not quiet:
Logger.err('No node at path \"{}\"'.format(p)) Logger.err(f'No node at path \"{p}\"')
return None return None
def get_node_if_changed(self, top, path, treepath): def get_node_if_changed(self, top, path, treepath):
@ -110,16 +110,16 @@ class Noder:
# maccess changed # maccess changed
old_maccess = node.maccess old_maccess = node.maccess
if float(maccess) != float(old_maccess): if float(maccess) != float(old_maccess):
self._debug('\tchange: maccess changed for \"{}\"'.format(path)) self._debug(f'\tchange: maccess changed for \"{path}\"')
return node, True return node, True
# test hash # test hash
if self.hash and node.md5: if self.hash and node.md5:
md5 = self._get_hash(path) md5 = self._get_hash(path)
if md5 != node.md5: if md5 != node.md5:
m = '\tchange: checksum changed for \"{}\"'.format(path) m = f'\tchange: checksum changed for \"{path}\"'
self._debug(m) self._debug(m)
return node, True return node, True
self._debug('\tchange: no change for \"{}\"'.format(path)) self._debug(f'\tchange: no change for \"{path}\"')
return node, False return node, False
def _rec_size(self, node, store=True): def _rec_size(self, node, store=True):
@ -128,9 +128,9 @@ class Noder:
@store: store the size in the node @store: store the size in the node
''' '''
if node.type == self.TYPE_FILE: if node.type == self.TYPE_FILE:
self._debug('getting node size for \"{}\"'.format(node.name)) self._debug(f'getting node size for \"{node.name}\"')
return node.size return node.size
m = 'getting node size recursively for \"{}\"'.format(node.name) m = f'getting node size recursively for \"{node.name}\"'
self._debug(m) self._debug(m)
size = 0 size = 0
for i in node.children: for i in node.children:
@ -202,13 +202,13 @@ class Noder:
def file_node(self, name, path, parent, storagepath): def file_node(self, name, path, parent, storagepath):
'''create a new node representing a file''' '''create a new node representing a file'''
if not os.path.exists(path): if not os.path.exists(path):
Logger.err('File \"{}\" does not exist'.format(path)) Logger.err(f'File \"{path}\" does not exist')
return None return None
path = os.path.abspath(path) path = os.path.abspath(path)
try: try:
st = os.lstat(path) st = os.lstat(path)
except OSError as e: except OSError as e:
Logger.err('OSError: {}'.format(e)) Logger.err(f'OSError: {e}')
return None return None
md5 = None md5 = None
if self.hash: if self.hash:
@ -221,11 +221,11 @@ class Noder:
if self.arc: if self.arc:
ext = os.path.splitext(path)[1][1:] ext = os.path.splitext(path)[1][1:]
if ext.lower() in self.decomp.get_formats(): if ext.lower() in self.decomp.get_formats():
self._debug('{} is an archive'.format(path)) self._debug(f'{path} is an archive')
names = self.decomp.get_names(path) names = self.decomp.get_names(path)
self.list_to_tree(n, names) self.list_to_tree(n, names)
else: else:
self._debug('{} is NOT an archive'.format(path)) self._debug(f'{path} is NOT an archive')
return n return n
def dir_node(self, name, path, parent, storagepath): def dir_node(self, name, path, parent, storagepath):
@ -359,7 +359,7 @@ class Noder:
''' '''
if node.type == self.TYPE_TOP: if node.type == self.TYPE_TOP:
# top node # top node
Logger.out('{}{}'.format(pre, node.name)) Logger.out(f'{pre}{node.name}')
elif node.type == self.TYPE_FILE: elif node.type == self.TYPE_FILE:
# node of type file # node of type file
name = node.name name = node.name
@ -373,11 +373,12 @@ class Noder:
storage = self._get_storage(node) storage = self._get_storage(node)
attr = '' attr = ''
if node.md5: if node.md5:
attr = ', md5:{}'.format(node.md5) attr = f', md5:{node.md5}'
sz = utils.size_to_str(node.size, raw=raw) sz = utils.size_to_str(node.size, raw=raw)
compl = 'size:{}{}'.format(sz, attr) compl = f'size:{sz}{attr}'
if withstorage: if withstorage:
compl += ', storage:{}'.format(Logger.bold(storage.name)) content = Logger.bold(storage.name)
compl += f', storage:{content}'
Logger.file(pre, name, compl) Logger.file(pre, name, compl)
elif node.type == self.TYPE_DIR: elif node.type == self.TYPE_DIR:
# node of type directory # node of type directory
@ -404,37 +405,37 @@ class Noder:
hf = utils.size_to_str(node.free, raw=raw) hf = utils.size_to_str(node.free, raw=raw)
ht = utils.size_to_str(node.total, raw=raw) ht = utils.size_to_str(node.total, raw=raw)
nbchildren = len(node.children) nbchildren = len(node.children)
freepercent = '{:.1f}%'.format( pcent = node.free * 100 / node.total
node.free * 100 / node.total freepercent = f'{pcent:.1f}%'
)
# get the date # get the date
dt = '' dt = ''
if self._has_attr(node, 'ts'): if self._has_attr(node, 'ts'):
dt = 'date:' dt = 'date:'
dt += '{}'.format(utils.epoch_to_str(node.ts)) dt += utils.epoch_to_str(node.ts)
ds = '' ds = ''
# the children size # the children size
sz = self._rec_size(node, store=False) sz = self._rec_size(node, store=False)
sz = utils.size_to_str(sz, raw=raw) sz = utils.size_to_str(sz, raw=raw)
ds = 'totsize:' + '{}'.format(sz) ds = 'totsize:' + f'{sz}'
# format the output # format the output
name = '{}'.format(node.name) name = node.name
args = [ args = [
'nbfiles:' + '{}'.format(nbchildren), 'nbfiles:' + f'{nbchildren}',
ds, ds,
'free:{}'.format(freepercent), f'free:{freepercent}',
'du:' + '{}/{}'.format(hf, ht), 'du:' + f'{hf}/{ht}',
dt] dt]
argsstring = ' | '.join(args)
Logger.storage(pre, Logger.storage(pre,
name, name,
'{}'.format(' | '.join(args)), argsstring,
node.attr) node.attr)
elif node.type == self.TYPE_ARC: elif node.type == self.TYPE_ARC:
# archive node # archive node
if self.arc: if self.arc:
Logger.arc(pre, node.name, node.archive) Logger.arc(pre, node.name, node.archive)
else: else:
Logger.err('bad node encountered: {}'.format(node)) Logger.err(f'bad node encountered: {node}')
def print_tree(self, top, node, style=anytree.ContRoundStyle(), def print_tree(self, top, node, style=anytree.ContRoundStyle(),
fmt='native', header=False, raw=False): fmt='native', header=False, raw=False):
@ -490,7 +491,7 @@ class Noder:
fullpath = os.path.join(storage.name, parents) fullpath = os.path.join(storage.name, parents)
nodes[fullpath] = node nodes[fullpath] = node
# prompt with fzf # prompt with fzf
self._fzf_prompt(nodes.keys()) paths = self._fzf_prompt(nodes.keys())
# print the resulting tree # print the resulting tree
subfmt = fmt.replace('fzf-', '') subfmt = fmt.replace('fzf-', '')
for path in paths: for path in paths:
@ -504,8 +505,8 @@ class Noder:
def to_dot(self, node, path='tree.dot'): def to_dot(self, node, path='tree.dot'):
'''export to dot for graphing''' '''export to dot for graphing'''
anytree.exporter.DotExporter(node).to_dotfile(path) anytree.exporter.DotExporter(node).to_dotfile(path)
Logger.info('dot file created under \"{}\"'.format(path)) Logger.info(f'dot file created under \"{path}\"')
return 'dot {} -T png -o /tmp/tree.png'.format(path) return f'dot {path} -T png -o /tmp/tree.png'
############################################################### ###############################################################
# searching # searching
@ -525,7 +526,7 @@ class Noder:
@fmt: output format @fmt: output format
@raw: raw size output @raw: raw size output
''' '''
self._debug('searching for \"{}\"'.format(key)) self._debug(f'searching for \"{key}\"')
if not key: if not key:
# nothing to search for # nothing to search for
return None return None
@ -533,7 +534,8 @@ class Noder:
if startpath: if startpath:
start = self.get_node(top, startpath) start = self.get_node(top, startpath)
found = anytree.findall(start, filter_=self._callback_find_name(key)) found = anytree.findall(start, filter_=self._callback_find_name(key))
self._debug(f'found {len(found)} node(s)') nb = len(found)
self._debug(f'found {nb} node(s)')
# compile found nodes # compile found nodes
paths = dict() paths = dict()
@ -575,7 +577,8 @@ class Noder:
if script: if script:
tmp = ['${source}/' + x for x in paths.keys()] tmp = ['${source}/' + x for x in paths.keys()]
cmd = 'op=file; source=/media/mnt; $op {}'.format(' '.join(tmp)) tmpstr = ' '.join(tmp)
cmd = f'op=file; source=/media/mnt; $op {tmpstr}'
Logger.info(cmd) Logger.info(cmd)
return found return found
@ -600,7 +603,7 @@ class Noder:
@fmt: output format @fmt: output format
@raw: print raw size @raw: print raw size
''' '''
self._debug('walking path: \"{}\"'.format(path)) self._debug(f'walking path: \"{path}\"')
r = anytree.resolver.Resolver('name') r = anytree.resolver.Resolver('name')
found = [] found = []
@ -676,22 +679,22 @@ class Noder:
'''sorting a list of items''' '''sorting a list of items'''
return sorted(items, key=self._sort, reverse=self.sortsize) return sorted(items, key=self._sort, reverse=self.sortsize)
def _sort(self, x): def _sort(self, lst):
'''sort a list''' '''sort a list'''
if self.sortsize: if self.sortsize:
return self._sort_size(x) return self._sort_size(lst)
return self._sort_fs(x) return self._sort_fs(lst)
def _sort_fs(self, n): def _sort_fs(self, node):
'''sorting nodes dir first and alpha''' '''sorting nodes dir first and alpha'''
return (n.type, n.name.lstrip('\.').lower()) return (node.type, node.name.lstrip('\.').lower())
def _sort_size(self, n): def _sort_size(self, node):
'''sorting nodes by size''' '''sorting nodes by size'''
try: try:
if not n.size: if not node.size:
return 0 return 0
return n.size return node.size
except AttributeError: except AttributeError:
return 0 return 0

@ -19,7 +19,7 @@ def md5sum(path):
'''calculate md5 sum of a file''' '''calculate md5 sum of a file'''
p = os.path.realpath(path) p = os.path.realpath(path)
if not os.path.exists(p): if not os.path.exists(p):
Logger.err('\nmd5sum - file does not exist: {}'.format(p)) Logger.err(f'\nmd5sum - file does not exist: {p}')
return None return None
try: try:
with open(p, mode='rb') as f: with open(p, mode='rb') as f:
@ -33,7 +33,7 @@ def md5sum(path):
except PermissionError: except PermissionError:
pass pass
except OSError as e: except OSError as e:
Logger.err('md5sum error: {}'.format(e)) Logger.err(f'md5sum error: {e}')
return None return None
@ -42,12 +42,13 @@ def size_to_str(size, raw=True):
div = 1024. div = 1024.
suf = ['B', 'K', 'M', 'G', 'T', 'P'] suf = ['B', 'K', 'M', 'G', 'T', 'P']
if raw or size < div: if raw or size < div:
return '{}'.format(size) return f'{size}'
for i in suf: for i in suf:
if size < div: if size < div:
return '{:.1f}{}'.format(size, i) return f'{size:.1f}{i}'
size = size / div size = size / div
return '{:.1f}{}'.format(size, suf[-1]) sufix = suf[-1]
return f'{size:.1f}{sufix}'
def epoch_to_str(epoch): def epoch_to_str(epoch):
@ -61,7 +62,7 @@ def epoch_to_str(epoch):
def ask(question): def ask(question):
'''ask the user what to do''' '''ask the user what to do'''
resp = input('{} [y|N] ? '.format(question)) resp = input(f'{question} [y|N] ? ')
return resp.lower() == 'y' return resp.lower() == 'y'

@ -36,7 +36,7 @@ class Walker:
@parent: parent node @parent: parent node
@name: this stoarge name @name: this stoarge name
''' '''
self._debug('indexing starting at {}'.format(path)) self._debug(f'indexing starting at {path}')
if not parent: if not parent:
parent = self.noder.dir_node(name, path, parent) parent = self.noder.dir_node(name, path, parent)
@ -49,21 +49,21 @@ class Walker:
cnt = 0 cnt = 0
for (root, dirs, files) in os.walk(path): for (root, dirs, files) in os.walk(path):
for f in files: for f in files:
self._debug('found file {} under {}'.format(f, path)) self._debug(f'found file {f} under {path}')
sub = os.path.join(root, f) sub = os.path.join(root, f)
if not os.path.exists(sub): if not os.path.exists(sub):
continue continue
self._progress(f) self._progress(f)
self._debug('index file {}'.format(sub)) self._debug(f'index file {sub}')
n = self.noder.file_node(os.path.basename(f), sub, n = self.noder.file_node(os.path.basename(f), sub,
parent, storagepath) parent, storagepath)
if n: if n:
cnt += 1 cnt += 1
for d in dirs: for d in dirs:
self._debug('found dir {} under {}'.format(d, path)) self._debug(f'found dir {d} under {path}')
base = os.path.basename(d) base = os.path.basename(d)
sub = os.path.join(root, d) sub = os.path.join(root, d)
self._debug('index directory {}'.format(sub)) self._debug(f'index directory {sub}')
if not os.path.exists(sub): if not os.path.exists(sub):
continue continue
dummy = self.noder.dir_node(base, sub, parent, storagepath) dummy = self.noder.dir_node(base, sub, parent, storagepath)
@ -92,35 +92,35 @@ class Walker:
@top: top node (storage) @top: top node (storage)
@storagepath: rel path relative to indexed directory @storagepath: rel path relative to indexed directory
''' '''
self._debug('reindexing starting at {}'.format(path)) self._debug(f'reindexing starting at {path}')
cnt = 0 cnt = 0
for (root, dirs, files) in os.walk(path): for (root, dirs, files) in os.walk(path):
for f in files: for f in files:
self._debug('found file \"{}\" under {}'.format(f, path)) self._debug(f'found file \"{f}\" under {path}')
sub = os.path.join(root, f) sub = os.path.join(root, f)
treepath = os.path.join(storagepath, f) treepath = os.path.join(storagepath, f)
reindex, n = self._need_reindex(parent, sub, treepath) reindex, n = self._need_reindex(parent, sub, treepath)
if not reindex: if not reindex:
self._debug('\tskip file {}'.format(sub)) self._debug(f'\tskip file {sub}')
self.noder.flag(n) self.noder.flag(n)
continue continue
self._log2file('update catalog for \"{}\"'.format(sub)) self._log2file(f'update catalog for \"{sub}\"')
n = self.noder.file_node(os.path.basename(f), sub, n = self.noder.file_node(os.path.basename(f), sub,
parent, storagepath) parent, storagepath)
self.noder.flag(n) self.noder.flag(n)
cnt += 1 cnt += 1
for d in dirs: for d in dirs:
self._debug('found dir \"{}\" under {}'.format(d, path)) self._debug(f'found dir \"{d}\" under {path}')
base = os.path.basename(d) base = os.path.basename(d)
sub = os.path.join(root, d) sub = os.path.join(root, d)
treepath = os.path.join(storagepath, d) treepath = os.path.join(storagepath, d)
reindex, dummy = self._need_reindex(parent, sub, treepath) reindex, dummy = self._need_reindex(parent, sub, treepath)
if reindex: if reindex:
self._log2file('update catalog for \"{}\"'.format(sub)) self._log2file(f'update catalog for \"{sub}\"')
dummy = self.noder.dir_node(base, sub, parent, storagepath) dummy = self.noder.dir_node(base, sub, parent, storagepath)
cnt += 1 cnt += 1
self.noder.flag(dummy) self.noder.flag(dummy)
self._debug('reindexing deeper under {}'.format(sub)) self._debug(f'reindexing deeper under {sub}')
nstoragepath = os.sep.join([storagepath, base]) nstoragepath = os.sep.join([storagepath, base])
if not storagepath: if not storagepath:
nstoragepath = base nstoragepath = base
@ -138,16 +138,16 @@ class Walker:
''' '''
cnode, changed = self.noder.get_node_if_changed(top, path, treepath) cnode, changed = self.noder.get_node_if_changed(top, path, treepath)
if not cnode: if not cnode:
self._debug('\t{} does not exist'.format(path)) self._debug(f'\t{path} does not exist')
return True, cnode return True, cnode
if cnode and not changed: if cnode and not changed:
# ignore this node # ignore this node
self._debug('\t{} has not changed'.format(path)) self._debug(f'\t{path} has not changed')
return False, cnode return False, cnode
if cnode and changed: if cnode and changed:
# remove this node and re-add # remove this node and re-add
self._debug('\t{} has changed'.format(path)) self._debug(f'\t{path} has changed')
self._debug('\tremoving node {} for {}'.format(cnode.name, path)) self._debug(f'\tremoving node {cnode.name} for {path}')
cnode.parent = None cnode.parent = None
return True, cnode return True, cnode
@ -163,15 +163,15 @@ class Walker:
return return
if not string: if not string:
# clean # clean
Logger.progr('{:80}'.format(' ')) Logger.progr(' ' * 80)
return return
if len(string) > self.MAXLINE: if len(string) > self.MAXLINE:
string = string[:self.MAXLINE] + '...' string = string[:self.MAXLINE] + '...'
Logger.progr('indexing: {:80}'.format(string)) Logger.progr(f'indexing: {string:80}')
def _log2file(self, string): def _log2file(self, string):
'''log to file''' '''log to file'''
if not self.lpath: if not self.lpath:
return return
line = '{}\n'.format(string) line = f'{string}\n'
Logger.flog(self.lpath, line, append=True) Logger.flog(self.lpath, line, append=True)

@ -1,6 +1,6 @@
pycodestyle; python_version >= '3.0' pycodestyle; python_version >= '3.0'
pyflakes; python_version >= '3.0' pyflakes; python_version >= '3.0'
#nose-py3; python_version >= '3.0' nose2; python_version >= '3.0'
nose; python_version >= '3.0'
coverage; python_version >= '3.0' coverage; python_version >= '3.0'
coveralls; python_version >= '3.0' coveralls; python_version >= '3.0'
pylint; python_version > '3.0'

@ -13,10 +13,11 @@ pycodestyle tests/
pyflakes catcli/ pyflakes catcli/
pyflakes tests/ pyflakes tests/
nosebin="nosetests" pylint catcli/
pylint tests/
PYTHONPATH=catcli ${nosebin} -s --with-coverage --cover-package=catcli nosebin="nose2"
#PYTHONPATH=catcli ${nosebin} -s PYTHONPATH=catcli ${nosebin} --with-coverage --coverage=catcli
for t in ${cur}/tests-ng/*; do for t in ${cur}/tests-ng/*; do
echo "running test \"`basename ${t}`\"" echo "running test \"`basename ${t}`\""

Loading…
Cancel
Save