diff --git a/autonomi/tests/evm/file.rs b/autonomi/tests/evm/file.rs index 6a85ff3f07..746cd1cea3 100644 --- a/autonomi/tests/evm/file.rs +++ b/autonomi/tests/evm/file.rs @@ -3,7 +3,7 @@ mod test { use crate::common; use crate::common::{evm_network_from_env, evm_wallet_from_env_or_default}; - use crate::evm::Client; + use autonomi::Client; use bytes::Bytes; use eyre::bail; use std::time::Duration; diff --git a/autonomi_cli/src/actions/download.rs b/autonomi_cli/src/actions/download.rs new file mode 100644 index 0000000000..f27c3f3e37 --- /dev/null +++ b/autonomi_cli/src/actions/download.rs @@ -0,0 +1,51 @@ +// Copyright 2024 MaidSafe.net limited. +// +// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3. +// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed +// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. Please review the Licences for the specific language governing +// permissions and limitations relating to use of the SAFE Network Software. + +use autonomi::{client::address::str_to_xorname, Client}; +use color_eyre::eyre::{eyre, Context, Result}; +use std::path::PathBuf; +use super::get_progress_bar; + +pub async fn download(addr: &str, dest_path: &str, client: &mut Client) -> Result<()> { + let address = str_to_xorname(addr) + .wrap_err("Failed to parse data address")?; + let root = client.fetch_root(address).await + .wrap_err("Failed to fetch data from address")?; + + let progress_bar = get_progress_bar(root.map.len() as u64)?; + let mut all_errs = vec![]; + for (path, file) in root.map { + progress_bar.println(format!("Fetching file: {path:?}...")); + let bytes = match client.fetch_file(&file).await { + Ok(bytes) => bytes, + Err(e) => { + let err = format!("Failed to fetch file {path:?}: {e}"); + all_errs.push(err); + continue; + } + }; + + let path = PathBuf::from(dest_path).join(path); + let here = PathBuf::from("."); + let parent = path.parent().unwrap_or_else(|| &here); + std::fs::create_dir_all(parent)?; + std::fs::write(path, bytes)?; + progress_bar.clone().inc(1); + } + progress_bar.finish_and_clear(); + + if all_errs.is_empty() { + println!("Successfully downloaded data at: {addr}"); + Ok(()) + } else { + let err_no = all_errs.len(); + eprintln!("{err_no} errors while downloading data at: {addr}"); + eprintln!("{all_errs:#?}"); + Err(eyre!("Errors while downloading data")) + } +} \ No newline at end of file diff --git a/autonomi_cli/src/actions/mod.rs b/autonomi_cli/src/actions/mod.rs index eba05b284f..8b4662c3d9 100644 --- a/autonomi_cli/src/actions/mod.rs +++ b/autonomi_cli/src/actions/mod.rs @@ -7,5 +7,10 @@ // permissions and limitations relating to use of the SAFE Network Software. mod connect; +mod download; +mod progress_bar; pub use connect::connect_to_network; +pub use download::download; + +pub use progress_bar::get_progress_bar; diff --git a/autonomi_cli/src/actions/progress_bar.rs b/autonomi_cli/src/actions/progress_bar.rs new file mode 100644 index 0000000000..4c6bbdf7bf --- /dev/null +++ b/autonomi_cli/src/actions/progress_bar.rs @@ -0,0 +1,22 @@ +// Copyright 2024 MaidSafe.net limited. +// +// This SAFE Network Software is licensed to you under The General Public License (GPL), version 3. +// Unless required by applicable law or agreed to in writing, the SAFE Network Software distributed +// under the GPL Licence is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +// KIND, either express or implied. Please review the Licences for the specific language governing +// permissions and limitations relating to use of the SAFE Network Software. + +use indicatif::{ProgressBar, ProgressStyle}; +use std::time::Duration; +use color_eyre::eyre::Result; + +pub fn get_progress_bar(length: u64) -> Result { + let progress_bar = ProgressBar::new(length); + progress_bar.set_style( + ProgressStyle::default_bar() + .template("{spinner:.green} [{elapsed_precise}] [{bar:40.cyan/blue}] {pos}/{len}")? + .progress_chars("#>-"), + ); + progress_bar.enable_steady_tick(Duration::from_millis(100)); + Ok(progress_bar) +} diff --git a/autonomi_cli/src/commands/file.rs b/autonomi_cli/src/commands/file.rs index 60c397beb9..17245b9eba 100644 --- a/autonomi_cli/src/commands/file.rs +++ b/autonomi_cli/src/commands/file.rs @@ -47,41 +47,7 @@ pub async fn upload(file: &str, peers: Vec) -> Result<()> { pub async fn download(addr: &str, dest_path: &str, peers: Vec) -> Result<()> { let mut client = crate::actions::connect_to_network(peers).await?; - - println!("Downloading data from {addr} to {dest_path}"); - let address = str_to_xorname(addr) - .wrap_err("Failed to parse data address")?; - let root = client.fetch_root(address).await - .wrap_err("Failed to fetch root")?; - - let mut all_errs = vec![]; - for (path, file) in root.map { - println!("Fetching file: {path:?}"); - let bytes = match client.fetch_file(&file).await { - Ok(bytes) => bytes, - Err(e) => { - let err = format!("Failed to fetch file {path:?}: {e}"); - all_errs.push(err); - continue; - } - }; - - let path = PathBuf::from(dest_path).join(path); - let here = PathBuf::from("."); - let parent = path.parent().unwrap_or_else(|| &here); - std::fs::create_dir_all(parent)?; - std::fs::write(path, bytes)?; - } - - if all_errs.is_empty() { - println!("Successfully downloaded data at: {addr}"); - Ok(()) - } else { - let err_no = all_errs.len(); - eprintln!("{err_no} errors while downloading data at: {addr}"); - eprintln!("{all_errs:#?}"); - Err(eyre!("Errors while downloading data")) - } + crate::actions::download(addr, dest_path, &mut client).await } pub fn list(peers: Vec) -> Result<()> {