summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/lib.rs2
-rw-r--r--src/tui.rs14
-rw-r--r--src/types.rs44
3 files changed, 58 insertions, 2 deletions
diff --git a/src/lib.rs b/src/lib.rs
index 4604c31..5fa0a6b 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,7 +1,9 @@
mod args;
+mod tui;
mod types;
pub use crate::args::*;
+pub use crate::tui::*;
pub use crate::types::*;
use std::path::PathBuf;
diff --git a/src/tui.rs b/src/tui.rs
new file mode 100644
index 0000000..df3504d
--- /dev/null
+++ b/src/tui.rs
@@ -0,0 +1,14 @@
+use indicatif::{ProgressBar, ProgressStyle};
+
+pub fn make_progress_bar(size: u64) -> ProgressBar {
+ let bar = ProgressBar::new(size);
+ bar.set_style(
+ ProgressStyle::with_template(
+ "{elapsed_precise:.white.dim} {wide_bar:.cyan} {bytes}/{total_bytes} ({bytes_per_sec}, {eta})",
+ )
+ .unwrap()
+ .progress_chars("█▉▊▋▌▍▎▏ "),
+ );
+
+ bar
+}
diff --git a/src/types.rs b/src/types.rs
index 5636fe9..b20ada1 100644
--- a/src/types.rs
+++ b/src/types.rs
@@ -1,8 +1,9 @@
+use futures_util::StreamExt;
use serde::Serialize;
use std::path::PathBuf;
-use tokio::fs;
+use tokio::{fs, io::AsyncWriteExt};
-use crate::{index_dir};
+use crate::{appimages_dir, index_dir, make_progress_bar};
#[derive(Debug, Serialize)]
pub struct AppImage {
@@ -31,4 +32,43 @@ impl AppImage {
Ok(())
}
+ pub async fn download_from_url(&self) -> Result<(), Box<dyn std::error::Error>> {
+ fs::create_dir_all(&appimages_dir()).await?;
+
+ // Try to extract filename from URL or use default
+ let url = &self.source.meta.url;
+ let filename = match url.split('/').next_back() {
+ Some(name) => name.to_string(),
+ None => format!("{}.AppImage", &self.executable),
+ };
+ let file_path = &appimages_dir().join(filename);
+
+ let resp = reqwest::get(&url.to_string()).await?;
+ let total_size = resp.content_length().unwrap_or(0);
+
+ let bar = make_progress_bar(total_size);
+ let mut out = tokio::fs::File::create(&file_path).await?;
+
+ // Stream download with progress updates
+ let mut stream = resp.bytes_stream();
+ while let Some(chunk) = stream.next().await {
+ let chunk = chunk?;
+ let len = chunk.len() as u64;
+ out.write_all(&chunk).await?;
+ bar.inc(len);
+ }
+
+ bar.finish_with_message("Download complete!");
+
+ // Make executable
+ #[cfg(unix)]
+ {
+ use std::os::unix::fs::PermissionsExt;
+ let mut perms = fs::metadata(&file_path).await?.permissions();
+ perms.set_mode(0o755);
+ fs::set_permissions(&file_path, perms).await?;
+ }
+
+ Ok(())
+ }
}