From 57dd1f12121f827f2ba7077cfa1f40e2a67c66a6 Mon Sep 17 00:00:00 2001 From: oskvr37 <oskarxpd@gmail.com> Date: Tue, 24 Dec 2024 14:19:42 +0100 Subject: [PATCH 01/11] =?UTF-8?q?=F0=9F=9A=80=20bump=20to=20`1.9.0`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 7d43502..9e425fe 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="tiddl", - version="1.8.3", + version="1.9.0", description="TIDDL (Tidal Downloader) is a Python CLI application that allows downloading Tidal tracks.", long_description=open("README.md", encoding="utf-8").read(), long_description_content_type="text/markdown", From 1ede4eef173f5ef0847c5e34ae64717530c30c69 Mon Sep 17 00:00:00 2001 From: oskvr37 <oskarxpd@gmail.com> Date: Thu, 26 Dec 2024 21:06:30 +0100 Subject: [PATCH 02/11] =?UTF-8?q?=F0=9F=90=9B=20fix=20#61?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tiddl/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tiddl/__init__.py b/tiddl/__init__.py index ae70c28..f4b3494 100644 --- a/tiddl/__init__.py +++ b/tiddl/__init__.py @@ -184,7 +184,7 @@ def downloadTrack( stream["manifestMimeType"], ) - os.makedirs(file_dir, exist_ok=True) + os.makedirs(f"{download_path}/{file_dir}", exist_ok=True) file_path = f"{download_path}/{file_dir}/{file_name}.{extension}" From 81c2628f417009088c97383827c7ff132f609d95 Mon Sep 17 00:00:00 2001 From: oskvr37 <oskarxpd@gmail.com> Date: Thu, 26 Dec 2024 21:06:55 +0100 Subject: [PATCH 03/11] =?UTF-8?q?=F0=9F=9A=80=20bump=20to=20`1.9.1`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 9e425fe..0197144 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="tiddl", - version="1.9.0", + version="1.9.1", description="TIDDL (Tidal Downloader) is a Python CLI application that allows downloading Tidal tracks.", long_description=open("README.md", encoding="utf-8").read(), long_description_content_type="text/markdown", From 19cd8688ac35ab4feb4a2d0a4f118d1e777fd462 Mon Sep 17 00:00:00 2001 From: oskvr37 <oskarxpd@gmail.com> Date: Sun, 29 Dec 2024 10:07:18 +0100 Subject: [PATCH 04/11] =?UTF-8?q?=F0=9F=90=9B=20fix=20#63?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tiddl/utils.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tiddl/utils.py b/tiddl/utils.py index 25b6554..334c5e2 100644 --- a/tiddl/utils.py +++ b/tiddl/utils.py @@ -78,7 +78,8 @@ def formatFilename(template: str, track: Track, playlist=""): artists = [artist["name"].strip() for artist in track["artists"]] release_date = datetime.strptime( - track["streamStartDate"], "%Y-%m-%dT%H:%M:%S.000+0000" + track["streamStartDate"] or "1970-01-01T00:00:00.000+0000", + "%Y-%m-%dT%H:%M:%S.000+0000", ) formatted_track: FormattedTrack = { From 71ece5cd0feb7c182d0787bc3d61f124ca58af45 Mon Sep 17 00:00:00 2001 From: oskvr37 <oskarxpd@gmail.com> Date: Sun, 29 Dec 2024 10:07:38 +0100 Subject: [PATCH 05/11] =?UTF-8?q?=F0=9F=9A=80=20bump=20to=20`1.9.2`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 0197144..9de9ca9 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="tiddl", - version="1.9.1", + version="1.9.2", description="TIDDL (Tidal Downloader) is a Python CLI application that allows downloading Tidal tracks.", long_description=open("README.md", encoding="utf-8").read(), long_description_content_type="text/markdown", From af95cff73ad044c688db39add3c6d171e5dfea6a Mon Sep 17 00:00:00 2001 From: oskvr37 <oskarxpd@gmail.com> Date: Sun, 29 Dec 2024 10:39:39 +0100 Subject: [PATCH 06/11] =?UTF-8?q?=E2=9C=A8=20skip=20non=20track=20items?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tiddl/__init__.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tiddl/__init__.py b/tiddl/__init__.py index f4b3494..edb23a8 100644 --- a/tiddl/__init__.py +++ b/tiddl/__init__.py @@ -217,6 +217,11 @@ def downloadAlbum(album_id: str | int, skip_existing: bool): for item in album_items["items"]: track = item["item"] + + if item["type"] != "track": + logger.warning(f"item is not a track: {track["title"]} ({track["id"]})") + continue + try: file_dir, file_name = downloadTrack( track, From 22809d08d7598b4ae643b111c3009f2d3ca50006 Mon Sep 17 00:00:00 2001 From: oskvr37 <oskarxpd@gmail.com> Date: Sun, 29 Dec 2024 11:01:50 +0100 Subject: [PATCH 07/11] =?UTF-8?q?=E2=9C=A8=20add=20version=20to=20file=20f?= =?UTF-8?q?ormatting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tiddl/utils.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tiddl/utils.py b/tiddl/utils.py index 334c5e2..dd53155 100644 --- a/tiddl/utils.py +++ b/tiddl/utils.py @@ -72,6 +72,7 @@ class FormattedTrack(TypedDict): released: str year: str playlist_number: str + version: str def formatFilename(template: str, track: Track, playlist=""): @@ -82,6 +83,8 @@ def formatFilename(template: str, track: Track, playlist=""): "%Y-%m-%dT%H:%M:%S.000+0000", ) + version = track.get("version", "") + formatted_track: FormattedTrack = { "album": re.sub(r'[<>:"|?*/\\]', "_", track["album"]["title"].strip()), "artist": track["artist"]["name"].strip(), @@ -94,6 +97,7 @@ def formatFilename(template: str, track: Track, playlist=""): "released": release_date.strftime("%m-%d-%Y"), "year": release_date.strftime("%Y"), "playlist_number": str(track.get("playlistNumber", "")), + "version": f"({version})" if version else "", } dirs = template.split("/") From aaaca1bbc516f2ff41f125cc91db49ae6dcbde92 Mon Sep 17 00:00:00 2001 From: oskvr37 <oskarxpd@gmail.com> Date: Sun, 29 Dec 2024 11:02:36 +0100 Subject: [PATCH 08/11] =?UTF-8?q?=F0=9F=9A=80=20bump=20to=20`1.9.3`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 9de9ca9..f28754e 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="tiddl", - version="1.9.2", + version="1.9.3", description="TIDDL (Tidal Downloader) is a Python CLI application that allows downloading Tidal tracks.", long_description=open("README.md", encoding="utf-8").read(), long_description_content_type="text/markdown", From 6d1e9c975f063dbc69a37aeb6a6578fab6eb31a5 Mon Sep 17 00:00:00 2001 From: oskvr37 <oskarxpd@gmail.com> Date: Tue, 14 Jan 2025 16:44:36 +0100 Subject: [PATCH 09/11] =?UTF-8?q?=F0=9F=90=9B=20fix=20#66?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tiddl/__init__.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/tiddl/__init__.py b/tiddl/__init__.py index edb23a8..7f76146 100644 --- a/tiddl/__init__.py +++ b/tiddl/__init__.py @@ -143,6 +143,11 @@ def downloadTrack( if track.get("status") == 404: raise ValueError(track) + if not track["allowStreaming"]: + logger.warning( + f"The track is not streamable: {track["title"]} ({track["id"]})" + ) + file_dir, file_name = formatFilename(file_template, track, playlist) file_path = f"{download_path}/{file_dir}/{file_name}" @@ -191,7 +196,7 @@ def downloadTrack( with open(file_path, "wb+") as f: f.write(track_data) - if not cover_data: + if not cover_data and track["album"]["cover"]: cover = Cover(track["album"]["cover"]) cover_data = cover.content From 8eaf49cfc1f8fae59c3f2ce857af7a83200d27b7 Mon Sep 17 00:00:00 2001 From: oskvr37 <oskarxpd@gmail.com> Date: Tue, 14 Jan 2025 16:44:58 +0100 Subject: [PATCH 10/11] =?UTF-8?q?=F0=9F=9A=80=20bump=20to=20`1.9.4`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index f28754e..efdc632 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name="tiddl", - version="1.9.3", + version="1.9.4", description="TIDDL (Tidal Downloader) is a Python CLI application that allows downloading Tidal tracks.", long_description=open("README.md", encoding="utf-8").read(), long_description_content_type="text/markdown", From 9602b293fc61b49099c07968cba16004740232d4 Mon Sep 17 00:00:00 2001 From: oskvr37 <oskarxpd@gmail.com> Date: Wed, 15 Jan 2025 19:55:33 +0100 Subject: [PATCH 11/11] fix #66 --- tiddl/__init__.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/tiddl/__init__.py b/tiddl/__init__.py index 7f76146..46f02d7 100644 --- a/tiddl/__init__.py +++ b/tiddl/__init__.py @@ -140,11 +140,8 @@ def downloadTrack( playlist="", cover_data=b"", ) -> tuple[str, str]: - if track.get("status") == 404: - raise ValueError(track) - - if not track["allowStreaming"]: - logger.warning( + if track.get("status", 200) != 200 or not track["allowStreaming"]: + raise ValueError( f"The track is not streamable: {track["title"]} ({track["id"]})" ) @@ -240,8 +237,8 @@ def downloadAlbum(album_id: str | int, skip_existing: bool): if SAVE_COVER: album_cover.save(f"{download_path}/{file_dir}") - except ValueError: - logger.warning(f"track unavailable") + except ValueError as e: + logger.error(e) skip_existing = not args.no_skip failed_input = [] @@ -269,11 +266,14 @@ def downloadAlbum(album_id: str | int, skip_existing: bool): logger.warning(f"{e.error['userMessage']} ({e.error['status']})") continue - downloadTrack( - track, - file_template=track_template, - skip_existing=skip_existing, - ) + try: + downloadTrack( + track, + file_template=track_template, + skip_existing=skip_existing, + ) + except ValueError as e: + logger.error(e) continue