Files
STARTLINER/rust/src/download_handler.rs
akanyan e9550e8eee feat: global progress bar
Also fix me having no foresight and executing things
inside log::debug! macros
2025-04-17 07:44:05 +00:00

73 lines
2.3 KiB
Rust

use std::{collections::HashSet, path::PathBuf};
use serde::{Deserialize, Serialize};
use tauri::{AppHandle, Emitter};
use tokio::fs::File;
use anyhow::{anyhow, Result};
use crate::pkg::{Package, PkgKey, Remote};
pub struct DownloadHandler {
paths: HashSet<PathBuf>,
app: AppHandle
}
#[derive(Serialize, Deserialize, Clone)]
pub struct DownloadTick {
pkg_key: PkgKey,
ratio: f32,
}
impl DownloadHandler {
pub fn new(app: AppHandle) -> DownloadHandler {
DownloadHandler {
paths: HashSet::new(),
app
}
}
pub fn download_zip(&mut self, zip_path: &PathBuf, pkg: &Package) -> Result<()> {
let rmt = pkg.rmt.as_ref()
.ok_or_else(|| anyhow!("Attempted to download a package without remote data"))?
.clone();
if self.paths.contains(zip_path) {
Ok(())
} else {
// TODO clear cache button should clear this
self.paths.insert(zip_path.clone());
tauri::async_runtime::spawn(Self::download_zip_proc(self.app.clone(), zip_path.clone(), pkg.key(), rmt));
Ok(())
}
}
async fn download_zip_proc(app: AppHandle, zip_path: PathBuf, pkg_key: PkgKey, rmt: Remote) -> Result<()> {
use futures::StreamExt;
use tokio::io::AsyncWriteExt;
// let zip_path_part = zip_path.add_extension("part");
let mut zip_path_part = zip_path.to_owned();
zip_path_part.set_extension("zip.part");
let mut cache_file_w = File::create(&zip_path_part).await?;
let mut byte_stream = reqwest::get(&rmt.download_url).await?.bytes_stream();
let mut total_bytes = 0;
log::info!("downloading: {}", rmt.download_url);
while let Some(item) = byte_stream.next().await {
let i = item?;
total_bytes += i.len();
_ = app.emit("download-progress", DownloadTick {
pkg_key: pkg_key.clone(),
ratio: (total_bytes as f32) / (rmt.file_size as f32),
})?;
cache_file_w.write_all(&mut i.as_ref()).await?;
}
cache_file_w.sync_all().await?;
tokio::fs::rename(&zip_path_part, &zip_path).await?;
log::debug!("downloaded to {:?}", zip_path);
app.emit("download-end", pkg_key)?;
Ok(())
}
}