diff --git a/brename.py b/brename.py index 984f9cc..7376489 100644 --- a/brename.py +++ b/brename.py @@ -38,16 +38,30 @@ underscore = '_' excise = stringtools.excise title = stringtools.title_capitalize +def natural_sorter(x): + ''' + Thank you Mark Byers + http://stackoverflow.com/a/11150413 + ''' + convert = lambda text: int(text) if text.isdigit() else text.lower() + alphanum_key = lambda key: [convert(c) for c in re.split(r'([0-9]+)', key)] + return alphanum_key(x) + def unicode_normalize(s): return unicodedata.normalize('NFC', s) -def brename(transformation, autoyes=False, recurse=False): +def brename(transformation, autoyes=False, do_naturalsort=False, recurse=False): if recurse: walker = spinal.walk_generator('.', yield_files=True, yield_directories=True) olds = [x.absolute_path for x in walker] else: olds = [os.path.join(os.getcwd(), x) for x in os.listdir('.')] + if do_naturalsort: + olds.sort(key=natural_sorter) + else: + olds.sort() + pairs = [] for (index, old) in enumerate(olds): new = old @@ -97,7 +111,12 @@ def loop(pairs, dry=False): os.rename(old, new) def brename_argparse(args): - brename(args.transformation, autoyes=args.autoyes, recurse=args.recurse) + return brename( + args.transformation, + autoyes=args.autoyes, + do_naturalsort=args.do_naturalsort, + recurse=args.recurse, + ) def main(argv): parser = argparse.ArgumentParser(description=__doc__) @@ -105,6 +124,7 @@ def main(argv): parser.add_argument('transformation', help='python command using x as variable name') parser.add_argument('-y', '--yes', dest='autoyes', action='store_true', help='accept results without confirming') parser.add_argument('--recurse', dest='recurse', action='store_true', help='operate on subdirectories also') + parser.add_argument('--naturalsort', dest='do_naturalsort', action='store_true') parser.set_defaults(func=brename_argparse) args = parser.parse_args(argv) diff --git a/fileprefix.py b/fileprefix.py deleted file mode 100644 index a23d4a2..0000000 --- a/fileprefix.py +++ /dev/null @@ -1,109 +0,0 @@ -''' -When you run this file from the commandline given a single argument, all -of the files in the current working directory will be renamed in the format -{argument}_{count} where argument is your cmd input and count is a zero-padded -integer that counts each file in the folder. -''' - -import argparse -import os -import re -import sys - -from voussoirkit import interactive -from voussoirkit import pathclass -from voussoirkit import safeprint - -IGNORE_EXTENSIONS = ['py', 'lnk', 'ini'] - - -def natural_sorter(x): - ''' - Thank you Mark Byers - http://stackoverflow.com/a/11150413 - ''' - convert = lambda text: int(text) if text.isdigit() else text.lower() - alphanum_key = lambda key: [convert(c) for c in re.split('([0-9]+)', key)] - return alphanum_key(x) - -def fileprefix( - prefix='', - sep='_', - ctime=False, - autoyes=False, - one_index=False, - ): - current_directory = pathclass.cwd() - - prefix = prefix.strip() - if prefix == ':': - prefix = current_directory.basename + ' - ' - elif prefix != '': - prefix += sep - - filepaths = current_directory.listdir() - filepaths = [f for f in filepaths if f.is_file] - filepaths = [f for f in filepaths if f.extension not in IGNORE_EXTENSIONS] - - try: - pyfile = pathclass.Path(__file__) - filepaths.remove(pyfile) - except ValueError: - pass - - # trust me on this. - zeropadding = len(str(len(filepaths))) - zeropadding = max(2, zeropadding) - zeropadding = str(zeropadding) - - format = '{{prefix}}{{index:0{pad}d}}{{extension}}'.format(pad=zeropadding) - - if ctime: - print('Sorting by time') - filepaths.sort(key=lambda x: x.stat.st_ctime) - else: - print('Sorting by name') - filepaths.sort(key=lambda x: natural_sorter(x.basename)) - - rename_pairs = [] - - start_index = 1 if one_index else 0 - for (index, filepath) in enumerate(filepaths, start_index): - extension = filepath.extension.with_dot - - newname = format.format(prefix=prefix, index=index, extension=extension) - if filepath.basename != newname: - rename_pairs.append((filepath.absolute_path, newname)) - for (oldname, newname) in rename_pairs: - message = f'{oldname} -> {newname}' - safeprint.safeprint(message) - - if autoyes or interactive.getpermission('Is this correct?'): - for (oldname, newname) in rename_pairs: - os.rename(oldname, newname) - - -def fileprefix_argparse(args): - return fileprefix( - autoyes=args.autoyes, - ctime=args.ctime, - one_index=args.one_index, - prefix=args.prefix, - sep=args.sep, - ) - -def main(argv): - parser = argparse.ArgumentParser() - - parser.add_argument('prefix', nargs='?', default='') - parser.add_argument('--sep', dest='sep', default=' ', help='the character between the prefix and remainder') - parser.add_argument('--ctime', dest='ctime', action='store_true', help='sort by ctime instead of filename') - parser.add_argument('-y', '--yes', dest='autoyes', action='store_true', help='accept results without confirming') - parser.add_argument('-1', dest='one_index', action='store_true') - parser.set_defaults(func=fileprefix_argparse) - - args = parser.parse_args(argv) - return args.func(args) - -if __name__ == '__main__': - raise SystemExit(main(sys.argv[1:]))