mirror of
https://github.com/beetbox/beets.git
synced 2026-03-18 19:33:01 +01:00
Fix extension issue in convert plugin when exporting a playlist (#5203)
Fix extension substitution inside path of the exported playlist. Before this, the exported playlist contained relative paths pointing to the converted files BUT the extension were not substituted comparing to before and the after the conversion. Therefore, running the playlist will fail for files which have been converted and where extension have changed. Example: 1. Convert `/path/to/library/artist.flac` to `/path/to/converted/artist.mp3` using the `-m playlist.m3u` command-line flag. 2. Open the generated playlist, and find the incorrect path `/path/to/converted/artist.flac` inside.
This commit is contained in:
commit
c1fa0a653d
3 changed files with 44 additions and 13 deletions
|
|
@ -627,6 +627,28 @@ class ConvertPlugin(BeetsPlugin):
|
|||
album, dest, path_formats, pretend, link, hardlink
|
||||
)
|
||||
|
||||
# If the user supplied a playlist name, create a playlist for files
|
||||
# copied to the destination.
|
||||
pl_normpath = None
|
||||
items_paths = None
|
||||
if playlist:
|
||||
_, ext = get_format(fmt)
|
||||
# Playlist paths are understood as relative to the dest directory.
|
||||
pl_normpath = util.normpath(playlist)
|
||||
pl_dir = os.path.dirname(pl_normpath)
|
||||
items_paths = []
|
||||
for item in items:
|
||||
item_path = item.destination(
|
||||
basedir=dest, path_formats=path_formats
|
||||
)
|
||||
|
||||
# When keeping new files in the library, destination paths
|
||||
# keep original files and extensions.
|
||||
if not opts.keep_new and should_transcode(item, fmt, force):
|
||||
item_path = replace_ext(item_path, ext)
|
||||
|
||||
items_paths.append(os.path.relpath(item_path, pl_dir))
|
||||
|
||||
self._parallel_convert(
|
||||
dest,
|
||||
opts.keep_new,
|
||||
|
|
@ -641,20 +663,7 @@ class ConvertPlugin(BeetsPlugin):
|
|||
)
|
||||
|
||||
if playlist:
|
||||
# Playlist paths are understood as relative to the dest directory.
|
||||
pl_normpath = util.normpath(playlist)
|
||||
pl_dir = os.path.dirname(pl_normpath)
|
||||
self._log.info("Creating playlist file {}", pl_normpath)
|
||||
# Generates a list of paths to media files, ensures the paths are
|
||||
# relative to the playlist's location and translates the unicode
|
||||
# strings we get from item.destination to bytes.
|
||||
items_paths = [
|
||||
os.path.relpath(
|
||||
item.destination(basedir=dest, path_formats=path_formats),
|
||||
pl_dir,
|
||||
)
|
||||
for item in items
|
||||
]
|
||||
if not pretend:
|
||||
m3ufile = M3UFile(playlist)
|
||||
m3ufile.set_contents(items_paths)
|
||||
|
|
|
|||
|
|
@ -56,6 +56,8 @@ Bug fixes
|
|||
- :ref:`import-cmd` Duplicate detection now works for as-is imports (when
|
||||
``autotag`` is disabled). Previously, ``duplicate_keys`` and
|
||||
``duplicate_action`` config options were silently ignored for as-is imports.
|
||||
- :doc:`/plugins/convert`: Fix extension substitution inside path of the
|
||||
exported playlist.
|
||||
|
||||
For plugin developers
|
||||
~~~~~~~~~~~~~~~~~~~~~
|
||||
|
|
|
|||
|
|
@ -288,6 +288,26 @@ class ConvertCliTest(ConvertTestCase, ConvertCommand):
|
|||
converted = self.convert_dest / "converted.ops"
|
||||
assert self.file_endswith(converted, "opus")
|
||||
|
||||
def assert_playlist_entry(self, expected_entry, *args):
|
||||
self.io.addinput("y")
|
||||
self.run_convert(*args, "--playlist", "playlist.m3u8")
|
||||
lines = (self.convert_dest / "playlist.m3u8").read_text().splitlines()
|
||||
assert lines[0] == "#EXTM3U"
|
||||
assert lines[1] == expected_entry
|
||||
|
||||
def test_playlist_entry_uses_config_format(self):
|
||||
self.assert_playlist_entry("converted.mp3")
|
||||
|
||||
def test_playlist_entry_uses_cli_format(self):
|
||||
self.assert_playlist_entry("converted.ops", "--format", "opus")
|
||||
|
||||
def test_playlist_entry_keeps_original_extension_when_not_transcoded(self):
|
||||
self.config["convert"]["no_convert"] = "format:ogg"
|
||||
self.assert_playlist_entry("converted.ogg")
|
||||
|
||||
def test_playlist_entry_keep_new_points_to_destination_file(self):
|
||||
self.assert_playlist_entry("converted.ogg", "--keep-new")
|
||||
|
||||
|
||||
@_common.slow_test()
|
||||
class NeverConvertLossyFilesTest(ConvertTestCase, ConvertCommand):
|
||||
|
|
|
|||
Loading…
Reference in a new issue