From a26eff6f6de7dfa22a80d1f33910ff1e456793e4 Mon Sep 17 00:00:00 2001 From: lennard <44114474+Dummerle@users.noreply.github.com> Date: Wed, 14 Dec 2022 21:28:23 +0100 Subject: [PATCH] Dynamically show size in download logs --- legendary/cli.py | 22 +++++++++++----------- legendary/downloader/mp/manager.py | 15 ++++++++------- legendary/utils/cli.py | 9 +++++++++ 3 files changed, 28 insertions(+), 18 deletions(-) diff --git a/legendary/cli.py b/legendary/cli.py index 79cd730..5231c55 100644 --- a/legendary/cli.py +++ b/legendary/cli.py @@ -21,7 +21,7 @@ from legendary import __version__, __codename__ from legendary.core import LegendaryCore from legendary.models.exceptions import InvalidCredentialsError from legendary.models.game import SaveGameStatus, VerifyResult, Game -from legendary.utils.cli import get_boolean_choice, get_int_choice, sdl_prompt, strtobool +from legendary.utils.cli import get_boolean_choice, get_int_choice, sdl_prompt, strtobool, get_size from legendary.lfs.crossover import * from legendary.utils.custom_parser import HiddenAliasSubparsersAction from legendary.utils.env import is_windows_mac_or_pyi @@ -974,12 +974,12 @@ class LegendaryCLI: exit(0) - logger.info(f'Install size: {analysis.install_size / 1024 / 1024:.02f} MiB') + logger.info(f'Install size: {get_size(analysis.install_size)}') compression = (1 - (analysis.dl_size / analysis.uncompressed_dl_size)) * 100 - logger.info(f'Download size: {analysis.dl_size / 1024 / 1024:.02f} MiB ' + logger.info(f'Download size: {get_size(analysis.dl_size)} ' f'(Compression savings: {compression:.01f}%)') - logger.info(f'Reusable size: {analysis.reuse_size / 1024 / 1024:.02f} MiB (chunks) / ' - f'{analysis.unchanged / 1024 / 1024:.02f} MiB (unchanged / skipped)') + logger.info(f'Reusable size: {get_size(analysis.reuse_size)} (chunks) / ' + f'{get_size(analysis.unchanged)} (unchanged / skipped)') logger.info('Downloads are resumable, you can interrupt the download with ' 'CTRL-C and resume it using the same command later on.') @@ -1932,7 +1932,7 @@ class LegendaryCLI: self.core.lgd.clean_tmp_data() after = self.core.lgd.get_dir_size() - logger.info(f'Cleanup complete! Removed {(before - after) / 1024 / 1024:.02f} MiB.') + logger.info(f'Cleanup complete! Removed {get_size(before - after)}.') def activate(self, args): if not self.core.login(): @@ -2253,8 +2253,8 @@ class LegendaryCLI: return logger.info(f'Install directory: {igame.install_path}') - logger.info(f'Install size: {ares.install_size / 1024 / 1024:.2f} MiB') - logger.info(f'Download size: {ares.dl_size / 1024 / 1024:.2f} MiB') + logger.info(f'Install size: {get_size(ares.install_size)}') + logger.info(f'Download size: {get_size(ares.dl_size)}') if not args.yes: if not get_boolean_choice('Do you want to install the overlay?'): @@ -2382,7 +2382,7 @@ class LegendaryCLI: default_choice = None for i, bottle in enumerate(usable_bottles, start=1): extra = [] - + if cx_version in bottle['cx_versions']: if app_name in bottle['compatible_apps']: extra.append('recommended') @@ -2425,8 +2425,8 @@ class LegendaryCLI: base_url=install_candidate.get('base_url')) logger.info(f'Bottle install directory: {path}') - logger.info(f'Bottle size: {ares.install_size / 1024 / 1024:.2f} MiB') - logger.info(f'Download size: {ares.dl_size / 1024 / 1024:.2f} MiB') + logger.info(f'Bottle size: {get_size(ares.install_size)}') + logger.info(f'Download size: {get_size(ares.dl_size)}') if not args.yes: if not get_boolean_choice('Do you want to download the selected bottle?'): diff --git a/legendary/downloader/mp/manager.py b/legendary/downloader/mp/manager.py index 38b4449..33227e6 100644 --- a/legendary/downloader/mp/manager.py +++ b/legendary/downloader/mp/manager.py @@ -17,6 +17,7 @@ from threading import Condition, Thread from legendary.downloader.mp.workers import DLWorker, FileWorker from legendary.models.downloading import * from legendary.models.manifest import ManifestComparison, Manifest +from legendary.utils.cli import get_size class DLManager(Process): @@ -724,13 +725,13 @@ class DLManager(Process): self.log.info(f'= Progress: {perc:.02f}% ({processed_chunks}/{num_chunk_tasks}), ' f'Running for {rt_hours:02d}:{rt_minutes:02d}:{rt_seconds:02d}, ' f'ETA: {hours:02d}:{minutes:02d}:{seconds:02d}') - self.log.info(f' - Downloaded: {total_dl / 1024 / 1024:.02f} MiB, ' - f'Written: {total_write / 1024 / 1024:.02f} MiB') - self.log.info(f' - Cache usage: {total_used:.02f} MiB, active tasks: {self.active_tasks}') - self.log.info(f' + Download\t- {dl_speed / 1024 / 1024:.02f} MiB/s (raw) ' - f'/ {dl_unc_speed / 1024 / 1024:.02f} MiB/s (decompressed)') - self.log.info(f' + Disk\t- {w_speed / 1024 / 1024:.02f} MiB/s (write) / ' - f'{r_speed / 1024 / 1024:.02f} MiB/s (read)') + self.log.info(f' - Downloaded: {get_size(total_dl)}, ' + f'Written: {get_size(total_write)}') + self.log.info(f' - Cache usage: {get_size(total_used)} , active tasks: {self.active_tasks}') + self.log.info(f' + Download\t- {get_size(dl_speed)}/s (raw) ' + f'/ {get_size(dl_unc_speed)}/s (decompressed)') + self.log.info(f' + Disk\t- {get_size(w_speed)}/s (write) / ' + f'{get_size(r_speed)}/s (read)') # send status update to back to instantiator (if queue exists) if self.status_queue: diff --git a/legendary/utils/cli.py b/legendary/utils/cli.py index c0fe14a..bf0ed8d 100644 --- a/legendary/utils/cli.py +++ b/legendary/utils/cli.py @@ -1,3 +1,6 @@ +from typing import Union + + def get_boolean_choice(prompt, default=True): yn = 'Y/n' if default else 'y/N' @@ -89,3 +92,9 @@ def strtobool(val): else: raise ValueError("invalid truth value %r" % (val,)) + +def get_size(b: Union[int, float]) -> str: + for i in ["", "Ki", "Mi", "Gi", "Ti", "Pi", "Ei"]: + if b < 1024: + return f"{b:.2f}{i}B" + b /= 1024