From 7578d77d8c0c6b000728c38fa93a1cb0f0b11ec1 Mon Sep 17 00:00:00 2001 From: pukkandan Date: Mon, 29 Nov 2021 02:55:37 +0530 Subject: [PATCH] [downloader] Add colors to download progress --- yt_dlp/YoutubeDL.py | 12 ++++++------ yt_dlp/downloader/common.py | 28 ++++++++++++++++++++++++---- yt_dlp/minicurses.py | 2 +- 3 files changed, 31 insertions(+), 11 deletions(-) diff --git a/yt_dlp/YoutubeDL.py b/yt_dlp/YoutubeDL.py index 73834b70f3..496b0e22db 100644 --- a/yt_dlp/YoutubeDL.py +++ b/yt_dlp/YoutubeDL.py @@ -849,24 +849,24 @@ class Styles(Enum): WARNING = 'yellow' SUPPRESS = 'light black' - def __format_text(self, out, text, f, fallback=None, *, test_encoding=False): - assert out in ('screen', 'err') + def _format_text(self, handle, allow_colors, text, f, fallback=None, *, test_encoding=False): if test_encoding: original_text = text - handle = self._screen_file if out == 'screen' else self._err_file encoding = self.params.get('encoding') or getattr(handle, 'encoding', 'ascii') text = text.encode(encoding, 'ignore').decode(encoding) if fallback is not None and text != original_text: text = fallback if isinstance(f, self.Styles): f = f._value_ - return format_text(text, f) if self._allow_colors[out] else text if fallback is None else fallback + return format_text(text, f) if allow_colors else text if fallback is None else fallback def _format_screen(self, *args, **kwargs): - return self.__format_text('screen', *args, **kwargs) + return self._format_text( + self._screen_file, self._allow_colors['screen'], *args, **kwargs) def _format_err(self, *args, **kwargs): - return self.__format_text('err', *args, **kwargs) + return self._format_text( + self._err_file, self._allow_colors['err'], *args, **kwargs) def report_warning(self, message, only_once=False): ''' diff --git a/yt_dlp/downloader/common.py b/yt_dlp/downloader/common.py index 4528f3be5c..64a450d384 100644 --- a/yt_dlp/downloader/common.py +++ b/yt_dlp/downloader/common.py @@ -247,11 +247,29 @@ def _prepare_multiline_status(self, lines=1): self._multiline = BreaklineStatusPrinter(self.ydl._screen_file, lines) else: self._multiline = MultilinePrinter(self.ydl._screen_file, lines, not self.params.get('quiet')) + self._multiline.allow_colors = self._multiline._HAVE_FULLCAP and not self.params.get('no_color') def _finish_multiline_status(self): self._multiline.end() - def _report_progress_status(self, s): + _progress_styles = { + 'downloaded_bytes': 'light blue', + 'percent': 'light blue', + 'eta': 'yellow', + 'speed': 'green', + 'elapsed': 'bold white', + 'total_bytes': '', + 'total_bytes_estimate': '', + } + + def _report_progress_status(self, s, default_template): + for name, style in self._progress_styles.items(): + name = f'_{name}_str' + if name not in s: + continue + s[name] = self._format_progress(s[name], style) + s['_default_template'] = default_template % s + progress_dict = s.copy() progress_dict.pop('info_dict') progress_dict = {'info': s['info_dict'], 'progress': progress_dict} @@ -264,6 +282,10 @@ def _report_progress_status(self, s): progress_template.get('download-title') or 'yt-dlp %(progress._default_template)s', progress_dict)) + def _format_progress(self, *args, **kwargs): + return self.ydl._format_text( + self._multiline.stream, self._multiline.allow_colors, *args, **kwargs) + def report_progress(self, s): if s['status'] == 'finished': if self.params.get('noprogress'): @@ -276,7 +298,6 @@ def report_progress(self, s): s['_elapsed_str'] = self.format_seconds(s['elapsed']) msg_template += ' in %(_elapsed_str)s' s['_percent_str'] = self.format_percent(100) - s['_default_template'] = msg_template % s self._report_progress_status(s) return @@ -323,8 +344,7 @@ def report_progress(self, s): msg_template += ' (frag %(fragment_index)s/%(fragment_count)s)' elif s.get('fragment_index'): msg_template += ' (frag %(fragment_index)s)' - s['_default_template'] = msg_template % s - self._report_progress_status(s) + self._report_progress_status(s, msg_template) def report_resuming_byte(self, resume_len): """Report attempt to resume at given byte.""" diff --git a/yt_dlp/minicurses.py b/yt_dlp/minicurses.py index 699b1158ab..c81153c1e0 100644 --- a/yt_dlp/minicurses.py +++ b/yt_dlp/minicurses.py @@ -78,6 +78,7 @@ class MultilinePrinterBase: def __init__(self, stream=None, lines=1): self.stream = stream self.maximum = lines - 1 + self._HAVE_FULLCAP = supports_terminal_sequences(stream) def __enter__(self): return self @@ -124,7 +125,6 @@ def __init__(self, stream=None, lines=1, preserve_output=True): self.preserve_output = preserve_output self._lastline = self._lastlength = 0 self._movelock = Lock() - self._HAVE_FULLCAP = supports_terminal_sequences(self.stream) def lock(func): @functools.wraps(func)