diff --git a/beets/library.py b/beets/library.py index e3ac1bd40..1cfe87f0c 100644 --- a/beets/library.py +++ b/beets/library.py @@ -1447,7 +1447,7 @@ class DefaultTemplateFunctions(object): cur_fmt = beets.config['time_format'].as_str() return time.strftime(fmt, time.strptime(s, cur_fmt)) - def tmpl_aunique(self, keys=None, disam=None): + def tmpl_aunique(self, keys=None, disam=None, bracket=None): """Generate a string that is guaranteed to be unique among all albums in the library who share the same set of keys. A fields from "disam" is used in the string if one is sufficient to @@ -1467,8 +1467,10 @@ class DefaultTemplateFunctions(object): keys = keys or 'albumartist album' disam = disam or 'albumtype year label catalognum albumdisambig' + bracket = bracket or '[]' keys = keys.split() disam = disam.split() + bracket = None if bracket is ' ' else list(bracket) album = self.lib.get_album(self.item) if not album: @@ -1502,13 +1504,20 @@ class DefaultTemplateFunctions(object): else: # No disambiguator distinguished all fields. - res = u' {0}'.format(album.id) + res = u' {1}{0}{2}'.format(album.id, bracket[0] if bracket else + u'', bracket[1] if bracket else u'') self.lib._memotable[memokey] = res return res # Flatten disambiguation value into a string. disam_value = album.formatted(True).get(disambiguator) - res = u' [{0}]'.format(disam_value) + res = u' {1}{0}{2}'.format(disam_value, bracket[0] if bracket else u'', + bracket[1] if bracket else u'') + + # Remove space and/or brackets if disambiguation value is empty + if bracket and res == u' ' + ''.join(bracket) or res.isspace(): + res = u'' + self.lib._memotable[memokey] = res return res diff --git a/docs/reference/pathformat.rst b/docs/reference/pathformat.rst index 72453a6e5..de1185ae0 100644 --- a/docs/reference/pathformat.rst +++ b/docs/reference/pathformat.rst @@ -71,8 +71,8 @@ These functions are built in to beets: For example, "café" becomes "cafe". Uses the mapping provided by the `unidecode module`_. See the :ref:`asciify-paths` configuration option. -* ``%aunique{identifiers,disambiguators}``: Provides a unique string to - disambiguate similar albums in the database. See :ref:`aunique`, below. +* ``%aunique{identifiers,disambiguators,brackets}``: Provides a unique string + to disambiguate similar albums in the database. See :ref:`aunique`, below. * ``%time{date_time,format}``: Return the date and time in any format accepted by `strftime`_. For example, to get the year some music was added to your library, use ``%time{$added,%Y}``. @@ -112,14 +112,16 @@ will expand to "[2008]" for one album and "[2010]" for the other. The function detects that you have two albums with the same artist and title but that they have different release years. -For full flexibility, the ``%aunique`` function takes two arguments, each of -which are whitespace-separated lists of album field names: a set of -*identifiers* and a set of *disambiguators*. Any group of albums with identical -values for all the identifiers will be considered "duplicates". Then, the -function tries each disambiguator field, looking for one that distinguishes each -of the duplicate albums from each other. The first such field is used as the -result for ``%aunique``. If no field suffices, an arbitrary number is used to -distinguish the two albums. +For full flexibility, the ``%aunique`` function takes three arguments. The +first two are whitespace-separated lists of album field names: a set of +*identifiers* and a set of *disambiguators*. The third argument is a pair of +characters used to surround the disambiguator. + +Any group of albums with identical values for all the identifiers will be +considered "duplicates". Then, the function tries each disambiguator field, +looking for one that distinguishes each of the duplicate albums from each +other. The first such field is used as the result for ``%aunique``. If no field +suffices, an arbitrary number is used to distinguish the two albums. The default identifiers are ``albumartist album`` and the default disambiguators are ``albumtype year label catalognum albumdisambig``. So you can get reasonable @@ -127,6 +129,9 @@ disambiguation behavior if you just use ``%aunique{}`` with no parameters in your path forms (as in the default path formats), but you can customize the disambiguation if, for example, you include the year by default in path formats. +The default characters used as brackets are ``[]``. If a single blank space is +used, then the disambiguator will not be surrounded by anything. + One caveat: When you import an album that is named identically to one already in your library, the *first* album—the one already in your library— will not consider itself a duplicate at import time. This means that ``%aunique{}`` will diff --git a/test/test_library.py b/test/test_library.py index 7aa88e064..d2c21d5f6 100644 --- a/test/test_library.py +++ b/test/test_library.py @@ -713,8 +713,8 @@ class DisambiguationTest(_common.TestCase, PathFormattingMixin): album2.year = 2001 album2.store() - self._assert_dest(b'/base/foo 1/the title', self.i1) - self._assert_dest(b'/base/foo 2/the title', self.i2) + self._assert_dest(b'/base/foo [1]/the title', self.i1) + self._assert_dest(b'/base/foo [2]/the title', self.i2) def test_unique_falls_back_to_second_distinguishing_field(self): self._setf(u'foo%aunique{albumartist album,month year}/$title')