aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src-tauri/src/core/downloader.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src-tauri/src/core/downloader.rs')
-rw-r--r--src-tauri/src/core/downloader.rs99
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(())
}