diff --git a/beetsplug/convert.py b/beetsplug/convert.py index af1279299..6f4b3e50e 100644 --- a/beetsplug/convert.py +++ b/beetsplug/convert.py @@ -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) diff --git a/docs/changelog.rst b/docs/changelog.rst index b7a284587..aa3c65200 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -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 ~~~~~~~~~~~~~~~~~~~~~ diff --git a/test/plugins/test_convert.py b/test/plugins/test_convert.py index 13dbea084..ab3c82248 100644 --- a/test/plugins/test_convert.py +++ b/test/plugins/test_convert.py @@ -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):