diff --git a/src/io/logging.rs b/src/io/logging.rs index 2640b73..ac0f161 100644 --- a/src/io/logging.rs +++ b/src/io/logging.rs @@ -1,10 +1,5 @@ -use std::{fs::{self, OpenOptions}, io::Write, time::{Duration, SystemTime}}; +use std::{fs::{self, OpenOptions}, io::Write, time::SystemTime}; -use colored::Colorize; -use reqwest::blocking::Client; -use serde_json::Value; - -use crate::config::{cfg::Config, status::Status}; pub fn setup_logging() -> fs::File { OpenOptions::new() @@ -21,83 +16,3 @@ pub fn log_error(mut log_file: &fs::File, message: &str) { .as_secs(); writeln!(log_file, "[{}] ERROR: {}", timestamp, message).unwrap(); } - -pub fn format_duration(duration: Duration) -> String { - let secs = duration.as_secs(); - format!("{:02}:{:02}:{:02}", secs / 3600, (secs % 3600) / 60, secs % 60) -} - -pub fn bytes_to_human(bytes: u64) -> String { - match bytes { - b if b > 1_000_000_000 => format!("{:.2} GB", b as f64 / 1_000_000_000.0), - b if b > 1_000_000 => format!("{:.2} MB", b as f64 / 1_000_000.0), - b if b > 1_000 => format!("{:.2} KB", b as f64 / 1_000.0), - b => format!("{} B", b), - } -} - -pub fn calculate_total_size(resources: &[Value], client: &Client, config: &Config) -> u64 { - let mut total_size = 0; - let mut failed_urls = 0; - - println!("{} Processing files...", Status::info()); - - for (i, item) in resources.iter().enumerate() { - if let Some(dest) = item.get("dest").and_then(Value::as_str) { - let mut file_size = 0; - let mut found_valid_url = false; - - for base_url in &config.zip_bases { - let url = format!("{}/{}", base_url, dest); - match client.head(&url).send() { - Ok(response) => { - if let Some(len) = response.headers().get("content-length") { - if let Ok(len_str) = len.to_str() { - if let Ok(len_num) = len_str.parse::() { - file_size = len_num; - found_valid_url = true; - break; - } - } - } - } - Err(e) => { - println!("{} Failed to HEAD {}: {}", Status::warning(), url, e); - } - } - } - - if found_valid_url { - total_size += file_size; - } else { - failed_urls += 1; - println!("{} Could not determine size for file: {}", Status::error(), dest); - } - } - - if i % 10 == 0 { - println!( - "{} Processed {}/{} files...", - Status::info(), - i + 1, - resources.len() - ); - } - } - - if failed_urls > 0 { - println!( - "{} Warning: Could not determine size for {} files", - Status::warning(), - failed_urls - ); - } - - println!( - "{} Total download size: {}", - Status::info(), - bytes_to_human(total_size).cyan() - ); - - total_size -} diff --git a/src/io/mod.rs b/src/io/mod.rs index dede10c..ca8e71c 100644 --- a/src/io/mod.rs +++ b/src/io/mod.rs @@ -1,3 +1,4 @@ pub mod console; pub mod file; -pub mod logging; \ No newline at end of file +pub mod logging; +pub mod util; \ No newline at end of file diff --git a/src/io/util.rs b/src/io/util.rs new file mode 100644 index 0000000..440b3d3 --- /dev/null +++ b/src/io/util.rs @@ -0,0 +1,93 @@ +use std::time::Duration; +use colored::Colorize; +use reqwest::blocking::Client; +use serde_json::Value; + +use crate::config::{cfg::Config, status::Status}; + +pub fn format_duration(duration: Duration) -> String { + let secs = duration.as_secs(); + format!("{:02}:{:02}:{:02}", secs / 3600, (secs % 3600) / 60, secs % 60) +} + +pub fn bytes_to_human(bytes: u64) -> String { + match bytes { + b if b > 1_000_000_000 => format!("{:.2} GB", b as f64 / 1_000_000_000.0), + b if b > 1_000_000 => format!("{:.2} MB", b as f64 / 1_000_000.0), + b if b > 1_000 => format!("{:.2} KB", b as f64 / 1_000.0), + b => format!("{} B", b), + } +} + +pub fn calculate_total_size(resources: &[Value], client: &Client, config: &Config) -> u64 { + let mut total_size = 0; + let mut failed_urls = 0; + + println!("{} Processing files...", Status::info()); + + for (i, item) in resources.iter().enumerate() { + if let Some(dest) = item.get("dest").and_then(Value::as_str) { + let mut file_size = 0; + let mut found_valid_url = false; + + for base_url in &config.zip_bases { + let url = format!("{}/{}", base_url, dest); + match client.head(&url).send() { + Ok(response) => { + if let Some(len) = response.headers().get("content-length") { + if let Ok(len_str) = len.to_str() { + if let Ok(len_num) = len_str.parse::() { + file_size = len_num; + found_valid_url = true; + break; + } + } + } + } + Err(e) => { + println!("{} Failed to HEAD {}: {}", Status::warning(), url, e); + } + } + } + + if found_valid_url { + total_size += file_size; + } else { + failed_urls += 1; + println!("{} Could not determine size for file: {}", Status::error(), dest); + } + } + + if i % 10 == 0 { + println!( + "{} Processed {}/{} files...", + Status::info(), + i + 1, + resources.len() + ); + } + } + + if failed_urls > 0 { + println!( + "{} Warning: Could not determine size for {} files", + Status::warning(), + failed_urls + ); + } + + println!( + "{} Total download size: {}", + Status::info(), + bytes_to_human(total_size).cyan() + ); + + total_size +} + +pub fn get_version(data: &Value, category: &str, version: &str) -> Result { + data[category][version] + .as_str() + .map(|s| s.to_string()) + .ok_or_else(|| format!("Missing {} URL", version)) +} \ No newline at end of file diff --git a/src/main.rs b/src/main.rs index 79ffb73..8f08602 100644 --- a/src/main.rs +++ b/src/main.rs @@ -15,8 +15,9 @@ use wuwa_downloader::{ io::{ console::print_results, file::get_dir, + util::{bytes_to_human, format_duration, calculate_total_size}, logging::{ - bytes_to_human, calculate_total_size, format_duration, log_error, setup_logging, + log_error, setup_logging, }, }, network::client::{download_file, fetch_index, get_predownload}, diff --git a/src/network/client.rs b/src/network/client.rs index 3dee63f..1135d59 100644 --- a/src/network/client.rs +++ b/src/network/client.rs @@ -8,7 +8,7 @@ use std::{io::{Read, Write}, fs, io, path::Path, time::Duration}; use crate::config::cfg::Config; use crate::download::progress::DownloadProgress; use crate::io::file::{calculate_md5, check_existing_file, get_filename}; -use crate::io::logging::log_error; +use crate::io::{logging::log_error, util::get_version}; use crate::config::status::Status; const INDEX_URL: &str = "https://gist.githubusercontent.com/yuhkix/b8796681ac2cd3bab11b7e8cdc022254/raw/30a8e747debe9e333d5f4ec5d8700dab500594a2/wuwa.json"; @@ -428,18 +428,11 @@ pub fn fetch_gist(client: &Client) -> Result { io::stdin().read_line(&mut input).unwrap(); match input.trim() { - "1" => return get_version_url(&gist_data, "live", "os-live"), - "2" => return get_version_url(&gist_data, "live", "cn-live"), - "3" => return get_version_url(&gist_data, "beta", "os-beta"), - "4" => return get_version_url(&gist_data, "beta", "cn-beta"), + "1" => return get_version(&gist_data, "live", "os-live"), + "2" => return get_version(&gist_data, "live", "cn-live"), + "3" => return get_version(&gist_data, "beta", "os-beta"), + "4" => return get_version(&gist_data, "beta", "cn-beta"), _ => println!("{} Invalid selection", Status::error()), } } } - -fn get_version_url(data: &Value, category: &str, version: &str) -> Result { - data[category][version] - .as_str() - .map(|s| s.to_string()) - .ok_or_else(|| format!("Missing {} URL", version)) -} \ No newline at end of file