From 432a1122c55ca5c6556b1a941c889fa331b4a7f5 Mon Sep 17 00:00:00 2001 From: rlaphoenix Date: Fri, 3 Mar 2023 01:59:29 +0000 Subject: [PATCH] Fix printing of aria2c logs when capturing progress --- devine/core/downloaders/aria2c.py | 71 ++++++++++++++++--------------- 1 file changed, 37 insertions(+), 34 deletions(-) diff --git a/devine/core/downloaders/aria2c.py b/devine/core/downloaders/aria2c.py index 2e6d701..2caec7f 100644 --- a/devine/core/downloaders/aria2c.py +++ b/devine/core/downloaders/aria2c.py @@ -1,4 +1,5 @@ import subprocess +import textwrap from functools import partial from pathlib import Path from typing import Optional, Union @@ -87,44 +88,46 @@ def aria2c( p = subprocess.Popen( [executable, *arguments], stdin=subprocess.PIPE, - stderr=[None, subprocess.DEVNULL][silent], - stdout=( - subprocess.PIPE if progress else - subprocess.DEVNULL if silent else - None - ), + stdout=[subprocess.PIPE, subprocess.DEVNULL][silent], universal_newlines=True ) p._stdin_write(uri) # noqa - if progress: - is_dl_summary = False - for line in iter(p.stdout.readline, ""): - line = line.strip() - if line: - if line.startswith("[") and line.endswith("]"): - if "%" in line: - # id, dledMiB/totalMiB(x%), CN:xx, DL:xxMiB, ETA:Xs - # eta may not always be available - data_parts = line[1:-1].split() - perc_parts = data_parts[1].split("(") - if len(perc_parts) == 2: - # might otherwise be e.g., 0B/0B, with no % symbol provided - progress( - total=100, - completed=int(perc_parts[1][:-2]), - downloaded=f"{data_parts[3].split(':')[1]}/s" - ) - elif line.startswith("Download Results"): - # we know it's 100% downloaded, but let's use the avg dl speed value - is_dl_summary = True - elif is_dl_summary and "OK" in line and "|" in line: - gid, status, avg_speed, path_or_uri = line.split("|") - progress(total=100, completed=100, downloaded=avg_speed.strip()) - elif not is_dl_summary: - buffer_msg = line.split(" ", maxsplit=2) - buffer_msg = f"[Aria2c]: {buffer_msg[-1].strip()}" - console.log(Text.from_ansi(buffer_msg)) + is_dl_summary = False + aria_log_buffer = "" + for line in iter(p.stdout.readline, ""): + line = line.strip() + if line: + if line.startswith("Download Results"): + # we know it's 100% downloaded, but let's use the avg dl speed value + is_dl_summary = True + elif line.startswith("[") and line.endswith("]"): + if progress and "%" in line: + # id, dledMiB/totalMiB(x%), CN:xx, DL:xxMiB, ETA:Xs + # eta may not always be available + data_parts = line[1:-1].split() + perc_parts = data_parts[1].split("(") + if len(perc_parts) == 2: + # might otherwise be e.g., 0B/0B, with no % symbol provided + progress( + total=100, + completed=int(perc_parts[1][:-2]), + downloaded=f"{data_parts[3].split(':')[1]}/s" + ) + elif is_dl_summary and "OK" in line and "|" in line: + gid, status, avg_speed, path_or_uri = line.split("|") + progress(total=100, completed=100, downloaded=avg_speed.strip()) + elif not is_dl_summary: + aria_log_buffer += f"{line.strip()}\n" + + if aria_log_buffer: + # wrap to console width - padding - '[Aria2c]: ' + aria_log_buffer = "\n ".join(textwrap.wrap( + aria_log_buffer.rstrip(), + width=console.width - 20, + initial_indent="" + )) + console.log(Text.from_ansi("\n[Aria2c]: " + aria_log_buffer)) p.wait()