normalisename/normalisename.py

76 lines
2.1 KiB
Python
Raw Normal View History

from os.path import basename, dirname
from os.path import join as joinpath
from re import sub
from collections.abc import Iterable
from unidecode import unidecode
2016-12-08 17:15:56 +00:00
class Normalisename:
def __init__(self, separator, whitelist, operation=None):
self._separator = separator
self._whitelist = set(whitelist)
self._operation = None
self.operation = operation or self.noop
@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
@staticmethod
def noop(*_):
pass
@property
def separator(self):
return self._separator
@property
def whitelist(self):
return self._whitelist.union({self.separator})
def __call__(self, path_or_paths):
if isinstance(path_or_paths, str):
return self.normalise(path_or_paths)
if isinstance(path_or_paths, Iterable):
return self.normalise_all(path_or_paths)
raise ValueError('Argument must be str Iterable[str]!')
def normalise_all(self, paths):
return [self.normalise(path) for path in paths]
def normalise(self, path):
path = self.strip_trailing_slash(path)
directory = dirname(path)
filename = basename(path)
normalpath = joinpath(directory, self.normalname(filename))
if path != normalpath:
self.operation(path, normalpath) # pylint: disable=not-callable
return normalpath
@staticmethod
def strip_trailing_slash(path):
if path[-1] == '/':
path = path[:-1]
return path
def normalname(self, filename):
return unidecode(
''.join(
ch for ch in sub(r'\s+', self.separator, filename)
if ch.isalnum()
or ch in self.whitelist
)
)
2018-09-08 22:49:03 +00:00
def check_normal(self, path):
filename = basename(path)
return filename == self.normalname(filename)