From 1137fe26596f6be069021998d1d161aa5e44fe6b Mon Sep 17 00:00:00 2001 From: Robert Honz Date: Thu, 1 Feb 2024 20:10:14 +0100 Subject: [PATCH 1/2] =?UTF-8?q?=E2=9C=A8=20Rename=20lyrics=20option=20and?= =?UTF-8?q?=20add=20lyrics=20to=20file=20options.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tidal_dl_ng/download.py | 2 +- tidal_dl_ng/model/cfg.py | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/tidal_dl_ng/download.py b/tidal_dl_ng/download.py index fb7db37..04ba1f7 100644 --- a/tidal_dl_ng/download.py +++ b/tidal_dl_ng/download.py @@ -269,7 +269,7 @@ class Download: isrc: str = track.isrc if hasattr(track, "isrc") and track.isrc else "" lyrics: str = "" - if self.settings.data.lyrics_save: + if self.settings.data.lyrics_embed: # Try to retrieve lyrics. try: lyrics: str = track.lyrics().subtitles if hasattr(track, "lyrics") else "" diff --git a/tidal_dl_ng/model/cfg.py b/tidal_dl_ng/model/cfg.py index 9fc4170..0af7f84 100644 --- a/tidal_dl_ng/model/cfg.py +++ b/tidal_dl_ng/model/cfg.py @@ -12,7 +12,8 @@ class Settings: skip_existing: SkipExisting = SkipExisting.Disabled # TODO: Implement cover download to a separate file. # album_cover_save: bool = True - lyrics_save: bool = False + lyrics_embed: bool = False + lyrics_file: bool = False # TODO: Implement API KEY selection. # api_key_index: bool = 0 # TODO: Implement album info download to separate file. @@ -41,7 +42,8 @@ class HelpSettings: "different file extension exists." ) album_cover_save: str = "Safe cover to album folder." - lyrics_save: str = "Safe lyrics to audio file." + lyrics_embed: str = "Embed lyrics in audio file." + lyrics_file: str = "Save lyrics to separate *.lrc file." api_key_index: str = "Set the device API KEY." album_info_save: str = "Save album info to track?" video_download: str = "Allow download of videos." From f94cd0d51cf1b6534dcf563cc4aa2d2ca9387c4a Mon Sep 17 00:00:00 2001 From: Robert Honz Date: Thu, 1 Feb 2024 20:53:45 +0100 Subject: [PATCH 2/2] =?UTF-8?q?=E2=9C=A8=20Lyrics=20are=20downloaded=20to?= =?UTF-8?q?=20separate=20*.lrc=20file.=20Implements=20#19?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tidal_dl_ng/constants.py | 1 + tidal_dl_ng/download.py | 29 ++++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/tidal_dl_ng/constants.py b/tidal_dl_ng/constants.py index 8c8fd6a..1348a74 100644 --- a/tidal_dl_ng/constants.py +++ b/tidal_dl_ng/constants.py @@ -2,6 +2,7 @@ from enum import Enum CTX_TIDAL: str = "tidal" REQUESTS_TIMEOUT_SEC = 45 +EXTENSION_LYRICS = ".lrc" class QualityVideo(Enum): diff --git a/tidal_dl_ng/download.py b/tidal_dl_ng/download.py index 04ba1f7..e67ce96 100644 --- a/tidal_dl_ng/download.py +++ b/tidal_dl_ng/download.py @@ -18,6 +18,7 @@ from tidalapi import Album, Mix, Playlist, Session, Track, UserPlaylist, Video from tidal_dl_ng.config import Settings from tidal_dl_ng.constants import ( + EXTENSION_LYRICS, REQUESTS_TIMEOUT_SEC, AudioExtensions, CoverDimensions, @@ -239,6 +240,10 @@ class Download: # Move final file to the configured destination directory. os.makedirs(os.path.dirname(path_file), exist_ok=True) shutil.move(tmp_path_file, path_file) + + # Move lyrics file + if self.settings.data.lyrics_file: + self._move_lyrics(path_file, tmp_path_file) else: self.fn_logger.debug(f"Download skipped, since file exists: '{path_file}'") @@ -254,12 +259,31 @@ class Download: return not download_skip, path_file + def _move_lyrics(self, file_media_dst: str, file_media_src: str): + # Build tmp lyrics filename + tmp_lyrics_file_path: str = file_media_src + EXTENSION_LYRICS + # Check if the file was downloaded + if os.path.isfile(tmp_lyrics_file_path): + # Move it. + shutil.move(tmp_lyrics_file_path, os.path.splitext(file_media_dst)[0] + EXTENSION_LYRICS) + def cover_url(self, sid: str, dimension: CoverDimensions = CoverDimensions.Px320): if sid is None: return "" return f"https://resources.tidal.com/images/{sid.replace('-', '/')}/{dimension.value}.jpg" + def lyrics_write_file(self, file_path: str, lyrics: str) -> str: + result: str = file_path + + try: + with open(file_path, "x", encoding="utf-8") as f: + f.write(lyrics) + except: + result = "" + + return result + def metadata_write(self, track: Track, path_file: str): result: bool = False release_date: str = ( @@ -269,7 +293,7 @@ class Download: isrc: str = track.isrc if hasattr(track, "isrc") and track.isrc else "" lyrics: str = "" - if self.settings.data.lyrics_embed: + if self.settings.data.lyrics_embed or self.settings.data.lyrics_file: # Try to retrieve lyrics. try: lyrics: str = track.lyrics().subtitles if hasattr(track, "lyrics") else "" @@ -277,6 +301,9 @@ class Download: # TODO: Implement proper logging. print(f"Could not retrieve lyrics for `{name_builder_item(track)}`.") + if lyrics: + self.lyrics_write_file(path_file + EXTENSION_LYRICS, lyrics) + # `None` values are not allowed. m: Metadata = Metadata( path_file=path_file,