From b133248361ec66d5b66ed53807fca8f7ffe65363 Mon Sep 17 00:00:00 2001 From: Daniyar Itegulov Date: Tue, 18 Jan 2022 10:53:23 +1100 Subject: [PATCH] feat: Implement download file progress bar (#6018) Fixes #4617 This PR introduces a download progress bar using [indicatif](https://github.com/console-rs/indicatif). I used the default download style they showcase in one of their [examples](https://github.com/console-rs/indicatif/blob/main/examples/download.rs) because I think it fits pretty well to the existing color scheme here. But let me know if you prefer something to be restyled. The gif below shows what it looks like (with middle cut out for the sake of brevity): ![progress-bar](https://user-images.githubusercontent.com/7879134/148504443-1205ee4c-ccec-435b-868b-ebe6a0e6c9b6.gif) --- Cargo.lock | 1 + nearcore/Cargo.toml | 1 + nearcore/src/config.rs | 19 +++++++++++++++++++ 3 files changed, 21 insertions(+) diff --git a/Cargo.lock b/Cargo.lock index fa81b7908f3..71be64fec74 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3335,6 +3335,7 @@ dependencies = [ "futures", "hyper", "hyper-tls", + "indicatif", "lazy-static-include", "near-actix-test-utils", "near-chain", diff --git a/nearcore/Cargo.toml b/nearcore/Cargo.toml index df81b1ef473..ab7881ad38c 100644 --- a/nearcore/Cargo.toml +++ b/nearcore/Cargo.toml @@ -34,6 +34,7 @@ near-rust-allocator-proxy = { version = "0.3.0", optional = true } lazy-static-include = "3" tempfile = "3" anyhow = "1.0.51" +indicatif = "0.15.0" near-crypto = { path = "../core/crypto" } near-primitives = { path = "../core/primitives" } diff --git a/nearcore/src/config.rs b/nearcore/src/config.rs index 0d239ad9ea6..85dd013767f 100644 --- a/nearcore/src/config.rs +++ b/nearcore/src/config.rs @@ -7,6 +7,7 @@ use std::time::Duration; use anyhow::{anyhow, bail, Context}; use hyper::body::HttpBody; +use indicatif::{ProgressBar, ProgressStyle}; use near_primitives::time::Clock; use num_rational::Rational; use serde::{Deserialize, Serialize}; @@ -1165,12 +1166,30 @@ async fn download_file_impl( let https_connector = hyper_tls::HttpsConnector::new(); let client = hyper::Client::builder().build::<_, hyper::Body>(https_connector); let mut resp = client.get(uri).await.map_err(FileDownloadError::HttpError)?; + let bar = if let Some(file_size) = resp.size_hint().upper() { + let bar = ProgressBar::new(file_size); + bar.set_style( + ProgressStyle::default_bar().template( + "{spinner:.green} [{elapsed_precise}] [{wide_bar:.cyan/blue}] {bytes}/{total_bytes} [{bytes_per_sec}] ({eta})" + ).progress_chars("#>-") + ); + bar + } else { + let bar = ProgressBar::new_spinner(); + bar.set_style( + ProgressStyle::default_bar() + .template("{spinner:.green} [{elapsed_precise}] {bytes} [{bytes_per_sec}]"), + ); + bar + }; while let Some(next_chunk_result) = resp.data().await { let next_chunk = next_chunk_result.map_err(FileDownloadError::HttpError)?; file.write_all(next_chunk.as_ref()) .await .map_err(|e| FileDownloadError::WriteError(path.to_path_buf(), e))?; + bar.inc(next_chunk.len() as u64); } + bar.finish(); Ok(()) }