diff --git a/tiddl/cli/download/__init__.py b/tiddl/cli/download/__init__.py index 6c86f9e..daa7c9e 100644 --- a/tiddl/cli/download/__init__.py +++ b/tiddl/cli/download/__init__.py @@ -1,12 +1,14 @@ import logging import click +from time import perf_counter from concurrent.futures import ThreadPoolExecutor from pathlib import Path from requests import Session +from rich.highlighter import ReprHighlighter from rich.progress import ( - BarColumn, + SpinnerColumn, Progress, TextColumn, ) @@ -106,8 +108,12 @@ def DownloadCommand( api = ctx.obj.getApi() progress = Progress( - TextColumn("{task.description}"), - BarColumn(bar_width=40), + SpinnerColumn(), + TextColumn( + "{task.description} • " + "{task.fields[speed]:.2f} Mbps • {task.fields[size]:.2f} MB", + highlighter=ReprHighlighter(), + ), console=ctx.obj.console, transient=True, auto_refresh=True, @@ -121,8 +127,8 @@ def DownloadCommand( ): if isinstance(item, Track): track_stream = api.getTrackStream(item.id, quality=DOWNLOAD_QUALITY) - logging.info( - f"★ Track '{item.title}' " + description = ( + f"Track '{item.title}' " f"{(str(track_stream.bitDepth) + ' bit') if track_stream.bitDepth else ''} " f"{str(track_stream.sampleRate) + ' kHz' if track_stream.sampleRate else ''}" ) @@ -130,8 +136,8 @@ def DownloadCommand( urls, extension = parseTrackStream(track_stream) elif isinstance(item, Video): video_stream = api.getVideoStream(item.id) - logging.info( - f"★ Video '{item.title}' {video_stream.videoQuality} quality" + description = ( + f"Video '{item.title}' {video_stream.videoQuality} quality" ) urls = parseVideoStream(video_stream) @@ -143,14 +149,18 @@ def DownloadCommand( ) task_id = progress.add_task( - description=f"{type(item).__name__}: {item.title}", + description=description, start=True, visible=True, - total=len(urls), + total=None, + # fields + speed=0, + size=0, ) with Session() as s: stream_data = b"" + time_start = perf_counter() for url in urls: req = s.get(url) @@ -162,7 +172,18 @@ def DownloadCommand( ) stream_data += req.content - progress.advance(task_id) + speed = ( + len(stream_data) + / (perf_counter() - time_start) + / (1024 * 128) + ) + size = len(stream_data) / 1024**2 + progress.update( + task_id, + advance=len(req.content), + speed=speed, + size=size, + ) path = path.with_suffix(extension) path.parent.mkdir(parents=True, exist_ok=True) @@ -203,7 +224,7 @@ def DownloadCommand( logging.error(f"Can not add metadata to: {path}, {e}") progress.remove_task(task_id) - logging.info(f"✔ '{item.title}'") + logging.info(f"{item.title!r} • {speed:.2f} Mbps • {size:.2f} MB") pool = ThreadPoolExecutor( max_workers=THREADS_COUNT or ctx.obj.config.download.threads @@ -243,7 +264,7 @@ def DownloadCommand( ) def downloadAlbum(album: Album): - logging.info(f"★ Album '{album.title}'") + logging.info(f"Album {album.title!r}") cover_data = Cover(album.cover).content if album.cover else b"" @@ -296,7 +317,7 @@ def DownloadCommand( case "artist": artist = api.getArtist(resource.id) - logging.info(f"★ Artist '{artist.name}'") + logging.info(f"Artist {artist.name!r}") def getAllAlbums(singles: bool): offset = 0 @@ -327,7 +348,7 @@ def DownloadCommand( case "playlist": playlist = api.getPlaylist(resource.id) - logging.info(f"★ Playlist '{playlist.title}'") + logging.info(f"Playlist {playlist.title!r}") offset = 0 while True: