diff --git a/beets/library.py b/beets/library.py index e3b5bbfa0..b2dd808ef 100644 --- a/beets/library.py +++ b/beets/library.py @@ -895,7 +895,7 @@ class Library(BaseLibrary): mapping[key] = util.sanitize_for_path(value, pathmod, key) # Perform substitution. - funcs = DefaultTemplateFunctions(self, item).functions() + funcs = DefaultTemplateFunctions(self, item, pathmod).functions() funcs.update(plugins.template_funcs()) subpath = subpath_tmpl.substitute(mapping, funcs) @@ -1362,9 +1362,10 @@ class DefaultTemplateFunctions(object): additional context to the functions -- specifically, the Item being evaluated. """ - def __init__(self, lib, item): + def __init__(self, lib, item, pathmod): self.lib = lib self.item = item + self.pathmod = pathmod _prefix = 'tmpl_' @@ -1478,5 +1479,9 @@ class DefaultTemplateFunctions(object): return u' {}'.format(album.id) # Flatten disambiguation values into a string. - values = [unicode(getattr(album, f)) for f in disambiguators] + values = [ + util.sanitize_for_path(unicode(getattr(album, f)), + self.pathmod, f) + for f in disambiguators + ] return u' [{}]'.format(u' '.join(values)) diff --git a/test/test_db.py b/test/test_db.py index 6297bed80..ce61c6a04 100644 --- a/test/test_db.py +++ b/test/test_db.py @@ -509,6 +509,14 @@ class DisambiguationTest(unittest.TestCase, PathFormattingMixin): self._assert_dest('/base/foo 1/the title', self.i1) self._assert_dest('/base/foo 2/the title', self.i2) + def test_unique_sanitized(self): + album2 = self.lib.get_album(self.i2) + album2.year = 2001 + album1 = self.lib.get_album(self.i1) + album1.albumtype = 'foo/bar' + self._setf(u'foo%unique{albumartist album,albumtype}/$title') + self._assert_dest('/base/foo [foo_bar]/the title', self.i1) + class PluginDestinationTest(unittest.TestCase): # Mock the plugins.template_values(item) function. def _template_values(self, item):