Merge pull request #378 from exislow/374-remove-when-downloading-much-files

👷 CLI: Download list is scrolling vertically and overall progress is …
This commit is contained in:
exislow
2025-03-01 21:54:21 +01:00
committed by GitHub
2 changed files with 78 additions and 48 deletions
+36 -9
View File
@@ -4,9 +4,16 @@ from pathlib import Path
from typing import Annotated, Optional
import typer
from rich.console import Group
from rich.live import Live
from rich.panel import Panel
from rich.progress import BarColumn, Console, Progress, SpinnerColumn, TextColumn
from rich.progress import (
BarColumn,
Console,
Progress,
SpinnerColumn,
TaskProgressColumn,
TextColumn,
)
from rich.table import Table
from tidal_dl_ng import __version__
@@ -58,10 +65,20 @@ def _download(ctx: typer.Context, urls: list[str], try_login: bool = True) -> bo
# Create initial objects.
settings: Settings = Settings()
progress: Progress = Progress(
"{task.description}",
TextColumn("[progress.description]{task.description}"),
SpinnerColumn(),
BarColumn(),
TextColumn("[progress.percentage]{task.percentage:>3.0f}%"),
TaskProgressColumn(),
refresh_per_second=20,
auto_refresh=True,
expand=True,
transient=False, # Prevent progress from disappearing
)
progress_overall = Progress(
TextColumn("[progress.description]{task.description}"),
SpinnerColumn(),
BarColumn(),
TaskProgressColumn(),
refresh_per_second=20,
auto_refresh=True,
expand=True,
@@ -74,16 +91,24 @@ def _download(ctx: typer.Context, urls: list[str], try_login: bool = True) -> bo
path_base=settings.data.download_base_path,
fn_logger=fn_logger,
progress=progress,
progress_overall=progress_overall,
)
progress_table = Table.grid()
# Style Progress display.
progress_table.add_row(Panel.fit(progress, title="Download Progress", border_style="green", padding=(2, 2)))
progress_table.add_row(progress)
progress_table.add_row(progress_overall)
progress_group = Group(
progress_table,
)
urls_pos_last = len(urls) - 1
# Use a single Live display for both progress and table
with Live(progress_table, refresh_per_second=20):
with Live(progress_group, refresh_per_second=20, vertical_overflow="visible"):
try:
for item in urls:
media_type: MediaType | bool = False
@@ -102,7 +127,10 @@ def _download(ctx: typer.Context, urls: list[str], try_login: bool = True) -> bo
download_delay: bool = bool(settings.data.download_delay and urls.index(item) < urls_pos_last)
dl.item(
media_id=item_id, media_type=media_type, file_template=file_template, download_delay=download_delay
media_id=item_id,
media_type=media_type,
file_template=file_template,
download_delay=download_delay,
)
elif media_type in [MediaType.ALBUM, MediaType.PLAYLIST, MediaType.MIX, MediaType.ARTIST]:
item_ids: [int] = []
@@ -122,11 +150,10 @@ def _download(ctx: typer.Context, urls: list[str], try_login: bool = True) -> bo
video_download=ctx.obj[CTX_TIDAL].settings.data.video_download,
download_delay=settings.data.download_delay,
)
finally:
# Clear and stop progress display
progress.refresh()
progress.stop()
print("\nDownload completed!")
return True
+10 -7
View File
@@ -73,6 +73,7 @@ class Download:
fn_logger: Callable
progress_gui: ProgressBars
progress: Progress
progress_overall: Progress
def __init__(
self,
@@ -82,6 +83,7 @@ class Download:
skip_existing: bool = False,
progress_gui: ProgressBars = None,
progress: Progress = None,
progress_overall: Progress = None,
):
self.settings = Settings()
self.session = session
@@ -89,6 +91,7 @@ class Download:
self.fn_logger = fn_logger
self.progress_gui = progress_gui
self.progress = progress
self.progress_overall = progress_overall
self.path_base = path_base
if not self.settings.data.path_binary_ffmpeg and (
@@ -150,8 +153,6 @@ class Download:
total_size_in_bytes: int = int(r.headers.get("content-length", 0))
block_size: int | None = 1048576
progress_total: float = total_size_in_bytes / block_size
except:
raise
finally:
r.close()
else:
@@ -709,10 +710,12 @@ class Download:
progress_stdout: bool = True
else:
progress_stdout: bool = False
self.progress_gui.list_name.emit(list_media_name_short[:30])
self.progress_gui.list_name.emit(list_media_name_short)
progress: Progress = self.progress_overall if self.progress_overall else self.progress
# Create the list progress task.
p_task1: TaskID = self.progress.add_task(
p_task1: TaskID = progress.add_task(
f"[green]List '{list_media_name_short}'", total=len(items), visible=progress_stdout
)
@@ -720,7 +723,7 @@ class Download:
result_dirs: [pathlib.Path] = []
# Iterate through list items
while not self.progress.finished:
while not progress.finished:
with futures.ThreadPoolExecutor(max_workers=self.settings.data.downloads_concurrent_max) as executor:
# Dispatch all download tasks to worker threads
l_futures: [any] = [
@@ -744,10 +747,10 @@ class Download:
result_dirs.append(result_path_file.parent)
# Advance progress bar.
self.progress.advance(p_task1)
progress.advance(p_task1)
if not progress_stdout:
self.progress_gui.list_item.emit(self.progress.tasks[p_task1].percentage)
self.progress_gui.list_item.emit(progress.tasks[p_task1].percentage)
# Create playlist file
if self.settings.data.playlist_create: