Configurable list of patterns which will be ignored when pruning empty directories.

* util.prune_dirs modified to accept glob patterns as clutter to determine emptiness.
* config option, 'clutter' (a list of filenames/glob patterns)
* ImportTask.prune passes this option's value to prune_dirs.
This commit is contained in:
steini 2013-02-04 23:41:38 +00:00
parent b6e7e41269
commit 10758c487f
4 changed files with 32 additions and 5 deletions

View file

@ -17,6 +17,7 @@ import:
singletons: no
default_action: apply
clutter: ["Thumbs.DB", ".DS_Store"]
ignore: [".*", "*~"]
replace:
'[\\/]': _

View file

@ -513,7 +513,11 @@ class ImportTask(object):
call when the file in question may not have been removed.
"""
if self.toppath and not os.path.exists(filename):
util.prune_dirs(os.path.dirname(filename), self.toppath)
util.prune_dirs(
os.path.dirname(filename),
self.toppath,
clutter=config['clutter'].get(list)
)
# Full-album pipeline stages.

View file

@ -193,11 +193,26 @@ def mkdirall(path):
raise FilesystemError(exc, 'create', (ancestor,),
traceback.format_exc())
def fnmatch_all(names, patterns):
"""
`names` and `patterns` should be iterables.
Returns True if all names match any of the patterns.
"""
for name in names:
matches = False
for pattern in patterns:
matches = fnmatch.fnmatch(name, pattern)
if matches:
break
if not matches:
return False
return True
def prune_dirs(path, root=None, clutter=('.DS_Store', 'Thumbs.db')):
"""If path is an empty directory, then remove it. Recursively remove
path's ancestry up to root (which is never removed) where there are
empty directories. If path is not contained in root, then nothing is
removed. Filenames in clutter are ignored when determining
removed. Glob patterns in clutter are ignored when determining
emptiness. If root is not provided, then only path may be removed
(i.e., no recursive removal).
"""
@ -224,13 +239,12 @@ def prune_dirs(path, root=None, clutter=('.DS_Store', 'Thumbs.db')):
if not os.path.exists(directory):
# Directory gone already.
continue
if all(fn in clutter for fn in os.listdir(directory)):
if fnmatch_all(os.listdir(directory), clutter):
# Directory contains only clutter (or nothing).
try:
shutil.rmtree(directory)
except OSError:
break
break
else:
break

View file

@ -332,6 +332,14 @@ class ImportApplyTest(_common.TestCase):
_call_stages(self.session, [self.i], self.info, toppath=self.srcdir)
self.assertNotExists(os.path.dirname(self.srcpath))
def test_apply_with_move_prunes_with_extra_clutter(self):
f = open(os.path.join(self.srcdir, 'testalbum', 'alog.log'), 'w')
f.close()
config['clutter'] = ['*.log']
config['import']['move'] = True
_call_stages(self.session, [self.i], self.info, toppath=self.srcdir)
self.assertNotExists(os.path.dirname(self.srcpath))
def test_manipulate_files_with_null_move(self):
"""It should be possible to "move" a file even when the file is
already at the destination.