Skip to content

Commit de29f62

Browse files
authored
Fix: Resolve playlist won't go up two relative levels. (#1952)
1 parent 06f44f3 commit de29f62

File tree

1 file changed

+26
-16
lines changed

1 file changed

+26
-16
lines changed

Diff for: music_assistant/providers/filesystem_local/__init__.py

+26-16
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@
88
import os
99
import os.path
1010
import time
11+
import urllib.parse
1112
from collections.abc import AsyncGenerator, Iterator, Sequence
13+
from pathlib import Path
1214
from typing import TYPE_CHECKING, Any, cast
1315

1416
import aiofiles
@@ -673,6 +675,8 @@ async def get_playlist_tracks(self, prov_playlist_id: str, page: int = 0) -> lis
673675
playlist_lines = parse_pls(playlist_data)
674676

675677
for idx, playlist_line in enumerate(playlist_lines, 1):
678+
if "#EXT" in playlist_line.path:
679+
continue
676680
if track := await self._parse_playlist_line(
677681
playlist_line.path, os.path.dirname(prov_playlist_id)
678682
):
@@ -718,24 +722,30 @@ async def _process_podcast_episode(item: FileSystemItem) -> None:
718722
async def _parse_playlist_line(self, line: str, playlist_path: str) -> Track | None:
719723
"""Try to parse a track from a playlist line."""
720724
try:
721-
# if a relative path was given in an upper level from the playlist,
722-
# try to resolve it
723-
for parentpart in ("../", "..\\"):
724-
while line.startswith(parentpart):
725-
if len(playlist_path) < 3:
726-
break # guard
727-
playlist_path = parentpart[:-3]
728-
line = line[3:]
729-
730-
# try to resolve the filename
731-
for filename in (line, os.path.join(playlist_path, line)):
732-
with contextlib.suppress(FileNotFoundError):
733-
file_item = await self.resolve(filename)
734-
tags = await async_parse_tags(file_item.absolute_path, file_item.file_size)
735-
return await self._parse_track(file_item, tags)
725+
line = line.replace("file://", "").strip()
726+
# try to resolve the filename (both normal and url decoded):
727+
# - as an absolute path
728+
# - relative to the playlist path
729+
# - relative to our base path
730+
# - relative to the playlist path with a leading slash
731+
for _line in (line, urllib.parse.unquote(line)):
732+
for filename in (
733+
# try to resolve the line as an absolute path
734+
_line,
735+
# try to resolve the line as a relative path to the playlist
736+
os.path.join(playlist_path, _line.removeprefix("/")),
737+
# try to resolve the line by resolving it against the absolute playlist path
738+
(Path(self.get_absolute_path(playlist_path)) / _line).resolve().as_posix(),
739+
):
740+
with contextlib.suppress(FileNotFoundError):
741+
file_item = await self.resolve(filename)
742+
tags = await async_parse_tags(file_item.absolute_path, file_item.file_size)
743+
return await self._parse_track(file_item, tags)
744+
# all attempts failed
745+
raise MediaNotFoundError("Invalid path/uri")
736746

737747
except MusicAssistantError as err:
738-
self.logger.warning("Could not parse uri/file %s to track: %s", line, str(err))
748+
self.logger.warning("Could not parse %s to track: %s", line, str(err))
739749

740750
return None
741751

0 commit comments

Comments
 (0)