mirror of
https://github.com/beetbox/beets.git
synced 2025-12-27 02:52:33 +01:00
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:
parent
b6e7e41269
commit
10758c487f
4 changed files with 32 additions and 5 deletions
|
|
@ -17,6 +17,7 @@ import:
|
|||
singletons: no
|
||||
default_action: apply
|
||||
|
||||
clutter: ["Thumbs.DB", ".DS_Store"]
|
||||
ignore: [".*", "*~"]
|
||||
replace:
|
||||
'[\\/]': _
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue