Skip to content

Slash in playlist name not replaced for .m3u #353

@B14CK313

Description

@B14CK313

You must use the search before you create an issue!

  • I did use the search, I promise!

What happened?

Some of my playlists contain a slash, like 🎸 Rock / Metal. While this slash is replaced/removed for the directory, it is not for the .m3u file. Creating this file fails with No such file or directory: '/path/to/playlist/dir/🎸 Rock Metal/_🎸 Rock / Metal.m3u'.

Shortened stacktrace to narrow it down:

  • tidal_dl_ng/cli.py:245 in download
  • tidal_dl_ng/cli.py:114 in _download
  • tidal_dl_ng/download.py:742 in items
  • tidal_dl_ng/download.py:768 in playlist_populate
  • pathlib.py:1013 in open

My temporary fix was to add name_list = name_list.replace("/", "_") in tidal_dl_ng/download.py::playlist_populate line 751, but there surely is a better way to do this.

Version App

v0.24.6

What operating system do you use?

Linux

Version OS

Archlinux 6.12.10-arch1-1.1

Relevant log output

╭───────────────────────────────────────────────────────────── Traceback (most recent call last) ─────────────────────────────────────────────────────────────╮
│ /path/to/python/lib/python3.12/site-packages/tidal_dl_ng/cli.py:245 in download                                      │
│                                                                                                                                                             │
│   242 │   │   │                                                                                                                                             │
│   243 │   │   │   raise typer.Abort()                                                                                                                       │
│   244 │                                                                                                                                                     │
│ ❱ 245 │   return _download(ctx, urls)                                                                                                                       │
│   246                                                                                                                                                       │
│   247                                                                                                                                                       │
│   248 @dl_fav_group.command(                                                                                                                                │
│                                                                                                                                                             │
│ ╭──────────────────────────────────────── locals ────────────────────────────────────────╮                                                                  │
│ │       ctx = <click.core.Context object at 0x7c1ec7d11520>                              │                                                                  │
│ │ file_urls = None                                                                       │                                                                  │
│ │      urls = ['https://listen.tidal.com/playlist/7d995fea-44ce-4764-aafc-fe0bd93bbb3f'] │                                                                  │
│ ╰────────────────────────────────────────────────────────────────────────────────────────╯                                                                  │
│                                                                                                                                                             │
│ /path/to/python/lib/python3.12/site-packages/tidal_dl_ng/cli.py:114 in _download                                     │
│                                                                                                                                                             │
│   111 │   │   │   │   │   item_ids.append(item_id)                                                                                                          │
│   112 │   │   │   │                                                                                                                                         │
│   113 │   │   │   │   for item_id in item_ids:                                                                                                              │
│ ❱ 114 │   │   │   │   │   dl.items(                                                                                                                         │
│   115 │   │   │   │   │   │   media_id=item_id,                                                                                                             │
│   116 │   │   │   │   │   │   media_type=media_type,                                                                                                        │
│   117 │   │   │   │   │   │   file_template=file_template,                                                                                                  │
│                                                                                                                                                             │
│ ╭────────────────────────────────────────── locals ───────────────────────────────────────────╮                                                             │
│ │            ctx = <click.core.Context object at 0x7c1ec7d11520>                              │                                                             │
│ │             dl = <tidal_dl_ng.download.Download object at 0x7c1ec7af6780>                   │                                                             │
│ │  file_template = 'playlists/{playlist_name}/{artist_name} - {track_title}'             │                                                             │
│ │      fn_logger = <tidal_dl_ng.helper.wrapper.LoggerWrapped object at 0x7c1ec7af6690>        │                                                             │
│ │           item = 'https://listen.tidal.com/playlist/7d995fea-44ce-4764-aafc-fe0bd93bbb3f'   │                                                             │
│ │        item_id = '7d995fea-44ce-4764-aafc-fe0bd93bbb3f'                                     │                                                             │
│ │       item_ids = ['7d995fea-44ce-4764-aafc-fe0bd93bbb3f']                                   │                                                             │
│ │     media_type = <MediaType.PLAYLIST: 'playlist'>                                           │                                                             │
│ │       progress = <rich.progress.Progress object at 0x7c1ec7a31280>                          │                                                             │
│ │ progress_table = <rich.table.Table object at 0x7c1ec7af6750>                                │                                                             │
│ │       settings = <tidal_dl_ng.config.Settings object at 0x7c1ec7af5a60>                     │                                                             │
│ │      try_login = True                                                                       │                                                             │
│ │           urls = ['https://listen.tidal.com/playlist/7d995fea-44ce-4764-aafc-fe0bd93bbb3f'] │                                                             │
│ │  urls_pos_last = 0                                                                          │                                                             │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────╯                                                             │
│                                                                                                                                                             │
│ /path/to/python/lib/python3.12/site-packages/tidal_dl_ng/download.py:742 in items                                    │
│                                                                                                                                                             │
│   739 │   │                                                                                                                                                 │
│   740 │   │   # Create playlist file                                                                                                                        │
│   741 │   │   if self.settings.data.playlist_create:                                                                                                        │
│ ❱ 742 │   │   │   self.playlist_populate(set(result_dirs), list_media_name, is_album)                                                                       │
│   743 │   │                                                                                                                                                 │
│   744 │   │   self.fn_logger.info(f"Finished list '{list_media_name}'.")                                                                                    │
│   745                                                                                                                                                       │
│                                                                                                                                                             │
│ ╭───────────────────────────────────────────────────────────────── locals ─────────────────────────────────────────────────────────────────╮                │
│ │        download_delay = True                                                                                                             │                │
│ │              executor = <concurrent.futures.thread.ThreadPoolExecutor object at 0x7c1ec7d13860>                                          │                │
│ │    file_name_relative = 'playlists/🚜 Rock - AlternativeBluesIndieCountryFolk/{artist_name} - {track_'+6                            │                │
│ │         file_template = 'playlists/{playlist_name}/{artist_name} - {track_title}'                                                   │                │
│ │                future = <Future at 0x7c1ec794f170 state=finished returned tuple>                                                         │                │
│ │              is_album = False                                                                                                            │                │
│ │                 items = [                                                                                                                │                │
│ │                         │   <tidalapi.media.Track object at 0x7c1ec792f200>,                                                             │                │
│ │                         │   <tidalapi.media.Track object at 0x7c1ec792f3b0>,                                                             │                │
│ │                         │   <tidalapi.media.Track object at 0x7c1ec792f1a0>,                                                             │                │
│ │                         │   <tidalapi.media.Track object at 0x7c1ec792f5c0>,                                                             │                │
│ │                         │   <tidalapi.media.Track object at 0x7c1ec792f710>,                                                             │                │
│ │                         │   <tidalapi.media.Track object at 0x7c1ec792f890>,                                                             │                │
│ │                         │   <tidalapi.media.Track object at 0x7c1ec792f9e0>,                                                             │                │
│ │                         │   <tidalapi.media.Track object at 0x7c1ec792fb30>,                                                             │                │
│ │                         │   <tidalapi.media.Track object at 0x7c1ec792fc80>,                                                             │                │
│ │                         │   <tidalapi.media.Track object at 0x7c1ec792fdd0>,                                                             │                │
│ │                         │   ... +35                                                                                                      │                │
│ │                         ]                                                                                                                │                │
│ │             l_futures = [                                                                                                                │                │
│ │                         │   <Future at 0x7c1ec7af7da0 state=finished returned tuple>,                                                    │                │
│ │                         │   <Future at 0x7c1ec7d99e50 state=finished returned tuple>,                                                    │                │
│ │                         │   <Future at 0x7c1ec792c7a0 state=finished returned tuple>,                                                    │                │
│ │                         │   <Future at 0x7c1ec792d190 state=finished returned tuple>,                                                    │                │
│ │                         │   <Future at 0x7c1ec792d2b0 state=finished returned tuple>,                                                    │                │
│ │                         │   <Future at 0x7c1ec792d220 state=finished returned tuple>,                                                    │                │
│ │                         │   <Future at 0x7c1ec792d3a0 state=finished returned tuple>,                                                    │                │
│ │                         │   <Future at 0x7c1ec792d520 state=finished returned tuple>,                                                    │                │
│ │                         │   <Future at 0x7c1ec792d640 state=finished returned tuple>,                                                    │                │
│ │                         │   <Future at 0x7c1ec792d5b0 state=finished returned tuple>,                                                    │                │
│ │                         │   ... +35                                                                                                      │                │
│ │                         ]                                                                                                                │                │
│ │       list_media_name = '🚜 Rock - Alternative/Blues/Indie/Country/Folk'                                                                 │                │
│ │ list_media_name_short = '🚜 Rock - Alternative/Blues/Ind'                                                                                │                │
│ │                 media = <tidalapi.playlist.UserPlaylist object at 0x7c1ec7d12300>                                                        │                │
│ │              media_id = '7d995fea-44ce-4764-aafc-fe0bd93bbb3f'                                                                           │                │
│ │            media_type = <MediaType.PLAYLIST: 'playlist'>                                                                                 │                │
│ │               p_task1 = 0                                                                                                                │                │
│ │       progress_stdout = True                                                                                                             │                │
│ │         quality_audio = None                                                                                                             │                │
│ │         quality_video = None                                                                                                             │                │
│ │           result_dirs = [                                                                                                                │                │
│ │                         │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk'),                    │                │
│ │                         │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk'),                    │                │
│ │                         │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk'),                    │                │
│ │                         │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk'),                    │                │
│ │                         │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk'),                    │                │
│ │                         │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk'),                    │                │
│ │                         │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk'),                    │                │
│ │                         │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk'),                    │                │
│ │                         │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk'),                    │                │
│ │                         │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk'),                    │                │
│ │                         │   ... +35                                                                                                      │                │
│ │                         ]                                                                                                                │                │
│ │      result_path_file = PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk/Björk - Army Of Me.flac') │                │
│ │                  self = <tidal_dl_ng.download.Download object at 0x7c1ec7af6780>                                                         │                │
│ │                status = True                                                                                                             │                │
│ │        video_download = True                                                                                                             │                │
│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯                │
│                                                                                                                                                             │
│ /path/to/python/lib/python3.12/site-packages/tidal_dl_ng/download.py:768 in playlist_populate                        │
│                                                                                                                                                             │
│   765 │   │   │   │   path_tracks.sort(key=lambda x: os.path.getmtime(x))                                                                                   │
│   766 │   │   │                                                                                                                                             │
│   767 │   │   │   # Write data to m3u file                                                                                                                  │
│ ❱ 768 │   │   │   with path_playlist.open(mode="w", encoding="utf-8") as f:                                                                                 │
│   769 │   │   │   │   for path_track in path_tracks:                                                                                                        │
│   770 │   │   │   │   │   # If it's a symlink write the relative file path to the actual track                                                              │
│   771 │   │   │   │   │   if path_track.is_symlink():                                                                                                       │
│                                                                                                                                                             │
│ ╭──────────────────────────────────────────────────────────────────────── locals ─────────────────────────────────────────────────────────────────────────╮ │
│ │      dir_scoped = PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk')                                              │ │
│ │     dirs_scoped = {PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk')}                                            │ │
│ │ extension_audio = <AudioExtensions.MP4: '.mp4'>                                                                                                         │ │
│ │        is_album = False                                                                                                                                 │ │
│ │       name_list = '🚜 Rock - Alternative/Blues/Indie/Country/Folk'                                                                                      │ │
│ │   path_playlist = PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk/_🚜 Rock -                                     │ │
│ │                   Alternative/Blues/Indie/Country/Folk.m3u')                                                                                            │ │
│ │     path_tracks = [                                                                                                                                     │ │
│ │                   │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk/The BossHoss, Mimi & Josy - Little         │ │
│ │                   Help.flac'),                                                                                                                          │ │
│ │                   │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk/The BossHoss - My Personal Song.flac'),    │ │
│ │                   │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk/The New Pornographers - The Laws Have      │ │
│ │                   Changed.flac'),                                                                                                                       │ │
│ │                   │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk/Asaf Avidan, The Mojos - Rubberband        │ │
│ │                   Girl.flac'),                                                                                                                          │ │
│ │                   │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk/The BossHoss - AYO.flac'),                 │ │
│ │                   │   PosixPath("/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk/Amalee - Cruel Angel's Thesis (From Neon   │ │
│ │                   Genesis Evangelion).flac"),                                                                                                           │ │
│ │                   │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk/Red Hot Chili Peppers - Otherside.flac'),  │ │
│ │                   │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk/Jill Andrews - Tell That Devil.flac'),     │ │
│ │                   │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk/Gin Wigmore - Black Sheep.flac'),          │ │
│ │                   │   PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk/Bonefield - Window.flac'),                 │ │
│ │                   │   ... +30                                                                                                                           │ │
│ │                   ]                                                                                                                                     │ │
│ │          result = []                                                                                                                                    │ │
│ │            self = <tidal_dl_ng.download.Download object at 0x7c1ec7af6780>                                                                              │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
│                                                                                                                                                             │
│ /path/to/python/cpython-3.12.8-linux-x86_64-gnu/lib/python3.12/pathlib.py:1013 in open                                                   │
│                                                                                                                                                             │
│   1010 │   │   """
│   1011 │   │   if "b" not in mode:                                                                                                                          │
│   1012 │   │   │   encoding = io.text_encoding(encoding)                                                                                                    │
│ ❱ 1013 │   │   return io.open(self, mode, buffering, encoding, errors, newline)                                                                             │
│   1014 │                                                                                                                                                    │
│   1015 │   def read_bytes(self):                                                                                                                            │
│   1016 │   │   """                                                                                                                                          │
│                                                                                                                                                             │
│ ╭──────────────────────────────────────────────────────────────────────── locals ─────────────────────────────────────────────────────────────────────────╮ │
│ │ buffering = -1                                                                                                                                          │ │
│ │  encoding = 'utf-8'                                                                                                                                     │ │
│ │    errors = None                                                                                                                                        │ │
│ │      mode = 'w'                                                                                                                                         │ │
│ │   newline = None                                                                                                                                        │ │
│ │      self = PosixPath('/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk/_🚜 Rock -                                           │ │
│ │             Alternative/Blues/Indie/Country/Folk.m3u')                                                                                                  │ │
│ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ │
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯
FileNotFoundError: [Errno 2] No such file or directory: '/path/to/playlist/dir/🚜 Rock - AlternativeBluesIndieCountryFolk/_🚜 Rock -
Alternative/Blues/Indie/Country/Folk.m3u'

Your settings

{
    "skip_existing": true,
    "lyrics_embed": true,
    "lyrics_file": true,
    "video_download": true,
    "download_delay": true,
    "download_base_path": "/path/to/music/",
    "quality_audio": "HI_RES_LOSSLESS",
    "quality_video": "480",
    "format_album": "{album_artist}/{album_title}/{track_volume_num_optional}{album_track_num}. {artist_name} - {track_title}",
    "format_playlist": "playlists/{playlist_name}/{artist_name} - {track_title}",
    "format_mix": "mix/{mix_name}/{artist_name} - {track_title}",
    "format_track": "{album_artist}/{album_title}/{track_volume_num_optional}{album_track_num}. {artist_name} - {track_title}",
    "format_video": "videos/{artist_name} - {track_title}",
    "video_convert_mp4": true,
    "path_binary_ffmpeg": "/usr/bin/ffmpeg",
    "metadata_cover_dimension": "320",
    "metadata_cover_embed": true,
    "cover_album_file": true,
    "extract_flac": true,
    "downloads_simultaneous_per_track_max": 20,
    "download_delay_sec_min": 3.0,
    "download_delay_sec_max": 15.0,
    "album_track_num_pad_min": 2,
    "downloads_concurrent_max": 3,
    "symlink_to_track": true,
    "playlist_create": true
}

Metadata

Metadata

Assignees

Labels

bugSomething isn't working

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions