mirror of
https://github.com/oskvr37/tiddl.git
synced 2026-06-13 04:05:08 +03:00
🎨 Format code
This commit is contained in:
+4
-10
@@ -26,7 +26,7 @@ from tiddl.models.api import (
|
||||
TrackStream,
|
||||
Video,
|
||||
VideoStream,
|
||||
Lyrics
|
||||
Lyrics,
|
||||
)
|
||||
|
||||
from tiddl.models.constants import TrackQuality
|
||||
@@ -124,9 +124,7 @@ class TidalApi:
|
||||
Album, f"albums/{album_id}", {"countryCode": self.country_code}
|
||||
)
|
||||
|
||||
def getAlbumItems(
|
||||
self, album_id: str | int, limit=LIMITS.ALBUM_ITEMS, offset=0
|
||||
):
|
||||
def getAlbumItems(self, album_id: str | int, limit=LIMITS.ALBUM_ITEMS, offset=0):
|
||||
return self.fetch(
|
||||
AlbumItems,
|
||||
f"albums/{album_id}/items",
|
||||
@@ -192,9 +190,7 @@ class TidalApi:
|
||||
{"countryCode": self.country_code},
|
||||
)
|
||||
|
||||
def getPlaylistItems(
|
||||
self, playlist_uuid: str, limit=LIMITS.PLAYLIST, offset=0
|
||||
):
|
||||
def getPlaylistItems(self, playlist_uuid: str, limit=LIMITS.PLAYLIST, offset=0):
|
||||
return self.fetch(
|
||||
PlaylistItems,
|
||||
f"playlists/{playlist_uuid}/items",
|
||||
@@ -215,9 +211,7 @@ class TidalApi:
|
||||
)
|
||||
|
||||
def getSession(self):
|
||||
return self.fetch(
|
||||
SessionResponse, "sessions", expire_after=DO_NOT_CACHE
|
||||
)
|
||||
return self.fetch(SessionResponse, "sessions", expire_after=DO_NOT_CACHE)
|
||||
|
||||
def getLyrics(self, track_id: str | int):
|
||||
return self.fetch(
|
||||
|
||||
@@ -34,18 +34,14 @@ def cli(ctx: Context, verbose: bool, quiet: bool, no_cache: bool):
|
||||
)
|
||||
)
|
||||
|
||||
LEVEL = (
|
||||
logging.DEBUG if verbose else logging.ERROR if quiet else logging.INFO
|
||||
)
|
||||
LEVEL = logging.DEBUG if verbose else logging.ERROR if quiet else logging.INFO
|
||||
|
||||
rich_handler = RichHandler(console=ctx.obj.console, rich_tracebacks=True)
|
||||
rich_handler.setLevel(LEVEL)
|
||||
|
||||
if LEVEL == logging.DEBUG:
|
||||
rich_handler.setFormatter(
|
||||
logging.Formatter(
|
||||
"[%(name)s.%(funcName)s] %(message)s", datefmt="[%X]"
|
||||
)
|
||||
logging.Formatter("[%(name)s.%(funcName)s] %(message)s", datefmt="[%X]")
|
||||
)
|
||||
|
||||
logging.basicConfig(
|
||||
|
||||
@@ -111,7 +111,7 @@ def DownloadCommand(
|
||||
SINGLES_FILTER: SinglesFilter,
|
||||
EMBED_LYRICS: bool,
|
||||
DOWNLOAD_VIDEO: bool,
|
||||
SCAN_PATH: str | None
|
||||
SCAN_PATH: str | None,
|
||||
):
|
||||
"""Download resources"""
|
||||
DOWNLOAD_VIDEO = DOWNLOAD_VIDEO or ctx.obj.config.download.download_video
|
||||
@@ -127,7 +127,7 @@ def DownloadCommand(
|
||||
THREADS_COUNT,
|
||||
DO_NOT_SKIP,
|
||||
SINGLES_FILTER,
|
||||
EMBED_LYRICS
|
||||
EMBED_LYRICS,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -216,13 +216,15 @@ def DownloadCommand(
|
||||
|
||||
if isinstance(item, Track):
|
||||
if track_stream.audioQuality == "HI_RES_LOSSLESS":
|
||||
path = asyncio.run(convertFileExtension(
|
||||
source_file=path,
|
||||
extension=".flac",
|
||||
remove_source=True,
|
||||
is_video=False,
|
||||
copy_audio=True, # extract flac from m4a container
|
||||
))
|
||||
path = asyncio.run(
|
||||
convertFileExtension(
|
||||
source_file=path,
|
||||
extension=".flac",
|
||||
remove_source=True,
|
||||
is_video=False,
|
||||
copy_audio=True, # extract flac from m4a container
|
||||
)
|
||||
)
|
||||
|
||||
if not cover_data and item.album.cover:
|
||||
cover_data = Cover(item.album.cover).content
|
||||
@@ -233,18 +235,27 @@ def DownloadCommand(
|
||||
lyrics_subtitles = ""
|
||||
|
||||
try:
|
||||
addMetadata(path, item, cover_data, credits, album_artist=album_artist, lyrics=lyrics_subtitles)
|
||||
addMetadata(
|
||||
path,
|
||||
item,
|
||||
cover_data,
|
||||
credits,
|
||||
album_artist=album_artist,
|
||||
lyrics=lyrics_subtitles,
|
||||
)
|
||||
except Exception as e:
|
||||
logging.error(f"Can not add metadata to: {path}, {e}")
|
||||
|
||||
elif isinstance(item, Video):
|
||||
path = asyncio.run(convertFileExtension(
|
||||
source_file=path,
|
||||
extension=".mp4",
|
||||
remove_source=True,
|
||||
is_video=True,
|
||||
copy_audio=True,
|
||||
))
|
||||
path = asyncio.run(
|
||||
convertFileExtension(
|
||||
source_file=path,
|
||||
extension=".mp4",
|
||||
remove_source=True,
|
||||
is_video=True,
|
||||
copy_audio=True,
|
||||
)
|
||||
)
|
||||
|
||||
try:
|
||||
addVideoMetadata(path, item)
|
||||
@@ -273,14 +284,20 @@ def DownloadCommand(
|
||||
|
||||
path = Path(PATH) if PATH else ctx.obj.config.download.path
|
||||
path /= f"{filename}.*"
|
||||
scan_path = Path(SCAN_PATH or ctx.obj.config.download.scan_path) / f"{filename}.*" if (SCAN_PATH or ctx.obj.config.download.scan_path) else path # Scan scan_path if set, else scans 'path'.
|
||||
scan_path = (
|
||||
Path(SCAN_PATH or ctx.obj.config.download.scan_path) / f"{filename}.*"
|
||||
if (SCAN_PATH or ctx.obj.config.download.scan_path)
|
||||
else path
|
||||
) # Scan scan_path if set, else scans 'path'.
|
||||
|
||||
# Respect DOWNLOAD_VIDEO = FALSE over DO_NOT_SKIP (as it's for the file exists check)
|
||||
if isinstance(item, Video) and not DOWNLOAD_VIDEO:
|
||||
logging.warning(f"Video '{item.title}' skipped as DOWNLOAD_VIDEO is false")
|
||||
return
|
||||
|
||||
if not DO_NOT_SKIP: # check if item is already downloaded (unless DO_NOT_SKIP is set, then override anything)
|
||||
if (
|
||||
not DO_NOT_SKIP
|
||||
): # check if item is already downloaded (unless DO_NOT_SKIP is set, then override anything)
|
||||
if isinstance(item, Track):
|
||||
if trackExists(item.audioQuality, DOWNLOAD_QUALITY, scan_path):
|
||||
logging.warning(f"Track '{item.title}' skipped - exists")
|
||||
|
||||
@@ -3,7 +3,13 @@ import click
|
||||
from tiddl.utils import TidalResource, ResourceTypeLiteral
|
||||
from tiddl.cli.ctx import Context, passContext
|
||||
|
||||
ResourceTypeList: list[ResourceTypeLiteral] = ["track", "video", "album", "artist", "playlist"]
|
||||
ResourceTypeList: list[ResourceTypeLiteral] = [
|
||||
"track",
|
||||
"video",
|
||||
"album",
|
||||
"artist",
|
||||
"playlist",
|
||||
]
|
||||
|
||||
|
||||
@click.group("fav")
|
||||
|
||||
@@ -15,6 +15,7 @@ makedirs(HOME_PATH, exist_ok=True)
|
||||
CONFIG_PATH = HOME_PATH / "tiddl.json"
|
||||
CONFIG_INDENT = 2
|
||||
|
||||
|
||||
class TemplateConfig(BaseModel):
|
||||
track: str = "{artist} - {title}"
|
||||
video: str = "{artist} - {title}"
|
||||
|
||||
+1
-3
@@ -80,9 +80,7 @@ def parseTrackStream(track_stream: TrackStream) -> tuple[list[str], str]:
|
||||
elif codecs.startswith("mp4"):
|
||||
file_extension = ".m4a"
|
||||
else:
|
||||
raise ValueError(
|
||||
f"Unknown codecs `{codecs}` (trackId {track_stream.trackId}"
|
||||
)
|
||||
raise ValueError(f"Unknown codecs `{codecs}` (trackId {track_stream.trackId}")
|
||||
|
||||
return urls, file_extension
|
||||
|
||||
|
||||
+16
-20
@@ -40,8 +40,12 @@ def addMetadata(
|
||||
picture.mime = "image/jpeg"
|
||||
metadata.add_picture(picture)
|
||||
|
||||
metadata["TITLE"] = track.title + (" ({})".format(track.version) if track.version else "")
|
||||
metadata["WORK"] = track.title + (" ({})".format(track.version) if track.version else "")
|
||||
metadata["TITLE"] = track.title + (
|
||||
" ({})".format(track.version) if track.version else ""
|
||||
)
|
||||
metadata["WORK"] = track.title + (
|
||||
" ({})".format(track.version) if track.version else ""
|
||||
)
|
||||
metadata["TRACKNUMBER"] = str(track.trackNumber)
|
||||
metadata["DISCNUMBER"] = str(track.volumeNumber)
|
||||
|
||||
@@ -58,9 +62,7 @@ def addMetadata(
|
||||
|
||||
if track.streamStartDate:
|
||||
metadata["DATE"] = track.streamStartDate.strftime("%Y-%m-%d")
|
||||
metadata["ORIGINALDATE"] = track.streamStartDate.strftime(
|
||||
"%Y-%m-%d"
|
||||
)
|
||||
metadata["ORIGINALDATE"] = track.streamStartDate.strftime("%Y-%m-%d")
|
||||
metadata["YEAR"] = str(track.streamStartDate.strftime("%Y"))
|
||||
metadata["ORIGINALYEAR"] = str(track.streamStartDate.strftime("%Y"))
|
||||
|
||||
@@ -102,13 +104,9 @@ def addMetadata(
|
||||
"discnumber": str(track.volumeNumber),
|
||||
"copyright": track.copyright if track.copyright else "",
|
||||
"albumartist": track.artist.name if track.artist else "",
|
||||
"artist": ";".join(
|
||||
[artist.name.strip() for artist in track.artists]
|
||||
),
|
||||
"artist": ";".join([artist.name.strip() for artist in track.artists]),
|
||||
"album": track.album.title,
|
||||
"date": str(track.streamStartDate)
|
||||
if track.streamStartDate
|
||||
else "",
|
||||
"date": str(track.streamStartDate) if track.streamStartDate else "",
|
||||
"bpm": str(track.bpm or 0),
|
||||
}
|
||||
)
|
||||
@@ -129,9 +127,7 @@ def addVideoMetadata(path: Path, video: Video):
|
||||
{
|
||||
"title": video.title,
|
||||
"albumartist": video.artist.name if video.artist else "",
|
||||
"artist": ";".join(
|
||||
[artist.name.strip() for artist in video.artists]
|
||||
),
|
||||
"artist": ";".join([artist.name.strip() for artist in video.artists]),
|
||||
"album": video.album.title if video.album else "",
|
||||
"date": str(video.streamStartDate) if video.streamStartDate else "",
|
||||
}
|
||||
@@ -162,7 +158,9 @@ class Cover:
|
||||
self.uid = uid
|
||||
|
||||
formatted_uid = uid.replace("-", "/")
|
||||
self.url = f"https://resources.tidal.com/images/{formatted_uid}/{size}x{size}.jpg"
|
||||
self.url = (
|
||||
f"https://resources.tidal.com/images/{formatted_uid}/{size}x{size}.jpg"
|
||||
)
|
||||
|
||||
logger.debug((self.uid, self.url))
|
||||
|
||||
@@ -172,9 +170,7 @@ class Cover:
|
||||
req = requests.get(self.url)
|
||||
|
||||
if req.status_code != 200:
|
||||
logger.error(
|
||||
f"could not download cover. ({req.status_code}) {self.url}"
|
||||
)
|
||||
logger.error(f"could not download cover. ({req.status_code}) {self.url}")
|
||||
return b""
|
||||
|
||||
logger.debug(f"got cover: {self.uid}")
|
||||
@@ -185,13 +181,13 @@ class Cover:
|
||||
if not self.content:
|
||||
logger.error("cover file content is empty")
|
||||
return
|
||||
|
||||
|
||||
file = directory_path / filename
|
||||
|
||||
if file.exists():
|
||||
logger.debug(f"cover already exists ({file})")
|
||||
return
|
||||
|
||||
|
||||
makedirs(directory_path, exist_ok=True)
|
||||
|
||||
try:
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ __all__ = [
|
||||
"Favorites",
|
||||
"TrackStream",
|
||||
"Search",
|
||||
"Lyrics"
|
||||
"Lyrics",
|
||||
]
|
||||
|
||||
|
||||
|
||||
+5
-7
@@ -80,9 +80,7 @@ def formatTrack(
|
||||
"disc": track.volumeNumber,
|
||||
"date": (track.streamStartDate if track.streamStartDate else ""),
|
||||
# i think we can remove year as we are able to format date
|
||||
"year": track.streamStartDate.strftime("%Y")
|
||||
if track.streamStartDate
|
||||
else "",
|
||||
"year": track.streamStartDate.strftime("%Y") if track.streamStartDate else "",
|
||||
"playlist": sanitizeString(playlist_title),
|
||||
"bpm": track.bpm or "",
|
||||
"quality": QUALITY_TO_ARG[track.audioQuality],
|
||||
@@ -130,9 +128,9 @@ def formatResource(
|
||||
"disc": resource.volumeNumber,
|
||||
"date": (resource.streamStartDate if resource.streamStartDate else ""),
|
||||
# i think we can remove year as we are able to format date
|
||||
"year": resource.streamStartDate.strftime("%Y")
|
||||
if resource.streamStartDate
|
||||
else "",
|
||||
"year": (
|
||||
resource.streamStartDate.strftime("%Y") if resource.streamStartDate else ""
|
||||
),
|
||||
"playlist": sanitizeString(playlist_title),
|
||||
"album_artist": sanitizeString(album_artist),
|
||||
"playlist_number": playlist_index or 0,
|
||||
@@ -223,7 +221,6 @@ async def convertFileExtension(
|
||||
ffmpeg.input(str(source_file))
|
||||
ffmpeg.output(str(output_file), **ffmpeg_args)
|
||||
|
||||
|
||||
@ffmpeg.on("completed")
|
||||
def on_completed():
|
||||
logging.debug("Conversion successful for: %s", output_file)
|
||||
@@ -232,6 +229,7 @@ async def convertFileExtension(
|
||||
os.remove(source_file)
|
||||
except OSError as e:
|
||||
logging.error(f"Error removing source file {source_file}: {e}")
|
||||
|
||||
await ffmpeg.execute()
|
||||
except Exception as e:
|
||||
logging.error(f"FFMPEG Error during conversion of {source_file}: {e}")
|
||||
|
||||
Reference in New Issue
Block a user