diff --git a/pyproject.toml b/pyproject.toml index 8822ce4..7909235 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "tiddl" -version = "2.7.0" +version = "2.8.0a1" description = "Download Tidal tracks with CLI downloader." readme = "README.md" requires-python = ">=3.11" diff --git a/tiddl/api.py b/tiddl/api.py index 662cfd8..66246df 100644 --- a/tiddl/api.py +++ b/tiddl/api.py @@ -17,6 +17,7 @@ from tiddl.models.api import ( AlbumItemsCredits, Artist, ArtistAlbumsItems, + ArtistVideosItems, Favorites, Playlist, PlaylistItems, @@ -51,6 +52,7 @@ def ensureLimit(limit: int, max_limit: int) -> int: class Limits: ARTIST_ALBUMS = 50 + ARTIST_VIDEOS = 50 ALBUM_ITEMS = 10 ALBUM_ITEMS_MAX = 100 PLAYLIST = 50 @@ -177,6 +179,23 @@ class TidalApi: expire_after=3600, ) + def getArtistVideos( + self, + artist_id: str | int, + limit: int = LIMITS.ARTIST_VIDEOS, + offset: int = 0, + ): + return self.fetch( + ArtistVideosItems, + f"artists/{artist_id}/videos", + { + "countryCode": self.country_code, + "limit": limit, + "offset": offset, + }, + expire_after=3600, + ) + def getMix( self, mix_id: str | int, diff --git a/tiddl/cli/download/__init__.py b/tiddl/cli/download/__init__.py index b570a26..045268a 100644 --- a/tiddl/cli/download/__init__.py +++ b/tiddl/cli/download/__init__.py @@ -99,6 +99,13 @@ logger = logging.getLogger(__name__) is_flag=True, help="Enable downloading videos", ) +@click.option( + "--only-video", + "-ov", + "ONLY_VIDEO", + is_flag=True, + help="Download only videos from an artist.", +) @click.option( "--scan-path", "SCAN_PATH", @@ -123,6 +130,7 @@ def DownloadCommand( SINGLES_FILTER: SinglesFilter, EMBED_LYRICS: bool, DOWNLOAD_VIDEO: bool, + ONLY_VIDEO: bool, SCAN_PATH: str | None, SAVE_M3U: bool, ): @@ -432,6 +440,26 @@ def DownloadCommand( artist = api.getArtist(resource.id) logger.info(f"Artist {artist.name!r}") + if ONLY_VIDEO: + offset = 0 + + while True: + artist_videos = api.getArtistVideos(resource.id, offset=offset) + + for video in artist_videos.items: + filename = formatResource( + TEMPLATE or ctx.obj.config.template.video, video + ) + + submitItem(video, filename) + + if offset > artist_videos.totalNumberOfItems: + break + + offset += artist_videos.limit + + return + def getAllAlbums(singles: bool): offset = 0 diff --git a/tiddl/models/api.py b/tiddl/models/api.py index 02933ad..3bf34a6 100644 --- a/tiddl/models/api.py +++ b/tiddl/models/api.py @@ -6,6 +6,7 @@ from tiddl.models.resource import Album, Artist, Playlist, Track, TrackQuality, __all__ = [ "SessionResponse", "ArtistAlbumsItems", + "ArtistVideosItems", "AlbumItems", "PlaylistItems", "Favorites", @@ -39,6 +40,8 @@ class Items(BaseModel): class ArtistAlbumsItems(Items): items: List[Album] +class ArtistVideosItems(Items): + items: List[Video] ItemType = Literal["track", "video"]