normalisename/normalisename.py

96 lines
3.6 KiB
Python
Executable File

#!/usr/bin/env python3
from unidecode import unidecode
from os import rename
from os.path import basename, dirname
from os.path import join as joinpath
from argparse import ArgumentParser
from sys import exit
class normalisename:
@property
def operation(self):
return self._operation
@operation.setter
def operation(self, value):
if not callable(value):
raise ValueError('Operation must be callable!')
self._operation = value
@property
def separator(self):
return self._separator
@property
def whitelist(self):
return self._whitelist
def __init__(self, operation, separator, whitelist):
self._operation = None
self.operation = operation
self._separator = separator
self._whitelist = set(whitelist)
def normalise(self, files):
for path in files:
if not self.check_normal(path):
dir = dirname(path)
file = basename(path)
normalpath = joinpath(dir, self.normalname(file))
self.operation(path, normalpath)
def check_normal(self, file):
file = basename(file)
return file == self.normalname(file)
def normalname(self, filename):
return unidecode(''.join(ch for ch in filename.replace(' ', self.separator)
if ch.isalnum()
or ch in self.whitelist))
if __name__ == '__main__':
# parse arguments
parser = ArgumentParser(description='Eliminate funky stuff from filenames.')
parser.add_argument('--separator', '-s', type=str, nargs='?', default='_',
help='Set separator to use (to replace spaces with).')
parser.add_argument('--allow', '-a', type=str, nargs='?', action='append',
help='Specify a special character to allow (it will not be removed).')
parser.add_argument('--disallow', '-d', type=str, nargs='?', action='append',
help='Specify a special character to disallow (it will removed).')
parser.add_argument('--whitelist', '-w', type=str,
help='Overwrite default whitelist (format: whitespace separated string).')
mgroup = parser.add_mutually_exclusive_group()
mgroup.add_argument('--dryrun', '-n', action='store_true',
help='Do not touch anything, just tell me what would change!')
mgroup.add_argument('--funky', '-f', action='store_true',
help='List filenames with special characters')
parser.add_argument('files', type=str, nargs='+',
help='File(s) to normalise the name of (relative or absolute path).')
args = parser.parse_args()
# verify arguments
if args.disallow:
if args.separator in args.disallow: exit('Disallowing your chosen separator makes no sense!')
# declare special characters that will not be removed (spaces are handled elsewhere)
whitelist = {' ', '.', '-'}
if args.whitelist: whitelist = set(args.whitelist.split())
# modify whitelist based on arguments
whitelist.add(args.separator)
if args.allow: whitelist = whitelist.union(set(args.allow))
if args.disallow: whitelist = whitelist.difference(set(args.disallow))
# define operations
listchanges = lambda a, b: print('{}{} --> {}'.format(a, ' '*(60-len(a)), b))
listfunky = lambda a, b: print(b)
operation = rename
if args.dryrun: operation = listchanges
elif args.funky: operation = listfunky
normalisename(operation, args.separator, whitelist).normalise(args.files)