Allow custom replacements in Item.destination

This allows for the use of differing replacements for destinations other than
the library, which is useful for beets-alternatives in the case where
filesystem requirements differ between the two paths.

Signed-off-by: Christopher Larson <kergoth@gmail.com>
This commit is contained in:
Christopher Larson 2021-10-12 15:39:33 -07:00
parent ee8a4de247
commit 86465e6437
3 changed files with 19 additions and 2 deletions

View file

@ -938,7 +938,7 @@ class Item(LibModel):
# Templating.
def destination(self, fragment=False, basedir=None, platform=None,
path_formats=None):
path_formats=None, replacements=None):
"""Returns the path in the library directory designated for the
item (i.e., where the file ought to be). fragment makes this
method return just the path fragment underneath the root library
@ -950,6 +950,8 @@ class Item(LibModel):
platform = platform or sys.platform
basedir = basedir or self._db.directory
path_formats = path_formats or self._db.path_formats
if replacements is None:
replacements = self._db.replacements
# Use a path format based on a query, falling back on the
# default.
@ -994,7 +996,7 @@ class Item(LibModel):
maxlen = util.max_filename_length(self._db.directory)
subpath, fellback = util.legalize_path(
subpath, self._db.replacements, maxlen,
subpath, replacements, maxlen,
os.path.splitext(self.path)[1], fragment
)
if fellback:

View file

@ -36,6 +36,11 @@ Other new things:
* :doc:`/plugins/unimported`: Support excluding specific
subdirectories in library.
For plugin developers:
* :py:meth:`beets.library.Item.destination` now accepts a `replacements`
argument to be used in favor of the default.
Bug fixes:
* :doc:`/plugins/lyrics`: Fix crash bug when beautifulsoup4 is not installed.

View file

@ -449,6 +449,16 @@ class DestinationTest(_common.TestCase):
self.assertEqual(self.i.destination(),
np('base/ber/foo'))
def test_destination_with_replacements_argument(self):
self.lib.directory = b'base'
self.lib.replacements = [(re.compile(r'a'), 'f')]
self.lib.path_formats = [('default', '$album/$title')]
self.i.title = 'foo'
self.i.album = 'bar'
replacements = [(re.compile(r'a'), 'e')]
self.assertEqual(self.i.destination(replacements=replacements),
np('base/ber/foo'))
@unittest.skip('unimplemented: #359')
def test_destination_with_empty_component(self):
self.lib.directory = b'base'