Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 13 additions & 10 deletions beets/util/m3u.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,19 +79,22 @@ def write(self):

Handles the creation of potential parent directories.
"""
# Use bytes for header if extm3u is True, otherwise use str
header = [b"#EXTM3U"] if self.extm3u else []

if not self.media_list:
raise EmptyPlaylistError
contents = header + self.media_list

# Ensure all media_list items are bytes
media_bytes = [
line.encode('utf-8') if isinstance(line, str) else line
for line in self.media_list
]

contents = header + media_bytes
pl_normpath = normpath(self.path)
mkdirall(pl_normpath)

try:
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()
)
with open(syspath(pl_normpath), "wb") as pl_file:
for line in contents:
pl_file.write(line + b"\n")
27 changes: 16 additions & 11 deletions beetsplug/convert.py
Original file line number Diff line number Diff line change
Expand Up @@ -616,24 +616,29 @@ def convert_func(self, lib, opts, args):
)

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,

items_paths = []
for item in items:
path = (
item.path
if item.path
else item.destination(basedir=dest, path_formats=path_formats)
)
for item in items
]
rel_path = os.path.relpath(path, pl_dir)

# Ensure string encoding for playlist entries (convert bytes to str)
if isinstance(rel_path, bytes):
rel_path = rel_path.decode('utf-8', errors='replace')

items_paths.append(rel_path)

if not pretend:
m3ufile = M3UFile(playlist)
m3ufile.set_contents(items_paths)
m3ufile.write()
m3ufile.write() # Assume m3ufile.write expects str lines

def convert_on_import(self, lib, item):
"""Transcode a file automatically after it is imported into the
Expand Down
Loading