mirror of
https://github.com/oskvr37/tiddl.git
synced 2026-06-13 04:05:08 +03:00
Merge pull request #72 from oskvr37/feat/singles-filter
✨ download eps and singles
This commit is contained in:
@@ -7,7 +7,7 @@ from .url import UrlGroup
|
||||
|
||||
from ..ctx import Context, passContext
|
||||
|
||||
from typing import List, Union
|
||||
from typing import List, Union, Literal
|
||||
|
||||
from tiddl.download import downloadTrackStream
|
||||
from tiddl.utils import formatTrack, trackExists, TidalResource
|
||||
@@ -17,9 +17,13 @@ from tiddl.models.constants import TrackArg, ARG_TO_QUALITY
|
||||
from tiddl.models.resource import Track, Album
|
||||
from tiddl.models.api import PlaylistItems, AlbumItems
|
||||
|
||||
SinglesFilter = Literal["none", "only", "include"]
|
||||
|
||||
|
||||
@click.command("download")
|
||||
@click.option("--quality", "-q", "quality", type=click.Choice(TrackArg.__args__))
|
||||
@click.option(
|
||||
"--quality", "-q", "quality", type=click.Choice(TrackArg.__args__)
|
||||
)
|
||||
@click.option(
|
||||
"--output", "-o", "template", type=str, help="Format track file template."
|
||||
)
|
||||
@@ -31,9 +35,21 @@ from tiddl.models.api import PlaylistItems, AlbumItems
|
||||
default=False,
|
||||
help="Dont skip downloaded tracks.",
|
||||
)
|
||||
@click.option(
|
||||
"--singles",
|
||||
"-s",
|
||||
"singles_filter",
|
||||
type=click.Choice(SinglesFilter.__args__),
|
||||
default="none",
|
||||
help="Defines how to treat artist EPs and singles.",
|
||||
)
|
||||
@passContext
|
||||
def DownloadCommand(
|
||||
ctx: Context, quality: TrackArg | None, template: str | None, noskip: bool
|
||||
ctx: Context,
|
||||
quality: TrackArg | None,
|
||||
template: str | None,
|
||||
noskip: bool,
|
||||
singles_filter: SinglesFilter = "none",
|
||||
):
|
||||
"""Download the tracks"""
|
||||
|
||||
@@ -46,13 +62,17 @@ def DownloadCommand(
|
||||
)
|
||||
return
|
||||
|
||||
download_quality = ARG_TO_QUALITY[quality or ctx.obj.config.download.quality]
|
||||
download_quality = ARG_TO_QUALITY[
|
||||
quality or ctx.obj.config.download.quality
|
||||
]
|
||||
|
||||
# .suffix is needed because the Path.with_suffix method will replace any content after dot
|
||||
# for example: 'album/01. title' becomes 'album/01.m4a'
|
||||
path = ctx.obj.config.download.path / f"{file_name}.suffix"
|
||||
|
||||
if not noskip and trackExists(track.audioQuality, download_quality, path):
|
||||
if not noskip and trackExists(
|
||||
track.audioQuality, download_quality, path
|
||||
):
|
||||
click.echo(
|
||||
f"{click.style('✔', 'cyan')} Skipping track {click.style(file_name, 'cyan')}"
|
||||
)
|
||||
@@ -109,14 +129,17 @@ def DownloadCommand(
|
||||
album_artist=album.artist.name,
|
||||
)
|
||||
|
||||
downloadTrack(track=track, file_name=file_name, cover_data=cover_data)
|
||||
downloadTrack(
|
||||
track=track, file_name=file_name, cover_data=cover_data
|
||||
)
|
||||
|
||||
def handleResource(resource: TidalResource):
|
||||
match resource.type:
|
||||
case "track":
|
||||
track = api.getTrack(resource.id)
|
||||
file_name = formatTrack(
|
||||
template=template or ctx.obj.config.template.track, track=track
|
||||
template=template or ctx.obj.config.template.track,
|
||||
track=track,
|
||||
)
|
||||
|
||||
downloadTrack(
|
||||
@@ -130,20 +153,35 @@ def DownloadCommand(
|
||||
downloadAlbum(album)
|
||||
|
||||
case "artist":
|
||||
# TODO: add `include_singles`
|
||||
all_albums: List[Album] = []
|
||||
offset = 0
|
||||
|
||||
while True:
|
||||
items = api.getArtistAlbums(resource.id, offset=offset)
|
||||
all_albums.extend(items.items)
|
||||
def getAllAlbums(singles: bool):
|
||||
all_albums: List[Album] = []
|
||||
offset = 0
|
||||
|
||||
if items.limit + items.offset > items.totalNumberOfItems:
|
||||
break
|
||||
while True:
|
||||
items = api.getArtistAlbums(
|
||||
resource.id,
|
||||
offset=offset,
|
||||
filter="EPSANDSINGLES" if singles else "ALBUMS",
|
||||
)
|
||||
all_albums.extend(items.items)
|
||||
|
||||
offset += items.limit
|
||||
if (
|
||||
items.limit + items.offset
|
||||
> items.totalNumberOfItems
|
||||
):
|
||||
break
|
||||
|
||||
for album in all_albums:
|
||||
offset += items.limit
|
||||
|
||||
return all_albums
|
||||
|
||||
if singles_filter == "include":
|
||||
albums = getAllAlbums(False) + getAllAlbums(True)
|
||||
else:
|
||||
albums = getAllAlbums(singles_filter == "only")
|
||||
|
||||
for album in albums:
|
||||
downloadAlbum(album)
|
||||
|
||||
case "playlist":
|
||||
@@ -174,7 +212,8 @@ def DownloadCommand(
|
||||
track = item.item
|
||||
|
||||
file_name = formatTrack(
|
||||
template=template or ctx.obj.config.template.playlist,
|
||||
template=template
|
||||
or ctx.obj.config.template.playlist,
|
||||
track=track,
|
||||
playlist_title=playlist.title,
|
||||
playlist_index=track.index // 100000,
|
||||
|
||||
Reference in New Issue
Block a user