diff options
Diffstat (limited to 'src-tauri/src/core/downloader.rs')
| -rw-r--r-- | src-tauri/src/core/downloader.rs | 99 |
1 files changed, 57 insertions, 42 deletions
diff --git a/src-tauri/src/core/downloader.rs b/src-tauri/src/core/downloader.rs index 33404e9..5f6ec80 100644 --- a/src-tauri/src/core/downloader.rs +++ b/src-tauri/src/core/downloader.rs @@ -1,9 +1,9 @@ +use futures::StreamExt; +use serde::{Deserialize, Serialize}; use std::path::PathBuf; -use serde::{Serialize, Deserialize}; +use std::sync::Arc; use tauri::{Emitter, Window}; -use futures::StreamExt; use tokio::io::AsyncWriteExt; -use std::sync::Arc; use tokio::sync::Semaphore; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -24,7 +24,7 @@ pub struct ProgressEvent { pub async fn download_files(window: Window, tasks: Vec<DownloadTask>) -> Result<(), String> { let client = reqwest::Client::new(); let semaphore = Arc::new(Semaphore::new(10)); // Max 10 concurrent downloads - + // Notify start (total files) let _ = window.emit("download-start", tasks.len()); @@ -32,43 +32,49 @@ pub async fn download_files(window: Window, tasks: Vec<DownloadTask>) -> Result< let client = client.clone(); let window = window.clone(); let semaphore = semaphore.clone(); - + async move { let _permit = semaphore.acquire().await.unwrap(); let file_name = task.path.file_name().unwrap().to_string_lossy().to_string(); // 1. Check if file exists and verify SHA1 if task.path.exists() { - let _ = window.emit("download-progress", ProgressEvent { - file: file_name.clone(), - downloaded: 0, - total: 0, - status: "Verifying".into(), - }); + let _ = window.emit( + "download-progress", + ProgressEvent { + file: file_name.clone(), + downloaded: 0, + total: 0, + status: "Verifying".into(), + }, + ); if let Some(expected_sha1) = &task.sha1 { if let Ok(data) = tokio::fs::read(&task.path).await { - let mut hasher = sha1::Sha1::new(); - use sha1::Digest; - hasher.update(&data); - let result = hex::encode(hasher.finalize()); - if &result == expected_sha1 { - // Already valid - let _ = window.emit("download-progress", ProgressEvent { - file: file_name.clone(), - downloaded: 0, - total: 0, - status: "Skipped".into(), - }); - return Ok(()); - } + let mut hasher = sha1::Sha1::new(); + use sha1::Digest; + hasher.update(&data); + let result = hex::encode(hasher.finalize()); + if &result == expected_sha1 { + // Already valid + let _ = window.emit( + "download-progress", + ProgressEvent { + file: file_name.clone(), + downloaded: 0, + total: 0, + status: "Skipped".into(), + }, + ); + return Ok(()); + } } } } // 2. Download if let Some(parent) = task.path.parent() { - let _ = tokio::fs::create_dir_all(parent).await; + let _ = tokio::fs::create_dir_all(parent).await; } match client.get(&task.url).send().await { @@ -78,7 +84,7 @@ pub async fn download_files(window: Window, tasks: Vec<DownloadTask>) -> Result< Ok(f) => f, Err(e) => return Err(format!("Create file error: {}", e)), }; - + let mut downloaded: u64 = 0; loop { match resp.chunk().await { @@ -87,35 +93,44 @@ pub async fn download_files(window: Window, tasks: Vec<DownloadTask>) -> Result< return Err(format!("Write error: {}", e)); } downloaded += chunk.len() as u64; - let _ = window.emit("download-progress", ProgressEvent { - file: file_name.clone(), - downloaded, - total: total_size, - status: "Downloading".into(), - }); + let _ = window.emit( + "download-progress", + ProgressEvent { + file: file_name.clone(), + downloaded, + total: total_size, + status: "Downloading".into(), + }, + ); } Ok(None) => break, Err(e) => return Err(format!("Download error: {}", e)), } } - }, + } Err(e) => return Err(format!("Request error: {}", e)), } - let _ = window.emit("download-progress", ProgressEvent { - file: file_name.clone(), - downloaded: 0, - total: 0, - status: "Finished".into(), - }); + let _ = window.emit( + "download-progress", + ProgressEvent { + file: file_name.clone(), + downloaded: 0, + total: 0, + status: "Finished".into(), + }, + ); Ok(()) } }); // Buffer unordered to run concurrently - tasks_stream.buffer_unordered(10).collect::<Vec<Result<(), String>>>().await; - + tasks_stream + .buffer_unordered(10) + .collect::<Vec<Result<(), String>>>() + .await; + let _ = window.emit("download-complete", ()); Ok(()) } |