mirror of
https://github.com/Cyrix126/gupaxx.git
synced 2024-12-22 14:49:21 +00:00
update/gupax: retry on failed bytes, add progress bar/spinner
This commit is contained in:
parent
6418a0ad2c
commit
8780b0684d
4 changed files with 58 additions and 30 deletions
|
@ -56,7 +56,7 @@ pub const HUGEPAGES_1GB: bool = true;
|
||||||
// Gupax
|
// Gupax
|
||||||
pub const GUPAX_UPDATE: &'static str = "Check for update on Gupax, P2Pool, and XMRig via GitHub's API and upgrade automatically";
|
pub const GUPAX_UPDATE: &'static str = "Check for update on Gupax, P2Pool, and XMRig via GitHub's API and upgrade automatically";
|
||||||
pub const GUPAX_AUTO_UPDATE: &'static str = "Automatically check for updates at startup";
|
pub const GUPAX_AUTO_UPDATE: &'static str = "Automatically check for updates at startup";
|
||||||
pub const GUPAX_UPDATE_VIA_TOR: &'static str = "Update through the Tor network. Gupax has Tor embedded, a Tor system proxy is not required.";
|
pub const GUPAX_UPDATE_VIA_TOR: &'static str = "Update through the Tor network. Tor is embedded within Gupax; a Tor system proxy is not required";
|
||||||
pub const GUPAX_AUTO_NODE: &'static str = "Automatically ping the community Monero nodes and select the fastest at startup for P2Pool";
|
pub const GUPAX_AUTO_NODE: &'static str = "Automatically ping the community Monero nodes and select the fastest at startup for P2Pool";
|
||||||
pub const GUPAX_ASK_BEFORE_QUIT: &'static str = "Ask before quitting if processes are still alive or if an update is in progress";
|
pub const GUPAX_ASK_BEFORE_QUIT: &'static str = "Ask before quitting if processes are still alive or if an update is in progress";
|
||||||
pub const GUPAX_SAVE_BEFORE_QUIT: &'static str = "Automatically save any changed settings before quitting";
|
pub const GUPAX_SAVE_BEFORE_QUIT: &'static str = "Automatically save any changed settings before quitting";
|
||||||
|
|
24
src/gupax.rs
24
src/gupax.rs
|
@ -35,27 +35,41 @@ impl Gupax {
|
||||||
// I have to pick one. This one seperates them though.
|
// I have to pick one. This one seperates them though.
|
||||||
let height = height/6.0;
|
let height = height/6.0;
|
||||||
let width = width - SPACE;
|
let width = width - SPACE;
|
||||||
|
let updating = *update.updating.lock().unwrap();
|
||||||
ui.vertical(|ui| {
|
ui.vertical(|ui| {
|
||||||
ui.set_enabled(!*update.updating.lock().unwrap());
|
ui.set_enabled(!updating);
|
||||||
if ui.add_sized([width, height], egui::Button::new("Check for updates")).on_hover_text(GUPAX_UPDATE).clicked() {
|
if ui.add_sized([width, height], egui::Button::new("Check for updates")).on_hover_text(GUPAX_UPDATE).clicked() {
|
||||||
update.path_p2pool = state.absolute_p2pool_path.display().to_string();
|
update.path_p2pool = state.absolute_p2pool_path.display().to_string();
|
||||||
update.path_xmrig = state.absolute_xmrig_path.display().to_string();
|
update.path_xmrig = state.absolute_xmrig_path.display().to_string();
|
||||||
update.tor = state.update_via_tor;
|
update.tor = state.update_via_tor;
|
||||||
let u = Arc::new(Mutex::new(update.clone()));
|
let u = Arc::new(Mutex::new(update.clone()));
|
||||||
let u = Arc::clone(&u);
|
let u = Arc::clone(&u);
|
||||||
|
let u2 = Arc::new(Mutex::new(update.clone()));
|
||||||
|
let u2 = Arc::clone(&u);
|
||||||
thread::spawn(move|| {
|
thread::spawn(move|| {
|
||||||
info!("Spawning update thread...");
|
info!("Spawning update thread...");
|
||||||
let handle = Update::start(u, version);
|
match Update::start(u, version) {
|
||||||
info!("...........>");
|
Err(e) => {
|
||||||
|
info!("Update | {} ... FAIL", e);
|
||||||
|
*u2.lock().unwrap().msg.lock().unwrap() = MSG_FAILED.to_string();
|
||||||
|
*u2.lock().unwrap().updating.lock().unwrap() = false;
|
||||||
|
},
|
||||||
|
_ => {
|
||||||
|
info!("Update ... OK");
|
||||||
|
*u2.lock().unwrap().msg.lock().unwrap() = MSG_SUCCESS.to_string();
|
||||||
|
*u2.lock().unwrap().prog.lock().unwrap() = 100;
|
||||||
|
*u2.lock().unwrap().updating.lock().unwrap() = false;
|
||||||
|
},
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
ui.vertical(|ui| {
|
ui.vertical(|ui| {
|
||||||
ui.set_enabled(*update.updating.lock().unwrap());
|
ui.set_enabled(updating);
|
||||||
let height = height/2.0;
|
let height = height/2.0;
|
||||||
let msg = format!("{}{}{}{}", *update.msg.lock().unwrap(), " ... ", *update.prog.lock().unwrap(), "%");
|
let msg = format!("{}{}{}{}", *update.msg.lock().unwrap(), " ... ", *update.prog.lock().unwrap(), "%");
|
||||||
ui.add_sized([width, height], egui::Label::new(msg));
|
ui.add_sized([width, height], egui::Label::new(msg));
|
||||||
// let range = *update.prog.lock().unwrap() as f32 / 100.0;
|
if updating { ui.add_sized([width, height], egui::Spinner::new().size(height)); }
|
||||||
ui.add_sized([width, height], egui::ProgressBar::new(*update.prog.lock().unwrap() as f32 / 100.0));
|
ui.add_sized([width, height], egui::ProgressBar::new(*update.prog.lock().unwrap() as f32 / 100.0));
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -582,6 +582,7 @@ impl eframe::App for App {
|
||||||
ui.style_mut().override_text_style = Some(egui::TextStyle::Body);
|
ui.style_mut().override_text_style = Some(egui::TextStyle::Body);
|
||||||
match self.tab {
|
match self.tab {
|
||||||
Tab::About => {
|
Tab::About => {
|
||||||
|
info!("");
|
||||||
ui.add_space(10.0);
|
ui.add_space(10.0);
|
||||||
ui.vertical_centered(|ui| {
|
ui.vertical_centered(|ui| {
|
||||||
// Display [Gupax] banner at max, 1/4 the available length
|
// Display [Gupax] banner at max, 1/4 the available length
|
||||||
|
|
|
@ -163,7 +163,10 @@ const MSG_TMP: &'static str = "Creating temporary directory";
|
||||||
const MSG_TOR: &'static str = "Creating Tor+HTTPS client";
|
const MSG_TOR: &'static str = "Creating Tor+HTTPS client";
|
||||||
const MSG_HTTPS: &'static str = "Creating HTTPS client";
|
const MSG_HTTPS: &'static str = "Creating HTTPS client";
|
||||||
const MSG_METADATA: &'static str = "Fetching package metadata";
|
const MSG_METADATA: &'static str = "Fetching package metadata";
|
||||||
const MSG_ARCHIVE: &'static str = "Downloading packages";
|
const MSG_COMPARE: &'static str = "Compare package versions";
|
||||||
|
const MSG_DOWNLOAD: &'static str = "Downloading packages";
|
||||||
|
pub const MSG_SUCCESS: &'static str = "Update successful";
|
||||||
|
pub const MSG_FAILED: &'static str = "Update failed";
|
||||||
|
|
||||||
// These two are sequential and not async so no need for a constant message.
|
// These two are sequential and not async so no need for a constant message.
|
||||||
// The package in question will be known at runtime, so that will be printed.
|
// The package in question will be known at runtime, so that will be printed.
|
||||||
|
@ -173,9 +176,10 @@ const MSG_ARCHIVE: &'static str = "Downloading packages";
|
||||||
//---------------------------------------------------------------------------------------------------- Update struct/impl
|
//---------------------------------------------------------------------------------------------------- Update struct/impl
|
||||||
// Contains values needed during update
|
// Contains values needed during update
|
||||||
// Progress bar structure:
|
// Progress bar structure:
|
||||||
// 10% | Create tmp directory and pkg list
|
// 0% | Create tmp directory and pkg list
|
||||||
// 15% | Create Tor/HTTPS client
|
// 10% | Create Tor/HTTPS client
|
||||||
// 15% | Download Metadata (x3)
|
// 15% | Download Metadata (x3)
|
||||||
|
// 15% | Compare Versions (x3)
|
||||||
// 30% | Download Archive (x3)
|
// 30% | Download Archive (x3)
|
||||||
// 15% | Extract (x3)
|
// 15% | Extract (x3)
|
||||||
// 15% | Upgrade (x3)
|
// 15% | Upgrade (x3)
|
||||||
|
@ -273,7 +277,6 @@ impl Update {
|
||||||
// so there will be some intermediate variables.
|
// so there will be some intermediate variables.
|
||||||
info!("Update | Init | {} ... {}%", MSG_TMP.to_string(), *update.lock().unwrap().prog.lock().unwrap());
|
info!("Update | Init | {} ... {}%", MSG_TMP.to_string(), *update.lock().unwrap().prog.lock().unwrap());
|
||||||
let tmp_dir = Self::get_tmp_dir();
|
let tmp_dir = Self::get_tmp_dir();
|
||||||
*update.lock().unwrap().prog.lock().unwrap() += 10;
|
|
||||||
|
|
||||||
// Make Pkg vector
|
// Make Pkg vector
|
||||||
let prog = update.lock().unwrap().prog.clone();
|
let prog = update.lock().unwrap().prog.clone();
|
||||||
|
@ -294,7 +297,8 @@ impl Update {
|
||||||
let prog = *update.lock().unwrap().prog.lock().unwrap();
|
let prog = *update.lock().unwrap().prog.lock().unwrap();
|
||||||
info!("Update | Init | {} ... {}%", *update.lock().unwrap().msg.lock().unwrap(), prog);
|
info!("Update | Init | {} ... {}%", *update.lock().unwrap().msg.lock().unwrap(), prog);
|
||||||
let client = Self::get_client(update.lock().unwrap().tor).await?;
|
let client = Self::get_client(update.lock().unwrap().tor).await?;
|
||||||
*update.lock().unwrap().prog.lock().unwrap() += 15;
|
*update.lock().unwrap().prog.lock().unwrap() += 10;
|
||||||
|
info!("Update | Init ... OK");
|
||||||
|
|
||||||
// Loop for metadata
|
// Loop for metadata
|
||||||
*update.lock().unwrap().msg.lock().unwrap() = MSG_METADATA.to_string();
|
*update.lock().unwrap().msg.lock().unwrap() = MSG_METADATA.to_string();
|
||||||
|
@ -322,6 +326,7 @@ impl Update {
|
||||||
info!("Update | Metadata ... OK");
|
info!("Update | Metadata ... OK");
|
||||||
|
|
||||||
// Loop for version comparison
|
// Loop for version comparison
|
||||||
|
*update.lock().unwrap().msg.lock().unwrap() = MSG_COMPARE.to_string();
|
||||||
info!("Update | Compare | Starting version comparison...");
|
info!("Update | Compare | Starting version comparison...");
|
||||||
let prog = update.lock().unwrap().prog.clone();
|
let prog = update.lock().unwrap().prog.clone();
|
||||||
let msg = update.lock().unwrap().msg.clone();
|
let msg = update.lock().unwrap().msg.clone();
|
||||||
|
@ -354,10 +359,13 @@ impl Update {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
*update.lock().unwrap().prog.lock().unwrap() += 5;
|
||||||
}
|
}
|
||||||
|
info!("Update | Compare ... OK");
|
||||||
|
|
||||||
// Loop for download
|
// Loop for download
|
||||||
let mut handles: Vec<JoinHandle<()>> = vec![];
|
let mut handles: Vec<JoinHandle<()>> = vec![];
|
||||||
|
*update.lock().unwrap().msg.lock().unwrap() = MSG_DOWNLOAD.to_string();
|
||||||
info!("Update | Download | Starting download...");
|
info!("Update | Download | Starting download...");
|
||||||
for pkg in vec2.iter() {
|
for pkg in vec2.iter() {
|
||||||
// Clone data before async
|
// Clone data before async
|
||||||
|
@ -380,11 +388,10 @@ impl Update {
|
||||||
link = pkg.link_prefix.to_string() + &version + &pkg.link_suffix + &version + &pkg.link_extension;
|
link = pkg.link_prefix.to_string() + &version + &pkg.link_suffix + &version + &pkg.link_extension;
|
||||||
}
|
}
|
||||||
info!("Update | Download | {} ... {}", pkg.name, link);
|
info!("Update | Download | {} ... {}", pkg.name, link);
|
||||||
let request = Pkg::get_request(link)?;
|
|
||||||
let handle: JoinHandle<()> = tokio::spawn(async move {
|
let handle: JoinHandle<()> = tokio::spawn(async move {
|
||||||
match client {
|
match client {
|
||||||
ClientEnum::Tor(t) => Pkg::get_bytes(name, bytes, prog, t, request).await,
|
ClientEnum::Tor(t) => Pkg::get_bytes(name, bytes, prog, t, link).await,
|
||||||
ClientEnum::Https(h) => Pkg::get_bytes(name, bytes, prog, h, request).await,
|
ClientEnum::Https(h) => Pkg::get_bytes(name, bytes, prog, h, link).await,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
handles.push(handle);
|
handles.push(handle);
|
||||||
|
@ -411,7 +418,6 @@ impl Update {
|
||||||
}
|
}
|
||||||
info!("Update | Extract ... OK");
|
info!("Update | Extract ... OK");
|
||||||
*update.lock().unwrap().updating.lock().unwrap() = false;
|
*update.lock().unwrap().updating.lock().unwrap() = false;
|
||||||
std::process::exit(0);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -491,8 +497,7 @@ impl Pkg {
|
||||||
pub async fn get_metadata<C>(name: Name, new_ver: Arc<Mutex<String>>, prog: Arc<Mutex<u8>>, client: Client<C>, link: String) -> Result<(), Error>
|
pub async fn get_metadata<C>(name: Name, new_ver: Arc<Mutex<String>>, prog: Arc<Mutex<u8>>, client: Client<C>, link: String) -> Result<(), Error>
|
||||||
where C: hyper::client::connect::Connect + Clone + Send + Sync + 'static, {
|
where C: hyper::client::connect::Connect + Clone + Send + Sync + 'static, {
|
||||||
// Retry [3] times if version is not [v*]
|
// Retry [3] times if version is not [v*]
|
||||||
let mut n = 0;
|
for i in 0..3 {
|
||||||
while n < 3 {
|
|
||||||
let request = Pkg::get_request(link.clone())?;
|
let request = Pkg::get_request(link.clone())?;
|
||||||
let mut response = client.request(request).await?;
|
let mut response = client.request(request).await?;
|
||||||
let body = hyper::body::to_bytes(response.body_mut()).await?;
|
let body = hyper::body::to_bytes(response.body_mut()).await?;
|
||||||
|
@ -503,28 +508,36 @@ impl Pkg {
|
||||||
info!("Update | Metadata | {} {} ... {}%", name, body.tag_name, *prog.lock().unwrap());
|
info!("Update | Metadata | {} {} ... {}%", name, body.tag_name, *prog.lock().unwrap());
|
||||||
return Ok(())
|
return Ok(())
|
||||||
}
|
}
|
||||||
warn!("Update | Metadata | {} metadata fetch failed, retry [{}/3]...", name, n);
|
warn!("Update | Metadata | {} failed, retry [{}/3]...", name, i);
|
||||||
n += 1;
|
|
||||||
}
|
}
|
||||||
error!("Update | Metadata | {} metadata fetch failed", name);
|
error!("Update | Metadata | {} failed", name);
|
||||||
Err(anyhow!("Metadata fetch failed"))
|
Err(anyhow!("{} | Metadata fetch failed", name))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes a [Request], fills the appropriate [Pkg]
|
// Takes a [Request], fills the appropriate [Pkg]
|
||||||
// [bytes] field with the [Archive/Standalone]
|
// [bytes] field with the [Archive/Standalone]
|
||||||
pub async fn get_bytes<C>(name: Name, bytes: Arc<Mutex<bytes::Bytes>>, prog: Arc<Mutex<u8>>, client: Client<C>, request: Request<Body>) -> Result<(), anyhow::Error>
|
pub async fn get_bytes<C>(name: Name, bytes: Arc<Mutex<bytes::Bytes>>, prog: Arc<Mutex<u8>>, client: Client<C>, link: String) -> Result<(), anyhow::Error>
|
||||||
where C: hyper::client::connect::Connect + Clone + Send + Sync + 'static, {
|
where C: hyper::client::connect::Connect + Clone + Send + Sync + 'static, {
|
||||||
// GitHub sends a 302 redirect, so we must follow
|
// GitHub sends a 302 redirect, so we must follow
|
||||||
// the [Location] header... only if Reqwest had custom
|
// the [Location] header... only if Reqwest had custom
|
||||||
// connectors so I didn't have to manually do this...
|
// connectors so I didn't have to manually do this...
|
||||||
|
// Also, retry [3] times if [Bytes] == empty
|
||||||
|
for i in 0..3 {
|
||||||
|
let request = Pkg::get_request(link.clone())?;
|
||||||
let response = client.request(request).await?;
|
let response = client.request(request).await?;
|
||||||
let request = Self::get_request(response.headers().get(hyper::header::LOCATION).unwrap().to_str()?.to_string())?;
|
let request = Self::get_request(response.headers().get(hyper::header::LOCATION).unwrap().to_str()?.to_string())?;
|
||||||
let response = client.request(request).await?;
|
let response = client.request(request).await?;
|
||||||
let body = hyper::body::to_bytes(response.into_body()).await?;
|
let body = hyper::body::to_bytes(response.into_body()).await?;
|
||||||
|
if ! body.is_empty() {
|
||||||
*bytes.lock().unwrap() = body;
|
*bytes.lock().unwrap() = body;
|
||||||
*prog.lock().unwrap() += 10;
|
*prog.lock().unwrap() += 10;
|
||||||
info!("Update | Download | {} ... {}%", name, *prog.lock().unwrap());
|
info!("Update | Download | {} ... {}%", name, *prog.lock().unwrap());
|
||||||
Ok(())
|
return Ok(())
|
||||||
|
}
|
||||||
|
warn!("Update | Metadata | {} download bytes are empty, retry [{}/3]...", name, i);
|
||||||
|
}
|
||||||
|
error!("Update | Download | {} failed", name);
|
||||||
|
Err(anyhow!("{} | Download failed", name))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue