diff --git a/src/commands/download.rs b/src/commands/download.rs index fde254e..706ff76 100644 --- a/src/commands/download.rs +++ b/src/commands/download.rs @@ -4,7 +4,7 @@ use crate::commands::shared::{ }; use crate::connection::MDRSConnection; use futures::stream::{FuturesUnordered, StreamExt}; -use std::path::Path; +use std::path::PathBuf; use std::sync::Arc; pub async fn download( @@ -26,7 +26,6 @@ pub async fn download( if !local_real.is_dir() { return Err(format!("Local directory `{}` not found.", local_path).into()); } - let local_dir_base = local_real.to_string_lossy().to_string(); // Split r_path into the parent directory path and the target basename. // Trailing slashes are already stripped by parse_remote_path, so this is safe. @@ -49,20 +48,20 @@ pub async fn download( return Ok(()); } // Python always places the downloaded file inside the local directory. - let dest = format!("{}/{}", local_dir_base, file.name); + let dest = local_real.join(&file.name); if skip_if_exists { - if Path::new(&dest).exists() { + if dest.exists() { if let Ok(meta) = std::fs::metadata(&dest) { if meta.len() == file.size { - println!("{}", dest); + println!("{}", dest.display()); return Ok(()); } } } } let url = make_absolute_url(&conn, &file.download_url); - conn.download_file(&url, &dest).await?; - println!("{}", dest); + conn.download_file(&url, &dest.to_string_lossy()).await?; + println!("{}", dest.display()); return Ok(()); } @@ -77,10 +76,10 @@ pub async fn download( } // Python downloads into local_path// (not directly into local_path). // We create that subdirectory first, then recurse into it. - let top_local = format!("{}/{}", local_dir_base, sub.name); + let top_local = local_real.join(&sub.name); // Iterative DFS: each entry is (remote_folder_id, local_dir) - let mut stack: Vec<(String, String)> = vec![(sub.id.clone(), top_local)]; + let mut stack: Vec<(String, PathBuf)> = vec![(sub.id.clone(), top_local)]; while let Some((folder_id, local_dir)) = stack.pop() { let folder = conn.retrieve_folder(&folder_id).await?; @@ -90,7 +89,7 @@ pub async fn download( } tokio::fs::create_dir_all(&local_dir).await?; - println!("{}", local_dir); + println!("{}", local_dir.display()); let dir_files = conn.list_all_files(&folder_id).await?; @@ -101,12 +100,12 @@ pub async fn download( if is_excluded(&excludes, &lab.name, &folder.path, Some(&f.name)) { continue; } - let dest_path = format!("{}/{}", local_dir, f.name); + let dest_path = local_dir.join(&f.name); if skip_if_exists { - if Path::new(&dest_path).exists() { + if dest_path.exists() { if let Ok(meta) = std::fs::metadata(&dest_path) { if meta.len() == f.size { - println!("{}", dest_path); + println!("{}", dest_path.display()); continue; } } @@ -114,13 +113,13 @@ pub async fn download( } let url = make_absolute_url(&conn, &f.download_url); let conn = conn.clone(); - let _fname = f.name.clone(); futs.push(tokio::spawn(async move { - match conn.download_file(&url, &dest_path).await { - Ok(_) => println!("{}", dest_path), + let dest_str = dest_path.to_string_lossy().to_string(); + match conn.download_file(&url, &dest_str).await { + Ok(_) => println!("{}", dest_path.display()), Err(_) => { - eprintln!("Failed: {}", dest_path); - if Path::new(&dest_path).is_file() { + eprintln!("Failed: {}", dest_path.display()); + if dest_path.is_file() { let _ = std::fs::remove_file(&dest_path); } } @@ -144,7 +143,7 @@ pub async fn download( None => continue, } } - let sub_local = format!("{}/{}", local_dir, sf.name); + let sub_local = local_dir.join(&sf.name); stack.push((sf.id.clone(), sub_local)); } }