mirror of
https://github.com/beetbox/beets.git
synced 2025-12-09 01:54:08 +01:00
Merge pull request #2399 from diomekes/aunique-bracket
Add bracket argument to aunique
This commit is contained in:
commit
ad957b51d8
4 changed files with 64 additions and 16 deletions
|
|
@ -1447,13 +1447,15 @@ 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
|
||||
disambiguate the albums. Otherwise, a fallback opaque value is
|
||||
used. Both "keys" and "disam" should be given as
|
||||
whitespace-separated lists of field names.
|
||||
whitespace-separated lists of field names, while "bracket" is a
|
||||
pair of characters to be used as brackets surrounding the
|
||||
disambiguator or empty to have no brackets.
|
||||
"""
|
||||
# Fast paths: no album, no item or library, or memoized value.
|
||||
if not self.item or not self.lib:
|
||||
|
|
@ -1467,9 +1469,20 @@ class DefaultTemplateFunctions(object):
|
|||
|
||||
keys = keys or 'albumartist album'
|
||||
disam = disam or 'albumtype year label catalognum albumdisambig'
|
||||
if bracket is None:
|
||||
bracket = '[]'
|
||||
keys = keys.split()
|
||||
disam = disam.split()
|
||||
|
||||
# Assign a left and right bracket or leave blank if argument is empty.
|
||||
if len(bracket) == 2:
|
||||
bracket = list(bracket)
|
||||
bracket_l = bracket[0]
|
||||
bracket_r = bracket[1]
|
||||
else:
|
||||
bracket_l = u''
|
||||
bracket_r = u''
|
||||
|
||||
album = self.lib.get_album(self.item)
|
||||
if not album:
|
||||
# Do nothing for singletons.
|
||||
|
|
@ -1502,13 +1515,19 @@ class DefaultTemplateFunctions(object):
|
|||
|
||||
else:
|
||||
# No disambiguator distinguished all fields.
|
||||
res = u' {0}'.format(album.id)
|
||||
res = u' {1}{0}{2}'.format(album.id, bracket_l, bracket_r)
|
||||
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)
|
||||
|
||||
# Return empty string if disambiguator is empty.
|
||||
if disam_value:
|
||||
res = u' {1}{0}{2}'.format(disam_value, bracket_l, bracket_r)
|
||||
else:
|
||||
res = u''
|
||||
|
||||
self.lib._memotable[memokey] = res
|
||||
return res
|
||||
|
||||
|
|
|
|||
|
|
@ -17,6 +17,11 @@ New features:
|
|||
return the item info for the file at the given path, or 404.
|
||||
* The :doc:`/plugins/web` also has a new config option, ``include_paths``,
|
||||
which will cause paths to be included in item API responses if set to true.
|
||||
* The ``%aunique`` template function for :ref:`aunique` now takes a third
|
||||
argument that specifies which brackets to use around the disambiguator
|
||||
value. The argument can be any two characters that represent the left and
|
||||
right brackets. It defaults to `[]` and can also be blank to turn off
|
||||
bracketing. :bug:`2397` :bug:`2399`
|
||||
|
||||
Fixes:
|
||||
|
||||
|
|
|
|||
|
|
@ -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,10 @@ 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 ``[]``. To change this, provide a
|
||||
third argument to the ``%aunique`` function consisting of two characters: the left
|
||||
and right brackets. Or, to turn off bracketing entirely, leave argument blank.
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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')
|
||||
|
|
@ -730,6 +730,24 @@ class DisambiguationTest(_common.TestCase, PathFormattingMixin):
|
|||
self._setf(u'foo%aunique{albumartist album,albumtype}/$title')
|
||||
self._assert_dest(b'/base/foo [foo_bar]/the title', self.i1)
|
||||
|
||||
def test_drop_empty_disambig_string(self):
|
||||
album1 = self.lib.get_album(self.i1)
|
||||
album1.albumdisambig = None
|
||||
album2 = self.lib.get_album(self.i2)
|
||||
album2.albumdisambig = u'foo'
|
||||
album1.store()
|
||||
album2.store()
|
||||
self._setf(u'foo%aunique{albumartist album,albumdisambig}/$title')
|
||||
self._assert_dest(b'/base/foo/the title', self.i1)
|
||||
|
||||
def test_change_brackets(self):
|
||||
self._setf(u'foo%aunique{albumartist album,year,()}/$title')
|
||||
self._assert_dest(b'/base/foo (2001)/the title', self.i1)
|
||||
|
||||
def test_remove_brackets(self):
|
||||
self._setf(u'foo%aunique{albumartist album,year,}/$title')
|
||||
self._assert_dest(b'/base/foo 2001/the title', self.i1)
|
||||
|
||||
|
||||
class PluginDestinationTest(_common.TestCase):
|
||||
def setUp(self):
|
||||
|
|
|
|||
Loading…
Reference in a new issue