|
8 | 8 | import os
|
9 | 9 | import os.path
|
10 | 10 | import time
|
| 11 | +import urllib.parse |
11 | 12 | from collections.abc import AsyncGenerator, Iterator, Sequence
|
| 13 | +from pathlib import Path |
12 | 14 | from typing import TYPE_CHECKING, Any, cast
|
13 | 15 |
|
14 | 16 | import aiofiles
|
@@ -718,17 +720,25 @@ async def _process_podcast_episode(item: FileSystemItem) -> None:
|
718 | 720 | async def _parse_playlist_line(self, line: str, playlist_path: str) -> Track | None:
|
719 | 721 | """Try to parse a track from a playlist line."""
|
720 | 722 | 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 = os.path.dirname(playlist_path) |
728 |
| - line = line[3:] |
| 723 | + line = line.replace("file://", "").strip() |
| 724 | + |
| 725 | + # handle relative paths in a level which is above the playlist itself |
| 726 | + if ".." in line: |
| 727 | + abs_playlist_path = self.get_absolute_path(playlist_path) |
| 728 | + line = (Path(abs_playlist_path) / line).resolve().as_posix() |
729 | 729 |
|
730 | 730 | # try to resolve the filename
|
731 |
| - for filename in (line, os.path.join(playlist_path, line)): |
| 731 | + # we try to resolve the playlist line from a few perspectives: |
| 732 | + # - as an absolute path |
| 733 | + # - relative to the playlist path |
| 734 | + # - relative to our base path |
| 735 | + for filename in ( |
| 736 | + line, |
| 737 | + os.path.join(playlist_path, line), |
| 738 | + # also try with url decoding the line as e.g. VLC seems to encode some characters |
| 739 | + urllib.parse.unquote(line), |
| 740 | + os.path.join(playlist_path, urllib.parse.unquote(line)), |
| 741 | + ): |
732 | 742 | with contextlib.suppress(FileNotFoundError):
|
733 | 743 | file_item = await self.resolve(filename)
|
734 | 744 | tags = await async_parse_tags(file_item.absolute_path, file_item.file_size)
|
|
0 commit comments