Implement download

This commit is contained in:
Kevin Yue
2024-02-18 21:52:58 +08:00
parent f9c0eb43a6
commit 935993e8da
8 changed files with 319 additions and 85 deletions

View File

@@ -9,9 +9,7 @@ license.workspace = true
tauri-build = { version = "1.5", features = [] }
[dependencies]
tauri = { workspace = true, features = [
"window-start-dragging",
] }
tauri = { workspace = true, features = ["window-start-dragging"] }
tokio.workspace = true
anyhow.workspace = true
log.workspace = true
@@ -23,3 +21,4 @@ async-stream = "0.3"
futures-util.workspace = true
downloader = "0.2"
tempfile.workspace = true
reqwest = { workspace = true, features = ["stream"] }

View File

@@ -1,8 +1,9 @@
use std::{sync::Arc, time::Duration};
use std::{io::Write, time::Duration};
use downloader::{progress::Reporter, Download, Downloader};
use tauri::{window::MenuHandle, Manager};
use tempfile::TempDir;
use futures_util::StreamExt;
use log::info;
use tauri::{window::MenuHandle, Manager, Window};
use tempfile::NamedTempFile;
pub struct App {
api_key: Vec<u8>,
@@ -17,10 +18,15 @@ impl App {
tauri::Builder::default()
.setup(|app| {
let win = app.get_window("main").unwrap();
hide_menu(win.menu_handle());
tauri::async_runtime::spawn(async move {
hide_menu(win.menu_handle());
let _ = download_gui();
let win_clone = win.clone();
download_gui(win.clone()).await;
win.listen("app://download", move |_event| {
tokio::spawn(download_gui(win_clone.clone()));
});
});
Ok(())
@@ -49,44 +55,61 @@ fn hide_menu(menu_handle: MenuHandle) {
});
}
struct DownloadProgress {}
async fn download_gui(win: Window) {
let url = "https://github.com/yuezk/GlobalProtect-openconnect/releases/download/v2.0.0/globalprotect-openconnect_2.0.0_x86_64.bin.tar.gz";
// let url = "https://free.nchc.org.tw/opensuse/distribution/leap/15.5/iso/openSUSE-Leap-15.5-DVD-x86_64-Build491.1-Media.iso";
impl Reporter for DownloadProgress {
fn setup(&self, max_progress: Option<u64>, message: &str) {
println!("{}: {}", message, max_progress.unwrap_or(0));
}
let win_clone = win.clone();
fn progress(&self, current: u64) {
println!("progress: {}", current);
}
fn set_message(&self, message: &str) {
println!("message: {}", message);
}
fn done(&self) {
println!("done")
match download(url, move |p| {
let _ = win.emit_all("app://download-progress", p);
})
.await
{
Err(err) => {
info!("download error: {}", err);
let _ = win_clone.emit_all("app://download-error", ());
}
Ok(file) => {
let path = file.into_temp_path();
info!("download completed: {:?}", path);
// Close window after 300ms
tokio::time::sleep(Duration::from_millis(300 * 1000)).await;
info!("file: {:?}", path);
let _ = win_clone.close();
}
}
}
fn download_gui() -> anyhow::Result<()> {
let tmp_dir = TempDir::new()?;
let tmp_dir = tmp_dir.into_path();
async fn download<T>(url: &str, on_progress: T) -> anyhow::Result<NamedTempFile>
where
T: Fn(Option<f64>) + Send + 'static,
{
let res = reqwest::get(url).await?.error_for_status()?;
let content_length = res.content_length().unwrap_or(0);
let mut downloader = Downloader::builder().download_folder(&tmp_dir).build()?;
info!("content_length: {}", content_length);
let dl = Download::new("https://github.com/yuezk/GlobalProtect-openconnect/releases/download/v2.0.0/globalprotect-openconnect_2.0.0_x86_64.bin.tar.gz");
let progress = Arc::new(DownloadProgress {});
let dl = dl.progress(progress);
let mut current_length = 0;
let mut stream = res.bytes_stream();
let result = downloader.download(&[dl])?;
let mut file = NamedTempFile::new()?;
for r in result {
match r {
Ok(s) => println!("Downloaded: {}", s),
Err(e) => println!("Error: {}", e),
while let Some(item) = stream.next().await {
let chunk = item?;
let chunk_size = chunk.len() as u64;
file.write_all(&chunk)?;
current_length += chunk_size;
let progress = current_length as f64 / content_length as f64 * 100.0;
if content_length > 0 {
on_progress(Some(progress));
} else {
on_progress(None);
}
}
Ok(())
Ok(file)
}

View File

@@ -3,6 +3,7 @@
use gpgui_helper::cli;
fn main() {
#[tokio::main]
async fn main() {
cli::run()
}

View File

@@ -38,9 +38,10 @@
"title": "GlobalProtect GUI Helper",
"center": true,
"resizable": true,
"width": 480,
"width": 500,
"height": 100,
"label": "main"
"label": "main",
"decorations": false
}
]
}