mirror of
https://github.com/Cyrix126/gupaxx.git
synced 2024-12-22 14:49:21 +00:00
update: implement retry on [v*] failure, version diff to new vec
This commit is contained in:
parent
446cb9db85
commit
6418a0ad2c
8 changed files with 212 additions and 123 deletions
|
@ -24,7 +24,7 @@ pub struct About {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl About {
|
impl About {
|
||||||
pub fn show(app: &mut App, ctx: &egui::Context, ui: &mut egui::Ui) {
|
pub fn show(app: &mut App, width: f32, height: f32, ctx: &egui::Context, ui: &mut egui::Ui) {
|
||||||
ui.add_space(10.0);
|
ui.add_space(10.0);
|
||||||
ui.vertical_centered(|ui| {
|
ui.vertical_centered(|ui| {
|
||||||
let space = ui.available_height()/2.2;
|
let space = ui.available_height()/2.2;
|
||||||
|
|
|
@ -26,6 +26,12 @@ pub const P2POOL_BASE_ARGS: &'static str = "";
|
||||||
pub const XMRIG_BASE_ARGS: &'static str = "--http-host=127.0.0.1 --http-port=18088 --algo=rx/0 --coin=Monero --randomx-cache-qos";
|
pub const XMRIG_BASE_ARGS: &'static str = "--http-host=127.0.0.1 --http-port=18088 --algo=rx/0 --coin=Monero --randomx-cache-qos";
|
||||||
pub const HORIZONTAL: &'static str = "--------------------------------------------";
|
pub const HORIZONTAL: &'static str = "--------------------------------------------";
|
||||||
|
|
||||||
|
// This is the typical space added when using
|
||||||
|
// [ui.separator()] or [ui.group()]
|
||||||
|
// Used for subtracting the width/height so
|
||||||
|
// things actually line up.
|
||||||
|
pub const SPACE: f32 = 10.0;
|
||||||
|
|
||||||
// OS specific
|
// OS specific
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
pub const OS: &'static str = " Windows";
|
pub const OS: &'static str = " Windows";
|
||||||
|
@ -48,10 +54,11 @@ pub const HUGEPAGES_1GB: bool = true;
|
||||||
|
|
||||||
// Tooltips
|
// Tooltips
|
||||||
// Gupax
|
// Gupax
|
||||||
pub const GUPAX_UPDATE: &'static str = "Update Gupax, P2Pool, and XMRig via GitHub's API";
|
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_AUTO_NODE: &'static str = "Automatically ping the community Monero nodes and select the fastest 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_ASK_BEFORE_QUIT: &'static str = "Ask before quitting if processes are still alive, or if an update is in progress";
|
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_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";
|
||||||
pub const GUPAX_PATH_P2POOL: &'static str = "The location of the P2Pool binary, both absolute and relative paths are accepted";
|
pub const GUPAX_PATH_P2POOL: &'static str = "The location of the P2Pool binary, both absolute and relative paths are accepted";
|
||||||
pub const GUPAX_PATH_XMRIG: &'static str = "The location of the XMRig binary, both absolute and relative paths are accepted";
|
pub const GUPAX_PATH_XMRIG: &'static str = "The location of the XMRig binary, both absolute and relative paths are accepted";
|
||||||
|
|
80
src/gupax.rs
80
src/gupax.rs
|
@ -19,43 +19,69 @@ use std::path::Path;
|
||||||
use crate::App;
|
use crate::App;
|
||||||
use egui::WidgetType::Button;
|
use egui::WidgetType::Button;
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::state::Gupax;
|
use crate::state::{Gupax,Version};
|
||||||
use crate::update::*;
|
use crate::update::*;
|
||||||
|
use std::thread;
|
||||||
|
use std::sync::{Arc,Mutex};
|
||||||
|
use log::*;
|
||||||
|
|
||||||
impl Gupax {
|
impl Gupax {
|
||||||
pub fn show(state: &mut Gupax, ctx: &egui::Context, ui: &mut egui::Ui) {
|
pub fn show(state: &mut Gupax, width: f32, height: f32, update: &mut Update, version: Version, ctx: &egui::Context, ui: &mut egui::Ui) {
|
||||||
let height = ui.available_height();
|
// Update button + Progress bar
|
||||||
let width = ui.available_width();
|
ui.group(|ui| {
|
||||||
let half_height = height / 6.0;
|
// These are in unnecessary [ui.vertical()]'s
|
||||||
let half_width = width / 2.0;
|
// because I need to use [ui.set_enabled]s, but I can't
|
||||||
|
// find a way to use a [ui.xxx()] with [ui.add_sized()].
|
||||||
|
// I have to pick one. This one seperates them though.
|
||||||
|
let height = height/6.0;
|
||||||
|
let width = width - SPACE;
|
||||||
|
ui.vertical(|ui| {
|
||||||
|
ui.set_enabled(!*update.updating.lock().unwrap());
|
||||||
|
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_xmrig = state.absolute_xmrig_path.display().to_string();
|
||||||
|
update.tor = state.update_via_tor;
|
||||||
|
let u = Arc::new(Mutex::new(update.clone()));
|
||||||
|
let u = Arc::clone(&u);
|
||||||
|
thread::spawn(move|| {
|
||||||
|
info!("Spawning update thread...");
|
||||||
|
let handle = Update::start(u, version);
|
||||||
|
info!("...........>");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
ui.vertical(|ui| {
|
||||||
|
ui.set_enabled(*update.updating.lock().unwrap());
|
||||||
|
let height = height/2.0;
|
||||||
|
let msg = format!("{}{}{}{}", *update.msg.lock().unwrap(), " ... ", *update.prog.lock().unwrap(), "%");
|
||||||
|
ui.add_sized([width, height], egui::Label::new(msg));
|
||||||
|
// let range = *update.prog.lock().unwrap() as f32 / 100.0;
|
||||||
|
ui.add_sized([width, height], egui::ProgressBar::new(*update.prog.lock().unwrap() as f32 / 100.0));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
ui.vertical(|ui| {
|
let width = (width - SPACE*10.0)/5.0;
|
||||||
ui.add_sized([half_width - 8.0, half_height], egui::Button::new("Check for updates")).on_hover_text(GUPAX_UPDATE);
|
let height = height/2.0;
|
||||||
ui.set_enabled(false);
|
|
||||||
ui.add_sized([half_width - 8.0, half_height], egui::Button::new("Upgrade")).on_hover_text("asdf");
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
ui.group(|ui| {
|
|
||||||
let mut style = (*ctx.style()).clone();
|
let mut style = (*ctx.style()).clone();
|
||||||
style.spacing.icon_width_inner = ui.available_height() / 6.0;
|
style.spacing.icon_width_inner = height / 6.0;
|
||||||
style.spacing.icon_width = ui.available_height() / 4.0;
|
style.spacing.icon_width = height / 4.0;
|
||||||
style.spacing.icon_spacing = ui.available_width() / 20.0;
|
style.spacing.icon_spacing = width / 20.0;
|
||||||
ctx.set_style(style);
|
ctx.set_style(style);
|
||||||
let half_width = (half_width/2.0)-15.0;
|
let height = height/2.0;
|
||||||
ui.vertical(|ui| {
|
ui.add_sized([width, height], egui::Checkbox::new(&mut state.auto_update, "Auto-update")).on_hover_text(GUPAX_AUTO_UPDATE);
|
||||||
ui.add_sized([half_width, half_height], egui::Checkbox::new(&mut state.auto_update, "Auto-update")).on_hover_text(GUPAX_AUTO_UPDATE);
|
ui.separator();
|
||||||
ui.add_sized([half_width, half_height], egui::Checkbox::new(&mut state.ask_before_quit, "Ask before quitting")).on_hover_text(GUPAX_ASK_BEFORE_QUIT);
|
ui.add_sized([width, height], egui::Checkbox::new(&mut state.auto_node, "Auto-node")).on_hover_text(GUPAX_AUTO_NODE);
|
||||||
});
|
ui.separator();
|
||||||
ui.vertical(|ui| {
|
ui.add_sized([width, height], egui::Checkbox::new(&mut state.update_via_tor, "Update via Tor")).on_hover_text(GUPAX_UPDATE_VIA_TOR);
|
||||||
ui.add_sized([half_width, half_height], egui::Checkbox::new(&mut state.auto_node, "Auto-node")).on_hover_text(GUPAX_AUTO_NODE);
|
ui.separator();
|
||||||
ui.add_sized([half_width, half_height], egui::Checkbox::new(&mut state.save_before_quit, "Save before quitting")).on_hover_text(GUPAX_SAVE_BEFORE_QUIT);
|
ui.add_sized([width, height], egui::Checkbox::new(&mut state.ask_before_quit, "Ask before quit")).on_hover_text(GUPAX_ASK_BEFORE_QUIT);
|
||||||
|
ui.separator();
|
||||||
|
ui.add_sized([width, height], egui::Checkbox::new(&mut state.save_before_quit, "Save before quit")).on_hover_text(GUPAX_SAVE_BEFORE_QUIT);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
ui.add_space(SPACE);
|
||||||
ui.add_space(10.0);
|
|
||||||
|
|
||||||
ui.horizontal(|ui| {
|
ui.horizontal(|ui| {
|
||||||
ui.label("P2Pool binary path:");
|
ui.label("P2Pool binary path:");
|
||||||
|
|
51
src/main.rs
51
src/main.rs
|
@ -70,7 +70,7 @@ pub struct App {
|
||||||
// State
|
// State
|
||||||
og: State, // og = Old state to compare against
|
og: State, // og = Old state to compare against
|
||||||
state: State, // state = Working state (current settings)
|
state: State, // state = Working state (current settings)
|
||||||
// update: Update, // State for update data [update.rs]
|
update: Update, // State for update data [update.rs]
|
||||||
diff: bool, // Instead of comparing [og == state] every frame, this bool indicates changes
|
diff: bool, // Instead of comparing [og == state] every frame, this bool indicates changes
|
||||||
// Process/update state:
|
// Process/update state:
|
||||||
// Doesn't make sense to save this on disk
|
// Doesn't make sense to save this on disk
|
||||||
|
@ -102,7 +102,6 @@ impl App {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
let throwaway = State::default();
|
|
||||||
let app = Self {
|
let app = Self {
|
||||||
tab: Tab::default(),
|
tab: Tab::default(),
|
||||||
quit: false,
|
quit: false,
|
||||||
|
@ -114,7 +113,7 @@ impl App {
|
||||||
node: Arc::new(Mutex::new(NodeStruct::default())),
|
node: Arc::new(Mutex::new(NodeStruct::default())),
|
||||||
og: State::default(),
|
og: State::default(),
|
||||||
state: State::default(),
|
state: State::default(),
|
||||||
// update: Update::new(&throwaway.gupax.absolute_p2pool_path, &throwaway.gupax.absolute_xmrig_path, true),
|
update: Update::new(PathBuf::new(), PathBuf::new(), true),
|
||||||
diff: false,
|
diff: false,
|
||||||
p2pool: false,
|
p2pool: false,
|
||||||
xmrig: false,
|
xmrig: false,
|
||||||
|
@ -144,10 +143,12 @@ impl App {
|
||||||
Err(err) => { panic_app(err.to_string()); exit(1); },
|
Err(err) => { panic_app(err.to_string()); exit(1); },
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
app.state = app.og.clone();
|
||||||
|
// Handle max threads
|
||||||
app.og.xmrig.max_threads = num_cpus::get();
|
app.og.xmrig.max_threads = num_cpus::get();
|
||||||
if app.og.xmrig.current_threads > app.og.xmrig.max_threads { app.og.xmrig.current_threads = app.og.xmrig.max_threads; }
|
if app.og.xmrig.current_threads > app.og.xmrig.max_threads { app.og.xmrig.current_threads = app.og.xmrig.max_threads; }
|
||||||
app.state = app.og.clone();
|
// Apply TOML values to [Update]
|
||||||
// app.update = Update::new(&app.og.gupax.absolute_p2pool_path, &app.og.gupax.absolute_xmrig_path, app.og.gupax.update_via_tor);
|
app.update = Update::new(app.og.gupax.absolute_p2pool_path.clone(), app.og.gupax.absolute_xmrig_path.clone(), app.og.gupax.update_via_tor);
|
||||||
app
|
app
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -198,10 +199,10 @@ fn init_text_styles(ctx: &egui::Context, width: f32) {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn init_logger() {
|
fn init_logger() {
|
||||||
#[cfg(debug_assertions)]
|
// #[cfg(debug_assertions)]
|
||||||
let filter = LevelFilter::Info;
|
let filter = LevelFilter::Info;
|
||||||
#[cfg(not(debug_assertions))]
|
// #[cfg(not(debug_assertions))]
|
||||||
let filter = LevelFilter::Warn;
|
// let filter = LevelFilter::Warn;
|
||||||
use env_logger::fmt::Color;
|
use env_logger::fmt::Color;
|
||||||
Builder::new().format(|buf, record| {
|
Builder::new().format(|buf, record| {
|
||||||
let level;
|
let level;
|
||||||
|
@ -228,7 +229,7 @@ fn init_logger() {
|
||||||
|
|
||||||
fn init_options() -> NativeOptions {
|
fn init_options() -> NativeOptions {
|
||||||
let mut options = eframe::NativeOptions::default();
|
let mut options = eframe::NativeOptions::default();
|
||||||
options.min_window_size = Option::from(Vec2::new(1280.0, 720.0));
|
options.min_window_size = Option::from(Vec2::new(854.0, 480.0));
|
||||||
options.max_window_size = Option::from(Vec2::new(3180.0, 2160.0));
|
options.max_window_size = Option::from(Vec2::new(3180.0, 2160.0));
|
||||||
options.initial_window_size = Option::from(Vec2::new(1280.0, 720.0));
|
options.initial_window_size = Option::from(Vec2::new(1280.0, 720.0));
|
||||||
options.follow_system_theme = false;
|
options.follow_system_theme = false;
|
||||||
|
@ -353,8 +354,8 @@ impl eframe::App for Panic {
|
||||||
//---------------------------------------------------------------------------------------------------- Main [App] frame
|
//---------------------------------------------------------------------------------------------------- Main [App] frame
|
||||||
fn main() {
|
fn main() {
|
||||||
init_logger();
|
init_logger();
|
||||||
let app = App::new();
|
|
||||||
let options = init_options();
|
let options = init_options();
|
||||||
|
let app = App::new();
|
||||||
eframe::run_native("Gupax", options, Box::new(|cc| Box::new(App::cc(cc, app))),);
|
eframe::run_native("Gupax", options, Box::new(|cc| Box::new(App::cc(cc, app))),);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -372,14 +373,7 @@ impl eframe::App for App {
|
||||||
// *-------*
|
// *-------*
|
||||||
// | DEBUG |
|
// | DEBUG |
|
||||||
// *-------*
|
// *-------*
|
||||||
let p2pool = self.og.gupax.absolute_p2pool_path.clone();
|
|
||||||
let xmrig = self.og.gupax.absolute_xmrig_path.clone();
|
|
||||||
let tor = self.og.gupax.update_via_tor.clone();
|
|
||||||
thread::spawn(move|| {
|
|
||||||
info!("Spawning update thread...");
|
|
||||||
let update = Update::start(&mut Update::new(p2pool, xmrig, tor));
|
|
||||||
});
|
|
||||||
thread::park();
|
|
||||||
// This sets the top level Ui dimensions.
|
// This sets the top level Ui dimensions.
|
||||||
// Used as a reference for other uis.
|
// Used as a reference for other uis.
|
||||||
egui::CentralPanel::default().show(ctx, |ui| { self.width = ui.available_width(); self.height = ui.available_height(); });
|
egui::CentralPanel::default().show(ctx, |ui| { self.width = ui.available_width(); self.height = ui.available_height(); });
|
||||||
|
@ -580,15 +574,19 @@ impl eframe::App for App {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Middle panel, contents of the [Tab]
|
||||||
egui::CentralPanel::default().show(ctx, |ui| {
|
egui::CentralPanel::default().show(ctx, |ui| {
|
||||||
|
// This sets the Ui dimensions after Top/Bottom are filled
|
||||||
|
self.width = ui.available_width();
|
||||||
|
self.height = ui.available_height();
|
||||||
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 => {
|
||||||
ui.add_space(10.0);
|
ui.add_space(10.0);
|
||||||
ui.vertical_centered(|ui| {
|
ui.vertical_centered(|ui| {
|
||||||
let space = ui.available_height()/2.2;
|
// Display [Gupax] banner at max, 1/4 the available length
|
||||||
self.banner.show(ui);
|
self.banner.show_max_size(ui, Vec2::new(self.width, self.height/4.0));
|
||||||
ui.label("Gupax (guh-picks) is a cross-platform GUI for mining");
|
ui.label("Gupax is a cross-platform GUI for mining");
|
||||||
ui.hyperlink_to("[Monero]", "https://www.github.com/monero-project/monero");
|
ui.hyperlink_to("[Monero]", "https://www.github.com/monero-project/monero");
|
||||||
ui.label("on the decentralized");
|
ui.label("on the decentralized");
|
||||||
ui.hyperlink_to("[P2Pool]", "https://www.github.com/SChernykh/p2pool");
|
ui.hyperlink_to("[P2Pool]", "https://www.github.com/SChernykh/p2pool");
|
||||||
|
@ -596,8 +594,7 @@ impl eframe::App for App {
|
||||||
ui.hyperlink_to("[XMRig]", "https://www.github.com/xmrig/xmrig");
|
ui.hyperlink_to("[XMRig]", "https://www.github.com/xmrig/xmrig");
|
||||||
ui.label("miner for max hashrate");
|
ui.label("miner for max hashrate");
|
||||||
|
|
||||||
ui.add_space(ui.available_height()/2.4);
|
ui.add_space(ui.available_height()/2.0);
|
||||||
|
|
||||||
ui.hyperlink_to("Powered by egui", "https://github.com/emilk/egui");
|
ui.hyperlink_to("Powered by egui", "https://github.com/emilk/egui");
|
||||||
ui.hyperlink_to(format!("{} {}", GITHUB, "Gupax made by hinto-janaiyo"), "https://www.github.com/hinto-janaiyo/gupax");
|
ui.hyperlink_to(format!("{} {}", GITHUB, "Gupax made by hinto-janaiyo"), "https://www.github.com/hinto-janaiyo/gupax");
|
||||||
ui.label("egui is licensed under MIT & Apache-2.0");
|
ui.label("egui is licensed under MIT & Apache-2.0");
|
||||||
|
@ -605,16 +602,16 @@ impl eframe::App for App {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Tab::Status => {
|
Tab::Status => {
|
||||||
Status::show(self, ctx, ui);
|
Status::show(self, self.width, self.height, ctx, ui);
|
||||||
}
|
}
|
||||||
Tab::Gupax => {
|
Tab::Gupax => {
|
||||||
Gupax::show(&mut self.state.gupax, ctx, ui);
|
Gupax::show(&mut self.state.gupax, self.width, self.height, &mut self.update, self.og.version.clone(), ctx, ui);
|
||||||
}
|
}
|
||||||
Tab::P2pool => {
|
Tab::P2pool => {
|
||||||
P2pool::show(&mut self.state.p2pool, ctx, ui);
|
P2pool::show(&mut self.state.p2pool, self.width, self.height, ctx, ui);
|
||||||
}
|
}
|
||||||
Tab::Xmrig => {
|
Tab::Xmrig => {
|
||||||
Xmrig::show(&mut self.state.xmrig, ctx, ui);
|
Xmrig::show(&mut self.state.xmrig, self.width, self.height, ctx, ui);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -34,7 +34,7 @@ use crate::node::{RINO,SETH,SELSTA};
|
||||||
|
|
||||||
|
|
||||||
impl P2pool {
|
impl P2pool {
|
||||||
pub fn show(&mut self, ctx: &egui::Context, ui: &mut egui::Ui) {
|
pub fn show(&mut self, width: f32, height: f32, ctx: &egui::Context, ui: &mut egui::Ui) {
|
||||||
// TODO:
|
// TODO:
|
||||||
// ping code
|
// ping code
|
||||||
// If ping-ING, display stats
|
// If ping-ING, display stats
|
||||||
|
|
|
@ -25,7 +25,7 @@ pub struct Status {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Status {
|
impl Status {
|
||||||
pub fn show(app: &mut App, ctx: &egui::Context, ui: &mut egui::Ui) {
|
pub fn show(app: &mut App, width: f32, height: f32, ctx: &egui::Context, ui: &mut egui::Ui) {
|
||||||
let color = if ui.visuals().dark_mode {
|
let color = if ui.visuals().dark_mode {
|
||||||
Color32::from_additive_luminance(196)
|
Color32::from_additive_luminance(196)
|
||||||
} else {
|
} else {
|
||||||
|
|
151
src/update.rs
151
src/update.rs
|
@ -33,7 +33,7 @@ use std::io::{Read,Write};
|
||||||
//use crate::{Name::*,State};
|
//use crate::{Name::*,State};
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
use rand::distributions::Alphanumeric;
|
use rand::distributions::Alphanumeric;
|
||||||
use anyhow::Error;
|
use anyhow::{anyhow,Error};
|
||||||
use arti_hyper::*;
|
use arti_hyper::*;
|
||||||
use arti_client::{TorClient,TorClientConfig};
|
use arti_client::{TorClient,TorClientConfig};
|
||||||
use tokio::io::{AsyncReadExt,AsyncWriteExt};
|
use tokio::io::{AsyncReadExt,AsyncWriteExt};
|
||||||
|
@ -45,6 +45,8 @@ use arti_hyper::*;
|
||||||
use log::*;
|
use log::*;
|
||||||
use crate::update::Name::*;
|
use crate::update::Name::*;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
use crate::state::Version;
|
||||||
|
use crate::constants::GUPAX_VERSION;
|
||||||
|
|
||||||
// use tls_api_native_tls::{TlsConnector,TlsConnectorBuilder};
|
// use tls_api_native_tls::{TlsConnector,TlsConnectorBuilder};
|
||||||
|
|
||||||
|
@ -155,6 +157,7 @@ const FAKE_USER_AGENT: [&'static str; 50] = [
|
||||||
"curl/7.85.0",
|
"curl/7.85.0",
|
||||||
];
|
];
|
||||||
|
|
||||||
|
const MSG_NONE: &'static str = "No update in progress";
|
||||||
const MSG_START: &'static str = "Starting update";
|
const MSG_START: &'static str = "Starting update";
|
||||||
const MSG_TMP: &'static str = "Creating temporary directory";
|
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";
|
||||||
|
@ -177,15 +180,16 @@ const MSG_ARCHIVE: &'static str = "Downloading packages";
|
||||||
// 15% | Extract (x3)
|
// 15% | Extract (x3)
|
||||||
// 15% | Upgrade (x3)
|
// 15% | Upgrade (x3)
|
||||||
|
|
||||||
|
#[derive(Clone)]
|
||||||
pub struct Update {
|
pub struct Update {
|
||||||
path_gupax: String, // Full path to current gupax
|
pub path_gupax: String, // Full path to current gupax
|
||||||
path_p2pool: String, // Full path to current p2pool
|
pub path_p2pool: String, // Full path to current p2pool
|
||||||
path_xmrig: String, // Full path to current xmrig
|
pub path_xmrig: String, // Full path to current xmrig
|
||||||
tmp_dir: String, // Full path to temporary directory
|
pub tmp_dir: String, // Full path to temporary directory
|
||||||
updating: Arc<Mutex<bool>>, // Is an update in progress?
|
pub updating: Arc<Mutex<bool>>, // Is an update in progress?
|
||||||
prog: Arc<Mutex<u8>>, // Holds the 0-100% progress bar number
|
pub prog: Arc<Mutex<u8>>, // Holds the 0-100% progress bar number
|
||||||
msg: Arc<Mutex<String>>, // Message to display on [Gupax] tab while updating
|
pub msg: Arc<Mutex<String>>, // Message to display on [Gupax] tab while updating
|
||||||
tor: bool, // Is Tor enabled or not?
|
pub tor: bool, // Is Tor enabled or not?
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Update {
|
impl Update {
|
||||||
|
@ -196,9 +200,9 @@ impl Update {
|
||||||
path_p2pool: path_p2pool.display().to_string(),
|
path_p2pool: path_p2pool.display().to_string(),
|
||||||
path_xmrig: path_xmrig.display().to_string(),
|
path_xmrig: path_xmrig.display().to_string(),
|
||||||
tmp_dir: "".to_string(),
|
tmp_dir: "".to_string(),
|
||||||
updating: Arc::new(Mutex::new(true)),
|
updating: Arc::new(Mutex::new(false)),
|
||||||
prog: Arc::new(Mutex::new(0)),
|
prog: Arc::new(Mutex::new(0)),
|
||||||
msg: Arc::new(Mutex::new("".to_string())),
|
msg: Arc::new(Mutex::new(MSG_NONE.to_string())),
|
||||||
tor,
|
tor,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,73 +258,114 @@ impl Update {
|
||||||
// 5. extract, upgrade
|
// 5. extract, upgrade
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
pub async fn start(&mut self) -> Result<(), anyhow::Error> {
|
pub async fn start(update: Arc<Mutex<Self>>, version: Version) -> Result<(), anyhow::Error> {
|
||||||
|
// Start
|
||||||
|
*update.lock().unwrap().updating.lock().unwrap() = true;
|
||||||
|
|
||||||
// Set progress bar
|
// Set progress bar
|
||||||
*self.msg.lock().unwrap() = MSG_START.to_string();
|
*update.lock().unwrap().msg.lock().unwrap() = MSG_START.to_string();
|
||||||
*self.prog.lock().unwrap() = 0;
|
*update.lock().unwrap().prog.lock().unwrap() = 0;
|
||||||
info!("Update | Init | {}...", *self.msg.lock().unwrap());
|
info!("Update | Init | {}...", *update.lock().unwrap().msg.lock().unwrap());
|
||||||
|
|
||||||
// Get temporary directory
|
// Get temporary directory
|
||||||
*self.msg.lock().unwrap() = MSG_TMP.to_string();
|
*update.lock().unwrap().msg.lock().unwrap() = MSG_TMP.to_string();
|
||||||
info!("Update | Init | {} ... {}%", *self.msg.lock().unwrap(), *self.prog.lock().unwrap());
|
// Cannot lock Arc<Mutex> twice in same line
|
||||||
|
// so there will be some intermediate variables.
|
||||||
|
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();
|
||||||
*self.prog.lock().unwrap() += 10;
|
*update.lock().unwrap().prog.lock().unwrap() += 10;
|
||||||
|
|
||||||
// Make Pkg vector
|
// Make Pkg vector
|
||||||
|
let prog = update.lock().unwrap().prog.clone();
|
||||||
|
let msg = update.lock().unwrap().msg.clone();
|
||||||
let vec = vec![
|
let vec = vec![
|
||||||
Pkg::new(Gupax, &tmp_dir, self.prog.clone(), self.msg.clone()),
|
Pkg::new(Gupax, &tmp_dir, prog.clone(), msg.clone()),
|
||||||
Pkg::new(P2pool, &tmp_dir, self.prog.clone(), self.msg.clone()),
|
Pkg::new(P2pool, &tmp_dir, prog.clone(), msg.clone()),
|
||||||
Pkg::new(Xmrig, &tmp_dir, self.prog.clone(), self.msg.clone()),
|
Pkg::new(Xmrig, &tmp_dir, prog.clone(), msg.clone()),
|
||||||
];
|
];
|
||||||
let mut handles: Vec<JoinHandle<()>> = vec![];
|
let mut handles: Vec<JoinHandle<()>> = vec![];
|
||||||
|
|
||||||
// Create Tor/HTTPS client
|
// Create Tor/HTTPS client
|
||||||
if self.tor { *self.msg.lock().unwrap() = MSG_TOR.to_string() } else { *self.msg.lock().unwrap() = MSG_HTTPS.to_string() }
|
if update.lock().unwrap().tor {
|
||||||
info!("Update | Init | {} ... {}%", *self.msg.lock().unwrap(), *self.prog.lock().unwrap());
|
*update.lock().unwrap().msg.lock().unwrap() = MSG_TOR.to_string()
|
||||||
let client = Self::get_client(self.tor).await?;
|
} else {
|
||||||
*self.prog.lock().unwrap() += 15;
|
*update.lock().unwrap().msg.lock().unwrap() = MSG_HTTPS.to_string()
|
||||||
|
}
|
||||||
|
let prog = *update.lock().unwrap().prog.lock().unwrap();
|
||||||
|
info!("Update | Init | {} ... {}%", *update.lock().unwrap().msg.lock().unwrap(), prog);
|
||||||
|
let client = Self::get_client(update.lock().unwrap().tor).await?;
|
||||||
|
*update.lock().unwrap().prog.lock().unwrap() += 15;
|
||||||
|
|
||||||
// Loop for metadata
|
// Loop for metadata
|
||||||
|
*update.lock().unwrap().msg.lock().unwrap() = MSG_METADATA.to_string();
|
||||||
info!("Update | Metadata | Starting metadata fetch...");
|
info!("Update | Metadata | Starting metadata fetch...");
|
||||||
for pkg in vec.iter() {
|
for pkg in vec.iter() {
|
||||||
// Clone data before sending to async
|
// Clone data before sending to async
|
||||||
let name = pkg.name.clone();
|
let name = pkg.name.clone();
|
||||||
let version = Arc::clone(&pkg.version);
|
let new_ver = Arc::clone(&pkg.new_ver);
|
||||||
let prog = Arc::clone(&pkg.prog);
|
let prog = Arc::clone(&pkg.prog);
|
||||||
let client = client.clone();
|
let client = client.clone();
|
||||||
let request = Pkg::get_request(pkg.link_metadata.to_string())?;
|
let link = pkg.link_metadata.to_string();
|
||||||
// Send to async
|
// Send to async
|
||||||
let handle: JoinHandle<()> = tokio::spawn(async move {
|
let handle: JoinHandle<()> = tokio::spawn(async move {
|
||||||
match client {
|
match client {
|
||||||
ClientEnum::Tor(t) => Pkg::get_metadata(name, version, prog, t, request).await,
|
ClientEnum::Tor(t) => Pkg::get_metadata(name, new_ver, prog, t, link).await,
|
||||||
ClientEnum::Https(h) => Pkg::get_metadata(name, version, prog, h, request).await,
|
ClientEnum::Https(h) => Pkg::get_metadata(name, new_ver, prog, h, link).await,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
handles.push(handle);
|
handles.push(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// TODO:
|
|
||||||
// connection fails sometimes
|
|
||||||
// Regex for [v...] or restart Client process.
|
|
||||||
|
|
||||||
|
|
||||||
// Unwrap async
|
// Unwrap async
|
||||||
for handle in handles {
|
for handle in handles {
|
||||||
handle.await?;
|
handle.await?;
|
||||||
}
|
}
|
||||||
info!("Update | Metadata ... OK");
|
info!("Update | Metadata ... OK");
|
||||||
|
|
||||||
|
// Loop for version comparison
|
||||||
|
info!("Update | Compare | Starting version comparison...");
|
||||||
|
let prog = update.lock().unwrap().prog.clone();
|
||||||
|
let msg = update.lock().unwrap().msg.clone();
|
||||||
|
let mut vec2 = vec![];
|
||||||
|
for pkg in vec.iter() {
|
||||||
|
let new_ver = pkg.new_ver.lock().unwrap().to_owned();
|
||||||
|
match pkg.name {
|
||||||
|
Gupax => {
|
||||||
|
if new_ver == GUPAX_VERSION {
|
||||||
|
info!("Update | Compare | {} {} == {} ... SKIPPING", pkg.name, pkg.new_ver.lock().unwrap(), GUPAX_VERSION);
|
||||||
|
} else {
|
||||||
|
info!("Update | Compare | {} {} != {} ... ADDING", pkg.name, pkg.new_ver.lock().unwrap(), GUPAX_VERSION);
|
||||||
|
vec2.push(pkg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
P2pool => {
|
||||||
|
if new_ver == version.p2pool {
|
||||||
|
info!("Update | Compare | {} {} == {} ... SKIPPING", pkg.name, pkg.new_ver.lock().unwrap(), version.p2pool);
|
||||||
|
} else {
|
||||||
|
info!("Update | Compare | {} {} != {} ... ADDING", pkg.name, pkg.new_ver.lock().unwrap(), version.p2pool);
|
||||||
|
vec2.push(pkg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Xmrig => {
|
||||||
|
if new_ver == GUPAX_VERSION {
|
||||||
|
info!("Update | Compare | {} {} == {} ... SKIPPING", pkg.name, pkg.new_ver.lock().unwrap(), version.xmrig);
|
||||||
|
} else {
|
||||||
|
info!("Update | Compare | {} {} != {} ... ADDING", pkg.name, pkg.new_ver.lock().unwrap(), version.xmrig);
|
||||||
|
vec2.push(pkg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Loop for download
|
// Loop for download
|
||||||
let mut handles: Vec<JoinHandle<()>> = vec![];
|
let mut handles: Vec<JoinHandle<()>> = vec![];
|
||||||
info!("Update | Download | Starting download...");
|
info!("Update | Download | Starting download...");
|
||||||
for pkg in vec.iter() {
|
for pkg in vec2.iter() {
|
||||||
// Clone data before async
|
// Clone data before async
|
||||||
let name = pkg.name.clone();
|
let name = pkg.name.clone();
|
||||||
let bytes = Arc::clone(&pkg.bytes);
|
let bytes = Arc::clone(&pkg.bytes);
|
||||||
let prog = Arc::clone(&pkg.prog);
|
let prog = Arc::clone(&pkg.prog);
|
||||||
let client = client.clone();
|
let client = client.clone();
|
||||||
let version = pkg.version.lock().unwrap().to_string();
|
let version = pkg.new_ver.lock().unwrap();
|
||||||
let link;
|
let link;
|
||||||
// Download link = PREFIX + Version (found at runtime) + SUFFIX + Version + EXT
|
// Download link = PREFIX + Version (found at runtime) + SUFFIX + Version + EXT
|
||||||
// Example: https://github.com/hinto-janaiyo/gupax/releases/download/v0.0.1/gupax-v0.0.1-linux-standalone-x64
|
// Example: https://github.com/hinto-janaiyo/gupax/releases/download/v0.0.1/gupax-v0.0.1-linux-standalone-x64
|
||||||
|
@ -354,7 +399,7 @@ impl Update {
|
||||||
// std::fs::OpenOptions::new().mode(0o700).create(true).write(true).open(&tmp);
|
// std::fs::OpenOptions::new().mode(0o700).create(true).write(true).open(&tmp);
|
||||||
std::fs::create_dir(&tmp)?;
|
std::fs::create_dir(&tmp)?;
|
||||||
info!("Update | Extract | Starting extraction...");
|
info!("Update | Extract | Starting extraction...");
|
||||||
for pkg in vec.iter() {
|
for pkg in vec2.iter() {
|
||||||
let tmp = tmp.to_string() + &pkg.name.to_string();
|
let tmp = tmp.to_string() + &pkg.name.to_string();
|
||||||
if pkg.name == Name::Gupax {
|
if pkg.name == Name::Gupax {
|
||||||
std::fs::write(tmp, pkg.bytes.lock().unwrap().as_ref())?;
|
std::fs::write(tmp, pkg.bytes.lock().unwrap().as_ref())?;
|
||||||
|
@ -365,6 +410,7 @@ impl Update {
|
||||||
info!("Update | Extract | {} ... {}%", pkg.name, pkg.prog.lock().unwrap());
|
info!("Update | Extract | {} ... {}%", pkg.name, pkg.prog.lock().unwrap());
|
||||||
}
|
}
|
||||||
info!("Update | Extract ... OK");
|
info!("Update | Extract ... OK");
|
||||||
|
*update.lock().unwrap().updating.lock().unwrap() = false;
|
||||||
std::process::exit(0);
|
std::process::exit(0);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -388,7 +434,8 @@ pub struct Pkg {
|
||||||
prog: Arc<Mutex<u8>>,
|
prog: Arc<Mutex<u8>>,
|
||||||
msg: Arc<Mutex<String>>,
|
msg: Arc<Mutex<String>>,
|
||||||
bytes: Arc<Mutex<hyper::body::Bytes>>,
|
bytes: Arc<Mutex<hyper::body::Bytes>>,
|
||||||
version: Arc<Mutex<String>>,
|
old_ver: String,
|
||||||
|
new_ver: Arc<Mutex<String>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Pkg {
|
impl Pkg {
|
||||||
|
@ -423,7 +470,8 @@ impl Pkg {
|
||||||
prog,
|
prog,
|
||||||
msg,
|
msg,
|
||||||
bytes: Arc::new(Mutex::new(bytes::Bytes::new())),
|
bytes: Arc::new(Mutex::new(bytes::Bytes::new())),
|
||||||
version: Arc::new(Mutex::new(String::new())),
|
old_ver: String::new(),
|
||||||
|
new_ver: Arc::new(Mutex::new(String::new())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,15 +488,26 @@ impl Pkg {
|
||||||
|
|
||||||
// Get metadata using [Generic hyper::client<C>] & [Request]
|
// Get metadata using [Generic hyper::client<C>] & [Request]
|
||||||
// and change [version, prog] under an Arc<Mutex>
|
// and change [version, prog] under an Arc<Mutex>
|
||||||
pub async fn get_metadata<C>(name: Name, version: Arc<Mutex<String>>, prog: Arc<Mutex<u8>>, client: Client<C>, request: Request<Body>) -> 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*]
|
||||||
|
let mut n = 0;
|
||||||
|
while n < 3 {
|
||||||
|
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?;
|
||||||
let body: Version = serde_json::from_slice(&body)?;
|
let body: TagName = serde_json::from_slice(&body)?;
|
||||||
*version.lock().unwrap() = body.tag_name.clone();
|
if body.tag_name.starts_with('v') {
|
||||||
|
*new_ver.lock().unwrap() = body.tag_name.clone();
|
||||||
*prog.lock().unwrap() += 5;
|
*prog.lock().unwrap() += 5;
|
||||||
info!("Update | Metadata | {} {} ... {}%", name, body.tag_name, *prog.lock().unwrap());
|
info!("Update | Metadata | {} {} ... {}%", name, body.tag_name, *prog.lock().unwrap());
|
||||||
Ok(())
|
return Ok(())
|
||||||
|
}
|
||||||
|
warn!("Update | Metadata | {} metadata fetch failed, retry [{}/3]...", name, n);
|
||||||
|
n += 1;
|
||||||
|
}
|
||||||
|
error!("Update | Metadata | {} metadata fetch failed", name);
|
||||||
|
Err(anyhow!("Metadata fetch failed"))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Takes a [Request], fills the appropriate [Pkg]
|
// Takes a [Request], fills the appropriate [Pkg]
|
||||||
|
@ -471,7 +530,7 @@ impl Pkg {
|
||||||
|
|
||||||
// This inherits the value of [tag_name] from GitHub's JSON API
|
// This inherits the value of [tag_name] from GitHub's JSON API
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
struct Version {
|
struct TagName {
|
||||||
tag_name: String,
|
tag_name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,7 +24,7 @@ use crate::constants::*;
|
||||||
use crate::state::Xmrig;
|
use crate::state::Xmrig;
|
||||||
|
|
||||||
impl Xmrig {
|
impl Xmrig {
|
||||||
pub fn show(&mut self, ctx: &egui::Context, ui: &mut egui::Ui) {
|
pub fn show(&mut self, width: f32, height: f32, ctx: &egui::Context, ui: &mut egui::Ui) {
|
||||||
let height = ui.available_height() / 10.0;
|
let height = ui.available_height() / 10.0;
|
||||||
let mut width = ui.available_width() - 10.0;
|
let mut width = ui.available_width() - 10.0;
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
|
|
Loading…
Reference in a new issue