mirror of
https://github.com/Cyrix126/gupaxx.git
synced 2024-12-22 14:49:21 +00:00
os: fix platform specific issues
This commit is contained in:
parent
b64e1e3a46
commit
22a03a6034
9 changed files with 152 additions and 154 deletions
98
Cargo.lock
generated
98
Cargo.lock
generated
|
@ -2,6 +2,48 @@
|
|||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "Gupax"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arti-client",
|
||||
"arti-hyper",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"dirs",
|
||||
"eframe",
|
||||
"egui",
|
||||
"egui_extras",
|
||||
"env_logger 0.9.1",
|
||||
"figment",
|
||||
"flate2",
|
||||
"hex-literal",
|
||||
"hyper",
|
||||
"hyper-tls",
|
||||
"image",
|
||||
"log",
|
||||
"monero",
|
||||
"num-format",
|
||||
"num_cpus",
|
||||
"rand 0.8.5",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.6",
|
||||
"tar",
|
||||
"tls-api",
|
||||
"tls-api-native-tls",
|
||||
"tokio",
|
||||
"toml",
|
||||
"tor-rtcompat",
|
||||
"walkdir",
|
||||
"winres",
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ab_glyph"
|
||||
version = "0.2.18"
|
||||
|
@ -1158,6 +1200,8 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "eframe"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b0d49426c3e72a6728b0c790d22db8bf7bbcff10d83b8b6f3a01295be982302e"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"egui",
|
||||
|
@ -1178,6 +1222,8 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "egui"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc9fcd393c3daaaf5909008a1d948319d538b79c51871e4df0993260260a94e4"
|
||||
dependencies = [
|
||||
"ahash 0.8.0",
|
||||
"epaint",
|
||||
|
@ -1188,6 +1234,8 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "egui-winit"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07ddc525334c416e11580123e147b970f738507f427c9fb1cd09ea2dd7416a3a"
|
||||
dependencies = [
|
||||
"arboard",
|
||||
"egui",
|
||||
|
@ -1201,6 +1249,8 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "egui_extras"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f698f685bb0ad39e87109e2f695ded0bccde77d5d40bbf7590cb5561c1e3039d"
|
||||
dependencies = [
|
||||
"egui",
|
||||
"image",
|
||||
|
@ -1209,6 +1259,8 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "egui_glow"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ad77d4a00402bae9658ee64be148f4b2a0b38e4fc7874970575ca01ed1c5b75d"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"egui",
|
||||
|
@ -1228,6 +1280,8 @@ checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797"
|
|||
[[package]]
|
||||
name = "emath"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9542a40106fdba943a055f418d1746a050e1a903a049b030c2b097d4686a33cf"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
]
|
||||
|
@ -1284,6 +1338,8 @@ dependencies = [
|
|||
[[package]]
|
||||
name = "epaint"
|
||||
version = "0.19.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5ba04741be7f6602b1a1b28f1082cce45948a7032961c52814f8946b28493300"
|
||||
dependencies = [
|
||||
"ab_glyph",
|
||||
"ahash 0.8.0",
|
||||
|
@ -1766,48 +1822,6 @@ dependencies = [
|
|||
"gl_generator",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gupax"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"arti-client",
|
||||
"arti-hyper",
|
||||
"bytes",
|
||||
"chrono",
|
||||
"dirs",
|
||||
"eframe",
|
||||
"egui",
|
||||
"egui_extras",
|
||||
"env_logger 0.9.1",
|
||||
"figment",
|
||||
"flate2",
|
||||
"hex-literal",
|
||||
"hyper",
|
||||
"hyper-tls",
|
||||
"image",
|
||||
"log",
|
||||
"monero",
|
||||
"num-format",
|
||||
"num_cpus",
|
||||
"rand 0.8.5",
|
||||
"regex",
|
||||
"reqwest",
|
||||
"rusqlite",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2 0.10.6",
|
||||
"tar",
|
||||
"tls-api",
|
||||
"tls-api-native-tls",
|
||||
"tokio",
|
||||
"toml",
|
||||
"tor-rtcompat",
|
||||
"walkdir",
|
||||
"winres",
|
||||
"zip",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.3.15"
|
||||
|
|
23
Cargo.toml
23
Cargo.toml
|
@ -1,6 +1,9 @@
|
|||
[package]
|
||||
name = "gupax"
|
||||
name = "Gupax"
|
||||
version = "0.1.0"
|
||||
authors = ["hinto-janaiyo <hinto-janaiyo@protonmail.com>"]
|
||||
description = "GUI for P2Pool+XMRig"
|
||||
documentation = "https://github.com/hinto-janaiyo/gupax"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
|
@ -10,17 +13,18 @@ arti-hyper = "0.7.0"
|
|||
bytes = "1.2.1"
|
||||
chrono = "0.4.22"
|
||||
dirs = "4.0.0"
|
||||
#eframe = "0.19.0"
|
||||
#egui = "0.19.0"
|
||||
#egui_extras = { version = "0.19.0", features = ["image"] }
|
||||
eframe = "0.19.0"
|
||||
egui = "0.19.0"
|
||||
egui_extras = { version = "0.19.0", features = ["image"] }
|
||||
## [external/egui/crates/eframe/src/native/run.rs] line 41: [.with_srgb(true)]
|
||||
## This line causes a [panic!] inside a Windows VM, from a Linux host.
|
||||
## There are many issue threads and PRs to fix it but for now,
|
||||
## this is here for convenience sake when I'm testing.
|
||||
## The only change is [.with_srgb()] is set to [false].
|
||||
eframe = { path = "external/egui/crates/eframe" }
|
||||
egui = { path = "external/egui/crates/egui" }
|
||||
egui_extras = { path = "external/egui/crates/egui_extras", features = ["image"] }
|
||||
#eframe = { path = "external/egui/crates/eframe" }
|
||||
#egui = { path = "external/egui/crates/egui" }
|
||||
#egui_glow = { path = "external/egui/crates/egui_glow"}
|
||||
#egui_extras = { path = "external/egui/crates/egui_extras", features = ["image"] }
|
||||
env_logger = "0.9.1"
|
||||
figment = { version = "0.10.8", features = ["toml"] }
|
||||
flate2 = "1.0"
|
||||
|
@ -61,6 +65,5 @@ winres = "0.1.12"
|
|||
|
||||
# For macOS build (cargo-bundle)
|
||||
[package.metadata.bundle]
|
||||
identifier = "io.github.hinto-janaiyo.gupax"
|
||||
icon = ["images/png/icon@2x.png"]
|
||||
short_description = "GUI for P2Pool+XMRig"
|
||||
identifier = "com.github.hinto-janaiyo.gupax"
|
||||
icon = ["images/icons/icon@2x.png"]
|
||||
|
|
|
@ -92,7 +92,7 @@ Windows/macOS/Linux:
|
|||
```
|
||||
cargo build --release
|
||||
```
|
||||
On macOS, if you want the binary to have an icon in `Finder`, you must install [`cargo-bundle`](https://github.com/burtonageo/cargo-bundle) and compile with:
|
||||
On macOS, if you want the binary to have an icon in `Finder`, you must install [`cargo-bundle`](https://github.com/burtonageo/cargo-bundle) and compile uwith:
|
||||
```
|
||||
cargo bundle --release
|
||||
```
|
||||
|
|
|
@ -57,6 +57,6 @@ Every frame, the max available `[width, height]` are calculated, and those are u
|
|||
Main [App] outer frame (default: [1280.0, 720.0])
|
||||
├─ Inner frame (1264.0, 704.0)
|
||||
├─ TopPanel = [width: (max-90.0)/5.0, height: max/10.0]
|
||||
├─ BottomPanel = [width: max, height: max/15.0]
|
||||
├─ BottomPanel = [width: max, height: max/18.0]
|
||||
├─ CentralPanel = [width: (max/8.0), height: the rest
|
||||
```
|
||||
|
|
|
@ -96,8 +96,6 @@ r#"USAGE: gupax [--flags]
|
|||
-r | --reset Reset all Gupax configuration/state
|
||||
-f | --ferris Print an extremely cute crab"#;
|
||||
pub const ARG_COPYRIGHT: &'static str =
|
||||
r#"Gupax, P2Pool, and XMRig are licensed under GPLv3.
|
||||
For more information, see here:
|
||||
- https://github.com/hinto-janaiyo/gupax
|
||||
- https://github.com/SChernykh/p2pool
|
||||
- https://github.com/xmrig/xmrig"#;
|
||||
r#"Gupax is licensed under GPLv3.
|
||||
For more information, see link below:
|
||||
<https://github.com/hinto-janaiyo/gupax>"#;
|
||||
|
|
|
@ -51,7 +51,7 @@ impl Gupax {
|
|||
info!("Spawning update thread...");
|
||||
match Update::start(update_thread, og_ver.clone(), state_ver.clone()) {
|
||||
Err(e) => {
|
||||
info!("Update ... {} ... FAIL", e);
|
||||
info!("Update ... FAIL ... {}", e);
|
||||
*update.lock().unwrap().msg.lock().unwrap() = format!("{} | {}", MSG_FAILED, e);
|
||||
},
|
||||
_ => {
|
||||
|
@ -87,13 +87,13 @@ impl Gupax {
|
|||
ui.horizontal(|ui| {
|
||||
ui.group(|ui| {
|
||||
let width = (width - SPACE*9.8)/5.0;
|
||||
let height = height/2.0;
|
||||
let height = height/2.5;
|
||||
let mut style = (*ctx.style()).clone();
|
||||
style.spacing.icon_width_inner = width / 6.0;
|
||||
style.spacing.icon_width = width / 4.0;
|
||||
style.spacing.icon_spacing = 20.0;
|
||||
ctx.set_style(style);
|
||||
let height = height/2.0;
|
||||
let height = height/2.5;
|
||||
ui.add_sized([width, height], egui::Checkbox::new(&mut state.auto_update, "Auto-update")).on_hover_text(GUPAX_AUTO_UPDATE);
|
||||
ui.separator();
|
||||
ui.add_sized([width, height], egui::Checkbox::new(&mut state.auto_node, "Auto-node")).on_hover_text(GUPAX_AUTO_NODE);
|
||||
|
|
52
src/main.rs
52
src/main.rs
|
@ -85,7 +85,7 @@ pub struct App {
|
|||
// Static stuff
|
||||
now: Instant, // Internal timer
|
||||
exe: String, // Path for [Gupax] binary
|
||||
tmp: String, // Tmp folder for updates, random every update
|
||||
dir: String, // Directory [Gupax] binary is in
|
||||
resolution: Vec2, // Frame resolution
|
||||
os: &'static str, // OS
|
||||
version: String, // Gupax version
|
||||
|
@ -115,7 +115,7 @@ impl App {
|
|||
node: Arc::new(Mutex::new(NodeStruct::default())),
|
||||
og: Arc::new(Mutex::new(State::default())),
|
||||
state: State::default(),
|
||||
update: Arc::new(Mutex::new(Update::new(PathBuf::new(), PathBuf::new(), true))),
|
||||
update: Arc::new(Mutex::new(Update::new(String::new(), PathBuf::new(), PathBuf::new(), true))),
|
||||
diff: false,
|
||||
p2pool: false,
|
||||
xmrig: false,
|
||||
|
@ -123,7 +123,7 @@ impl App {
|
|||
reset: false,
|
||||
now: Instant::now(),
|
||||
exe: "".to_string(),
|
||||
tmp: "".to_string(),
|
||||
dir: "".to_string(),
|
||||
resolution: Vec2::new(1280.0, 720.0),
|
||||
os: OS,
|
||||
version: format!("{}", GUPAX_VERSION),
|
||||
|
@ -132,12 +132,16 @@ impl App {
|
|||
};
|
||||
// Apply arg state
|
||||
let mut app = parse_args(app);
|
||||
// Get exe path + random tmp folder
|
||||
app.exe = match get_exe_dir() {
|
||||
// Get exe path
|
||||
app.exe = match get_exe() {
|
||||
Ok(exe) => exe,
|
||||
Err(err) => { panic_main(err.to_string()); exit(1); },
|
||||
};
|
||||
app.tmp = get_rand_tmp(&app.exe);
|
||||
// Get exe directory path
|
||||
app.dir = match get_exe_dir() {
|
||||
Ok(dir) => dir,
|
||||
Err(err) => { panic_main(err.to_string()); exit(1); },
|
||||
};
|
||||
// Read disk state if no [--reset] arg
|
||||
if app.reset == false {
|
||||
app.og = match State::get() {
|
||||
|
@ -157,7 +161,7 @@ impl App {
|
|||
let p2pool_path = app.og.lock().unwrap().gupax.absolute_p2pool_path.clone();
|
||||
let xmrig_path = app.og.lock().unwrap().gupax.absolute_xmrig_path.clone();
|
||||
let tor = app.og.lock().unwrap().gupax.update_via_tor;
|
||||
app.update = Arc::new(Mutex::new(Update::new(p2pool_path, xmrig_path, tor)));
|
||||
app.update = Arc::new(Mutex::new(Update::new(app.exe.clone(), p2pool_path, xmrig_path, tor)));
|
||||
app
|
||||
}
|
||||
}
|
||||
|
@ -264,7 +268,7 @@ fn parse_args(mut app: App) -> App {
|
|||
match arg.as_str() {
|
||||
"-h"|"--help" => { println!("{}", ARG_HELP); exit(0); },
|
||||
"-v"|"--version" => {
|
||||
println!("Gupax | {}\nP2Pool | {}\nXMRig | {}\n\nOS: [{}], Commit: [{}]\n\n{}", GUPAX_VERSION, P2POOL_VERSION, XMRIG_VERSION, OS_NAME, &COMMIT[..40], ARG_COPYRIGHT);
|
||||
println!("Gupax {} (OS: {}, Commit: {})\n\n{}", GUPAX_VERSION, OS_NAME, &COMMIT[..40], ARG_COPYRIGHT);
|
||||
exit(0);
|
||||
},
|
||||
"-f"|"--ferris" => { println!("{}", FERRIS); exit(0); },
|
||||
|
@ -298,25 +302,12 @@ pub fn get_exe_dir() -> Result<String, std::io::Error> {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn get_rand_tmp(path: &String) -> String {
|
||||
use rand::{thread_rng, Rng};
|
||||
use rand::distributions::Alphanumeric;
|
||||
let rand: String = thread_rng()
|
||||
.sample_iter(&Alphanumeric)
|
||||
.take(10)
|
||||
.map(char::from)
|
||||
.collect();
|
||||
let path = path.to_string() + "/gupax_tmp_" + &rand;
|
||||
info!("Generated rand_tmp ... {}", path);
|
||||
path
|
||||
}
|
||||
|
||||
// Clean any [gupax_tmp.*] directories
|
||||
pub fn clean_dir() -> Result<(), anyhow::Error> {
|
||||
for entry in std::fs::read_dir(get_exe_dir()?)? {
|
||||
let entry = entry?;
|
||||
entry.path().is_dir() && continue;
|
||||
if entry.file_name().to_str().ok_or(anyhow::Error::msg("Basename failed"))?.starts_with("gupax_tmp_") {
|
||||
if ! entry.path().is_dir() { continue }
|
||||
if entry.file_name().to_str().ok_or(anyhow::Error::msg("Basename failed"))?.starts_with("gupax_update_") {
|
||||
let path = entry.path();
|
||||
match std::fs::remove_dir_all(&path) {
|
||||
Ok(_) => info!("Remove [{}] ... OK", path.display()),
|
||||
|
@ -431,13 +422,13 @@ impl eframe::App for App {
|
|||
// Close confirmation.
|
||||
if self.quit {
|
||||
// If [ask_before_quit == true]
|
||||
if self.state.gupax.ask_before_quit {
|
||||
if self.og.lock().unwrap().gupax.ask_before_quit {
|
||||
egui::TopBottomPanel::bottom("quit").show(ctx, |ui| {
|
||||
let width = self.width;
|
||||
let height = self.height/8.0;
|
||||
ui.group(|ui| {
|
||||
if ui.add_sized([width, height], egui::Button::new("Yes")).clicked() {
|
||||
if self.state.gupax.save_before_quit {
|
||||
if self.og.lock().unwrap().gupax.save_before_quit {
|
||||
if self.diff {
|
||||
info!("Saving before quit...");
|
||||
match self.state.save() {
|
||||
|
@ -461,15 +452,14 @@ impl eframe::App for App {
|
|||
let ten = height/10.0;
|
||||
// Detect processes or update
|
||||
ui.add_space(ten);
|
||||
// || self.update.updating
|
||||
if self.p2pool || self.xmrig {
|
||||
if *self.update.lock().unwrap().updating.lock().unwrap() || self.p2pool || self.xmrig {
|
||||
ui.add_sized([width, height/4.0], Label::new("Are you sure you want to quit?"));
|
||||
// if self.update.updating { ui.add_sized([width, ten], Label::new("Update is in progress...!")); }
|
||||
if *self.update.lock().unwrap().updating.lock().unwrap() { ui.add_sized([width, ten], Label::new("Update is in progress...!")); }
|
||||
if self.p2pool { ui.add_sized([width, ten], Label::new("P2Pool is online...!")); }
|
||||
if self.xmrig { ui.add_sized([width, ten], Label::new("XMRig is online...!")); }
|
||||
// Else, just quit
|
||||
} else {
|
||||
if self.state.gupax.save_before_quit {
|
||||
if self.og.lock().unwrap().gupax.save_before_quit {
|
||||
if self.diff {
|
||||
info!("Saving before quit...");
|
||||
match self.state.save() {
|
||||
|
@ -486,7 +476,7 @@ impl eframe::App for App {
|
|||
});
|
||||
// Else, quit (save if [save_before_quit == true]
|
||||
} else {
|
||||
if self.state.gupax.save_before_quit {
|
||||
if self.og.lock().unwrap().gupax.save_before_quit {
|
||||
if self.diff {
|
||||
info!("Saving before quit...");
|
||||
match self.state.save() {
|
||||
|
@ -534,7 +524,7 @@ impl eframe::App for App {
|
|||
// Bottom: app info + state/process buttons
|
||||
egui::TopBottomPanel::bottom("bottom").show(ctx, |ui| {
|
||||
let width = self.width/8.0;
|
||||
let height = self.height/15.0;
|
||||
let height = self.height/18.0;
|
||||
ui.style_mut().override_text_style = Some(Name("Bottom".into()));
|
||||
ui.horizontal(|ui| {
|
||||
ui.group(|ui| {
|
||||
|
|
21
src/state.rs
21
src/state.rs
|
@ -96,7 +96,7 @@ impl State {
|
|||
// Windows | {FOLDERID_RoamingAppData} | C:\Users\Alice\AppData\Roaming
|
||||
let mut path = match dirs::data_dir() {
|
||||
Some(mut path) => {
|
||||
path.push(DIRECTORY);
|
||||
path.push(STATE_DIRECTORY);
|
||||
info!("OS data path ... OK");
|
||||
path
|
||||
},
|
||||
|
@ -104,7 +104,7 @@ impl State {
|
|||
};
|
||||
// Create directory
|
||||
fs::create_dir_all(&path)?;
|
||||
path.push(FILENAME);
|
||||
path.push(STATE_FILE);
|
||||
info!("TOML path ... {}", path.display());
|
||||
Ok(path)
|
||||
}
|
||||
|
@ -255,27 +255,24 @@ impl From<std::io::Error> for TomlError {
|
|||
}
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Const
|
||||
const FILENAME: &'static str = "gupax.toml";
|
||||
// State file
|
||||
const STATE_FILE: &'static str = "gupax.toml";
|
||||
const ERROR: &'static str = "TOML Error";
|
||||
const PATH_ERROR: &'static str = "PATH for state directory could not be not found";
|
||||
#[cfg(target_os = "windows")]
|
||||
const DIRECTORY: &'static str = "Gupax";
|
||||
const STATE_DIRECTORY: &'static str = "Gupax";
|
||||
#[cfg(target_os = "macos")]
|
||||
const DIRECTORY: &'static str = "Gupax";
|
||||
const STATE_DIRECTORY: &'static str = "com.github.hinto-janaiyo.gupax";
|
||||
#[cfg(target_os = "linux")]
|
||||
const DIRECTORY: &'static str = "gupax";
|
||||
const STATE_DIRECTORY: &'static str = "gupax";
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
pub const DEFAULT_P2POOL_PATH: &'static str = r"P2Pool\p2pool.exe";
|
||||
#[cfg(target_os = "macos")]
|
||||
pub const DEFAULT_P2POOL_PATH: &'static str = "P2Pool/P2Pool";
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_family = "unix")]
|
||||
pub const DEFAULT_P2POOL_PATH: &'static str = "p2pool/p2pool";
|
||||
#[cfg(target_os = "windows")]
|
||||
pub const DEFAULT_XMRIG_PATH: &'static str = r"XMRig\xmrig.exe";
|
||||
#[cfg(target_os = "macos")]
|
||||
pub const DEFAULT_XMRIG_PATH: &'static str = "XMRig/XMRig";
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_family = "unix")]
|
||||
pub const DEFAULT_XMRIG_PATH: &'static str = "xmrig/xmrig";
|
||||
|
||||
//---------------------------------------------------------------------------------------------------- Error Enum
|
||||
|
|
|
@ -35,6 +35,7 @@ use crate::update::Name::*;
|
|||
use hyper::{Client,Body,Request};
|
||||
use hyper::header::HeaderValue;
|
||||
use hyper_tls::HttpsConnector;
|
||||
use hyper::header::LOCATION;
|
||||
use log::*;
|
||||
use rand::distributions::Alphanumeric;
|
||||
use rand::{thread_rng, Rng};
|
||||
|
@ -55,18 +56,17 @@ use std::os::unix::fs::OpenOptionsExt;
|
|||
|
||||
//---------------------------------------------------------------------------------------------------- Constants
|
||||
// Package naming schemes:
|
||||
// gupax | gupax-vX.X.X-(windows|macos|linux)-x64.(zip|tar.gz)
|
||||
// gupax | gupax-vX.X.X-(windows|macos|linux)-x64(standalone|bundle).(zip|tar.gz)
|
||||
// p2pool | p2pool-vX.X.X-(windows|macos|linux)-x64.(zip|tar.gz)
|
||||
// xmrig | xmrig-X.X.X-(msvc-win64|macos-x64|linux-static-x64).(zip|tar.gz)
|
||||
//
|
||||
// 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.tar.gz
|
||||
//
|
||||
// Exceptions (there are always exceptions...):
|
||||
// - XMRig doesn't have a [v], so it is [xmrig-6.18.0-...]
|
||||
// - XMRig separates the hash and signature
|
||||
// - P2Pool hashes are in UPPERCASE
|
||||
// - Gupax will be downloaded as a standalone binary (no decompression/extraction needed)
|
||||
|
||||
const GUPAX_METADATA: &'static str = "https://api.github.com/repos/hinto-janaiyo/gupax/releases/latest";
|
||||
const P2POOL_METADATA: &'static str = "https://api.github.com/repos/SChernykh/p2pool/releases/latest";
|
||||
|
@ -85,21 +85,21 @@ const P2POOL_HASH: &'static str = "sha256sums.txt.asc";
|
|||
const XMRIG_HASH: &'static str = "SHA256SUMS";
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
const GUPAX_EXTENSION: &'static str = "-windows-x64-standalone.exe";
|
||||
const GUPAX_EXTENSION: &'static str = "-windows-x64-standalone.zip";
|
||||
#[cfg(target_os = "windows")]
|
||||
const P2POOL_EXTENSION: &'static str = "-windows-x64.zip";
|
||||
#[cfg(target_os = "windows")]
|
||||
const XMRIG_EXTENSION: &'static str = "-msvc-win64.zip";
|
||||
|
||||
#[cfg(target_os = "macos")]
|
||||
const GUPAX_EXTENSION: &'static str = "-macos-x64-standalone";
|
||||
const GUPAX_EXTENSION: &'static str = "-macos-x64-standalone.tar.gz";
|
||||
#[cfg(target_os = "macos")]
|
||||
const P2POOL_EXTENSION: &'static str = "-macos-x64.tar.gz";
|
||||
#[cfg(target_os = "macos")]
|
||||
const XMRIG_EXTENSION: &'static str = "-macos-x64.tar.gz";
|
||||
|
||||
#[cfg(target_os = "linux")]
|
||||
const GUPAX_EXTENSION: &'static str = "-linux-x64-standalone";
|
||||
const GUPAX_EXTENSION: &'static str = "-linux-x64-standalone.tar.gz";
|
||||
#[cfg(target_os = "linux")]
|
||||
const P2POOL_EXTENSION: &'static str = "-linux-x64.tar.gz";
|
||||
#[cfg(target_os = "linux")]
|
||||
|
@ -107,23 +107,17 @@ const XMRIG_EXTENSION: &'static str = "-linux-static-x64.tar.gz";
|
|||
|
||||
#[cfg(target_os = "windows")]
|
||||
const GUPAX_BINARY: &'static str = "gupax.exe";
|
||||
#[cfg(target_os = "macos")]
|
||||
const GUPAX_BINARY: &'static str = "Gupax";
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_family = "unix")]
|
||||
const GUPAX_BINARY: &'static str = "gupax";
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
const P2POOL_BINARY: &'static str = "p2pool.exe";
|
||||
#[cfg(target_os = "macos")]
|
||||
const P2POOL_BINARY: &'static str = "P2Pool";
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_family = "unix")]
|
||||
const P2POOL_BINARY: &'static str = "p2pool";
|
||||
|
||||
#[cfg(target_os = "windows")]
|
||||
const XMRIG_BINARY: &'static str = "xmrig.exe";
|
||||
#[cfg(target_os = "macos")]
|
||||
const XMRIG_BINARY: &'static str = "XMRig";
|
||||
#[cfg(target_os = "linux")]
|
||||
#[cfg(target_family = "unix")]
|
||||
const XMRIG_BINARY: &'static str = "xmrig";
|
||||
|
||||
// Some fake Curl/Wget user-agents because GitHub API requires one and a Tor browser
|
||||
|
@ -235,9 +229,9 @@ pub struct Update {
|
|||
|
||||
impl Update {
|
||||
// Takes in current paths from [State]
|
||||
pub fn new(path_p2pool: PathBuf, path_xmrig: PathBuf, tor: bool) -> Self {
|
||||
pub fn new(path_gupax: String, path_p2pool: PathBuf, path_xmrig: PathBuf, tor: bool) -> Self {
|
||||
Self {
|
||||
path_gupax: crate::get_exe().unwrap(),
|
||||
path_gupax,
|
||||
path_p2pool: path_p2pool.display().to_string(),
|
||||
path_xmrig: path_xmrig.display().to_string(),
|
||||
tmp_dir: "".to_string(),
|
||||
|
@ -260,9 +254,9 @@ impl Update {
|
|||
.collect();
|
||||
let base = crate::get_exe_dir()?;
|
||||
#[cfg(target_os = "windows")]
|
||||
let tmp_dir = format!("{}{}{}{}", base, r"\gupax_tmp_", rand_string, r"\");
|
||||
let tmp_dir = format!("{}{}{}{}", base, r"\gupax_update_", rand_string, r"\");
|
||||
#[cfg(target_family = "unix")]
|
||||
let tmp_dir = format!("{}{}{}{}", base, "/gupax_tmp_", rand_string, "/");
|
||||
let tmp_dir = format!("{}{}{}{}", base, "/gupax_update_", rand_string, "/");
|
||||
info!("Update | Temporary directory ... {}", tmp_dir);
|
||||
Ok(tmp_dir)
|
||||
}
|
||||
|
@ -346,7 +340,8 @@ impl Update {
|
|||
}
|
||||
let prog = *update.lock().unwrap().prog.lock().unwrap();
|
||||
info!("Update | {}", update.lock().unwrap().msg.lock().unwrap());
|
||||
let client = Self::get_client(update.lock().unwrap().tor).await?;
|
||||
let tor = update.lock().unwrap().tor;
|
||||
let client = Self::get_client(tor).await?;
|
||||
*update.lock().unwrap().prog.lock().unwrap() += 5.0;
|
||||
info!("Update | Init ... OK ... {}%", prog);
|
||||
|
||||
|
@ -490,14 +485,10 @@ impl Update {
|
|||
let version = pkg.new_ver.lock().unwrap();
|
||||
let link;
|
||||
// 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-x64-standalone
|
||||
// XMRig doesn't have a [v], so slice it out
|
||||
if pkg.name == Name::Xmrig {
|
||||
link = pkg.link_prefix.to_string() + &version + &pkg.link_suffix + &version[1..] + &pkg.link_extension;
|
||||
// TODO FIX ME
|
||||
// This is temp link for v0.0.1 of [Gupax]
|
||||
} else if pkg.name == Name::Gupax {
|
||||
link = "https://github.com/hinto-janaiyo/gupax/releases/download/v0.0.1/gupax-v0.0.1-linux-x64".to_string()
|
||||
} else {
|
||||
link = pkg.link_prefix.to_string() + &version + &pkg.link_suffix + &version + &pkg.link_extension;
|
||||
}
|
||||
|
@ -549,18 +540,15 @@ impl Update {
|
|||
*update.lock().unwrap().msg.lock().unwrap() = format!("{}{}", MSG_EXTRACT, new_pkgs);
|
||||
info!("Update | {}", EXTRACT);
|
||||
for pkg in vec4.iter() {
|
||||
if pkg.name == Name::Gupax {
|
||||
let tmp = tmp_dir.to_owned() + GUPAX_BINARY;
|
||||
#[cfg(target_family = "unix")]
|
||||
std::fs::OpenOptions::new().create(true).write(true).mode(0o750).open(&tmp)?;
|
||||
std::fs::write(tmp, pkg.bytes.lock().unwrap().as_ref())?;
|
||||
} else {
|
||||
let tmp = tmp_dir.to_owned() + &pkg.name.to_string();
|
||||
#[cfg(target_os = "windows")]
|
||||
ZipArchive::extract(&mut ZipArchive::new(std::io::Cursor::new(pkg.bytes.lock().unwrap().as_ref()))?, tmp)?;
|
||||
#[cfg(target_family = "unix")]
|
||||
tar::Archive::new(flate2::read::GzDecoder::new(pkg.bytes.lock().unwrap().as_ref())).unpack(tmp)?;
|
||||
let tmp;
|
||||
match pkg.name {
|
||||
Name::Gupax => tmp = tmp_dir.to_owned() + GUPAX_BINARY,
|
||||
_ => tmp = tmp_dir.to_owned() + &pkg.name.to_string(),
|
||||
}
|
||||
#[cfg(target_os = "windows")]
|
||||
ZipArchive::extract(&mut ZipArchive::new(std::io::Cursor::new(pkg.bytes.lock().unwrap().as_ref()))?, tmp)?;
|
||||
#[cfg(target_family = "unix")]
|
||||
tar::Archive::new(flate2::read::GzDecoder::new(pkg.bytes.lock().unwrap().as_ref())).unpack(tmp)?;
|
||||
*update.lock().unwrap().prog.lock().unwrap() += (5.0 / pkg_amount).round();
|
||||
info!("Update | {} ... OK", pkg.name);
|
||||
}
|
||||
|
@ -577,18 +565,24 @@ impl Update {
|
|||
// Just in case, create all folders
|
||||
for entry in WalkDir::new(tmp_dir.clone()) {
|
||||
let entry = entry?.clone();
|
||||
// If not a file, continue
|
||||
if ! entry.file_type().is_file() { continue }
|
||||
let basename = entry.file_name().to_str().ok_or(anyhow::Error::msg("WalkDir basename failed"))?;
|
||||
match basename {
|
||||
GUPAX_BINARY => {
|
||||
let path = update.lock().unwrap().path_gupax.clone();
|
||||
info!("Update | Moving [{}] -> [{}]", entry.path().display(), path);
|
||||
// Unix can replace running binaries no problem (they're loading into memory)
|
||||
// Windows locks binaries in place, so we must move (rename) current binary
|
||||
// into the temp folder, then move the new binary into the old ones spot.
|
||||
// Clearing the temp folder is now moved at startup instead at the end
|
||||
// of this function due to this behavior, thanks Windows.
|
||||
let path = update.lock().unwrap().path_gupax.clone();
|
||||
#[cfg(target_os = "windows")]
|
||||
std::fs::rename(&path, tmp_dir.clone() + "gupax_old.exe")?;
|
||||
let tmp_windows = tmp_dir.clone() + "gupax_old.exe";
|
||||
#[cfg(target_os = "windows")]
|
||||
info!("Update | WINDOWS ONLY ... Moving [{}] -> [{}]", &path, tmp_windows);
|
||||
#[cfg(target_os = "windows")]
|
||||
std::fs::rename(&path, tmp_windows)?;
|
||||
info!("Update | Moving [{}] -> [{}]", entry.path().display(), path);
|
||||
std::fs::rename(entry.path(), path)?;
|
||||
*update.lock().unwrap().prog.lock().unwrap() += (5.0 / pkg_amount).round();
|
||||
},
|
||||
|
@ -693,7 +687,7 @@ impl Pkg {
|
|||
|
||||
//---------------------------------------------------------------------------------------------------- Pkg functions
|
||||
// Generate fake [User-Agent] HTTP header
|
||||
pub fn get_user_agent() -> &'static str {
|
||||
fn get_user_agent() -> &'static str {
|
||||
let rand = thread_rng().gen_range(0..50);
|
||||
let user_agent = FAKE_USER_AGENT[rand];
|
||||
info!("Update | Randomly selecting User-Agent ({}/50) ... {}", rand, user_agent);
|
||||
|
@ -701,7 +695,7 @@ impl Pkg {
|
|||
}
|
||||
|
||||
// Generate GET request based off input URI + fake user agent
|
||||
pub fn get_request(link: String, user_agent: &'static str) -> Result<Request<Body>, anyhow::Error> {
|
||||
fn get_request(link: String, user_agent: &'static str) -> Result<Request<Body>, anyhow::Error> {
|
||||
let request = Request::builder()
|
||||
.method("GET")
|
||||
.uri(link)
|
||||
|
@ -712,8 +706,8 @@ impl Pkg {
|
|||
|
||||
// Get metadata using [Generic hyper::client<C>] & [Request]
|
||||
// and change [version, prog] under an Arc<Mutex>
|
||||
pub async fn get_metadata<C>(name: Name, new_ver: Arc<Mutex<String>>, client: Client<C>, link: String, user_agent: &'static str) -> Result<(), Error>
|
||||
where C: hyper::client::connect::Connect + Clone + Send + Sync + 'static, {
|
||||
async fn get_metadata<C>(name: Name, new_ver: Arc<Mutex<String>>, client: Client<C>, link: String, user_agent: &'static str) -> Result<(), Error>
|
||||
where C: hyper::client::connect::Connect + Clone + Send + Sync + 'static, {
|
||||
let request = Pkg::get_request(link.clone(), user_agent)?;
|
||||
let mut response = client.request(request).await?;
|
||||
let body = hyper::body::to_bytes(response.body_mut()).await?;
|
||||
|
@ -724,15 +718,17 @@ impl Pkg {
|
|||
|
||||
// Takes a [Request], fills the appropriate [Pkg]
|
||||
// [bytes] field with the [Archive/Standalone]
|
||||
pub async fn get_bytes<C>(name: Name, bytes: Arc<Mutex<bytes::Bytes>>, client: Client<C>, link: String, user_agent: &'static str) -> Result<(), anyhow::Error>
|
||||
where C: hyper::client::connect::Connect + Clone + Send + Sync + 'static, {
|
||||
async fn get_bytes<C>(name: Name, bytes: Arc<Mutex<bytes::Bytes>>, client: Client<C>, link: String, user_agent: &'static str) -> Result<(), anyhow::Error>
|
||||
where C: hyper::client::connect::Connect + Clone + Send + Sync + 'static, {
|
||||
let request = Self::get_request(link.clone(), user_agent)?;
|
||||
let mut response = client.request(request).await?;
|
||||
// GitHub sends a 302 redirect, so we must follow
|
||||
// the [Location] header... only if Reqwest had custom
|
||||
// connectors so I didn't have to manually do this...
|
||||
let request = Self::get_request(link.clone(), user_agent)?;
|
||||
let response = client.request(request).await?;
|
||||
let request = Self::get_request(response.headers().get(hyper::header::LOCATION).unwrap().to_str()?.to_string(), user_agent)?;
|
||||
let response = client.request(request).await?;
|
||||
if response.headers().contains_key(LOCATION) {
|
||||
let request = Self::get_request(response.headers().get(LOCATION).unwrap().to_str()?.to_string(), user_agent)?;
|
||||
response = client.request(request).await?;
|
||||
}
|
||||
let body = hyper::body::to_bytes(response.into_body()).await?;
|
||||
*bytes.lock().unwrap() = body;
|
||||
Ok(())
|
||||
|
|
Loading…
Reference in a new issue