convert: playlist: M3U write + contents as bytes

Make sure we stay with the beets standard of handling everything internally as
bytes.

- M3UFile.write() method writes in wb mode.
- Playlist contents and EXTM3U header is handled as bytes.
  - item.destination() gives us unicode string paths, we tranlate to bytes
    using util.bytestring_path().
- Fix test_playlist*write* tests to encode UTF-8 assert strings as bytes using
  bytestring_path() before comparision.
This commit is contained in:
J0J0 Todos 2023-03-22 19:55:09 +01:00
parent 0884e67d35
commit a4d03ef586
3 changed files with 17 additions and 14 deletions

View file

@ -76,7 +76,7 @@ class M3UFile():
Handles the creation of potential parent directories.
"""
header = ["#EXTM3U"] if self.extm3u else []
header = [b"#EXTM3U"] if self.extm3u else []
if not self.media_list:
raise EmptyPlaylistError
contents = header + self.media_list
@ -84,9 +84,10 @@ class M3UFile():
mkdirall(pl_normpath)
try:
with open(syspath(pl_normpath), "w", encoding="utf-8") as pl_file:
pl_file.writelines('\n'.join(contents))
pl_file.write('\n') # Final linefeed to prevent noeol file.
with open(syspath(pl_normpath), "wb") as pl_file:
for line in contents:
pl_file.write(line + b'\n')
pl_file.write(b'\n') # Final linefeed to prevent noeol file.
except OSError as exc:
raise FilesystemError(exc, 'create', (pl_normpath, ),
traceback.format_exc())

View file

@ -486,7 +486,7 @@ class ConvertPlugin(BeetsPlugin):
self._log.info("Creating playlist file: {0}",
util.normpath(playlist))
items_paths = [
util.syspath(item.destination(
util.bytestring_path(item.destination(
basedir=dest, path_formats=path_formats, fragment=True
)) for item in items
]

View file

@ -42,8 +42,8 @@ class M3UFileTest(unittest.TestCase):
the_playlist_file = path.join(tempdir, b'playlist.m3u')
m3ufile = M3UFile(the_playlist_file)
m3ufile.set_contents([
'/This/is/a/path/to_a_file.mp3',
'/This/is/another/path/to_a_file.mp3',
bytestring_path('/This/is/a/path/to_a_file.mp3'),
bytestring_path('/This/is/another/path/to_a_file.mp3')
])
m3ufile.write()
self.assertTrue(path.exists(the_playlist_file))
@ -55,8 +55,8 @@ class M3UFileTest(unittest.TestCase):
the_playlist_file = path.join(tempdir, b'playlist.m3u8')
m3ufile = M3UFile(the_playlist_file)
m3ufile.set_contents([
'/This/is/å/path/to_a_file.mp3',
'/This/is/another/path/tö_a_file.mp3',
bytestring_path('/This/is/å/path/to_a_file.mp3'),
bytestring_path('/This/is/another/path/tö_a_file.mp3')
])
m3ufile.write()
self.assertTrue(path.exists(the_playlist_file))
@ -70,8 +70,8 @@ class M3UFileTest(unittest.TestCase):
b'playlist_write_and_read_windows.m3u8')
m3ufile = M3UFile(the_playlist_file)
m3ufile.set_contents([
r"x:\This\is\å\path\to_a_file.mp3",
r"x:\This\is\another\path\tö_a_file.mp3"
bytestring_path(r"x:\This\is\å\path\to_a_file.mp3"),
bytestring_path(r"x:\This\is\another\path\tö_a_file.mp3")
])
m3ufile.write()
self.assertTrue(path.exists(the_playlist_file))
@ -79,12 +79,14 @@ class M3UFileTest(unittest.TestCase):
m3ufile_read.load()
self.assertEquals(
m3ufile.media_list[0],
path.join('x:\\', 'This', 'is', 'å', 'path', 'to_a_file.mp3')
bytestring_path(
path.join('x:\\', 'This', 'is', 'å', 'path', 'to_a_file.mp3'))
)
self.assertEquals(
m3ufile.media_list[1],
r"x:\This\is\another\path\tö_a_file.mp3",
path.join('x:\\', 'This', 'is', 'another', 'path', 'tö_a_file.mp3')
bytestring_path(r"x:\This\is\another\path\tö_a_file.mp3"),
bytestring_path(path.join(
'x:\\', 'This', 'is', 'another', 'path', 'tö_a_file.mp3'))
)
rmtree(tempdir)