mirror of
https://github.com/hinto-janai/gupax.git
synced 2024-11-18 02:07:40 +00:00
main/disk: get OS data path only once, pass ref for [state/node]
This commit is contained in:
parent
7a5fe24276
commit
d0ced90bb1
3 changed files with 140 additions and 118 deletions
70
src/disk.rs
70
src/disk.rs
|
@ -50,39 +50,25 @@ use log::*;
|
||||||
// create_new() | Write a default TOML Struct into the appropriate file (in OS data path)
|
// create_new() | Write a default TOML Struct into the appropriate file (in OS data path)
|
||||||
// into_absolute_path() | Convert relative -> absolute path
|
// into_absolute_path() | Convert relative -> absolute path
|
||||||
|
|
||||||
pub fn get_os_data_path() -> Result<PathBuf, TomlError> {
|
pub fn get_gupax_data_path() -> Result<PathBuf, TomlError> {
|
||||||
// Get OS data folder
|
// Get OS data folder
|
||||||
// Linux | $XDG_DATA_HOME or $HOME/.local/share | /home/alice/.local/state
|
// Linux | $XDG_DATA_HOME or $HOME/.local/share/gupax | /home/alice/.local/state/gupax
|
||||||
// macOS | $HOME/Library/Application Support | /Users/Alice/Library/Application Support
|
// macOS | $HOME/Library/Application Support/Gupax | /Users/Alice/Library/Application Support/Gupax
|
||||||
// Windows | {FOLDERID_RoamingAppData} | C:\Users\Alice\AppData\Roaming
|
// Windows | {FOLDERID_RoamingAppData}\Gupax | C:\Users\Alice\AppData\Roaming\Gupax
|
||||||
let path = match dirs::data_dir() {
|
match dirs::data_dir() {
|
||||||
Some(path) => {
|
|
||||||
info!("OS | Data path ... OK");
|
|
||||||
path
|
|
||||||
},
|
|
||||||
None => { error!("OS | Data path ... FAIL"); return Err(TomlError::Path(PATH_ERROR.to_string())) },
|
|
||||||
};
|
|
||||||
// Create directory
|
|
||||||
fs::create_dir_all(&path)?;
|
|
||||||
Ok(path)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn get_file_path(file: File) -> Result<PathBuf, TomlError> {
|
|
||||||
let name = File::name(&file);
|
|
||||||
|
|
||||||
let mut path = match dirs::data_dir() {
|
|
||||||
Some(mut path) => {
|
Some(mut path) => {
|
||||||
path.push(DIRECTORY);
|
path.push(DIRECTORY);
|
||||||
info!("OS | Data path ... OK");
|
info!("OS | Data path ... OK ... {}", path.display());
|
||||||
path
|
Ok(path)
|
||||||
},
|
},
|
||||||
None => { error!("Couldn't get OS PATH for data"); return Err(TomlError::Path(PATH_ERROR.to_string())) },
|
None => { error!("OS | Data path ... FAIL"); Err(TomlError::Path(PATH_ERROR.to_string())) },
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn create_gupax_dir(path: PathBuf) -> Result<(), TomlError> {
|
||||||
// Create directory
|
// Create directory
|
||||||
fs::create_dir_all(&path)?;
|
fs::create_dir_all(&path)?;
|
||||||
path.push(name);
|
Ok(())
|
||||||
info!("{:?} | Path ... {}", file, path.display());
|
|
||||||
Ok(path)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert a [File] path to a [String]
|
// Convert a [File] path to a [String]
|
||||||
|
@ -198,15 +184,14 @@ impl State {
|
||||||
// |_ Create a default file if not found
|
// |_ Create a default file if not found
|
||||||
// 2. Deserialize [String] into a proper [Struct]
|
// 2. Deserialize [String] into a proper [Struct]
|
||||||
// |_ Attempt to merge if deserialization fails
|
// |_ Attempt to merge if deserialization fails
|
||||||
pub fn get() -> Result<Self, TomlError> {
|
pub fn get(path: &PathBuf) -> Result<Self, TomlError> {
|
||||||
// Read
|
// Read
|
||||||
let file = File::State;
|
let file = File::State;
|
||||||
let path = get_file_path(file)?;
|
|
||||||
let string = match read_to_string(file, &path) {
|
let string = match read_to_string(file, &path) {
|
||||||
Ok(string) => string,
|
Ok(string) => string,
|
||||||
// Create
|
// Create
|
||||||
_ => {
|
_ => {
|
||||||
Self::create_new()?;
|
Self::create_new(path)?;
|
||||||
match read_to_string(file, &path) {
|
match read_to_string(file, &path) {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(e) => return Err(e),
|
Err(e) => return Err(e),
|
||||||
|
@ -218,17 +203,16 @@ impl State {
|
||||||
Ok(s) => Ok(s),
|
Ok(s) => Ok(s),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("State | Attempting merge...");
|
warn!("State | Attempting merge...");
|
||||||
Self::merge(string)
|
Self::merge(string, path)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Completely overwrite current [state.toml]
|
// Completely overwrite current [state.toml]
|
||||||
// with a new default version, and return [Self].
|
// with a new default version, and return [Self].
|
||||||
pub fn create_new() -> Result<Self, TomlError> {
|
pub fn create_new(path: &PathBuf) -> Result<Self, TomlError> {
|
||||||
info!("State | Creating new default...");
|
info!("State | Creating new default...");
|
||||||
let new = Self::new();
|
let new = Self::new();
|
||||||
let path = get_file_path(File::State)?;
|
|
||||||
let string = match toml::ser::to_string(&new) {
|
let string = match toml::ser::to_string(&new) {
|
||||||
Ok(o) => { info!("State | Serialization ... OK"); o },
|
Ok(o) => { info!("State | Serialization ... OK"); o },
|
||||||
Err(e) => { error!("State | Couldn't serialize default file: {}", e); return Err(TomlError::Serialize(e)) },
|
Err(e) => { error!("State | Couldn't serialize default file: {}", e); return Err(TomlError::Serialize(e)) },
|
||||||
|
@ -239,9 +223,8 @@ impl State {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save [State] onto disk file [gupax.toml]
|
// Save [State] onto disk file [gupax.toml]
|
||||||
pub fn save(&mut self) -> Result<(), TomlError> {
|
pub fn save(&mut self, path: &PathBuf) -> Result<(), TomlError> {
|
||||||
info!("State | Saving to disk...");
|
info!("State | Saving to disk...");
|
||||||
let path = get_file_path(File::State)?;
|
|
||||||
// Convert path to absolute
|
// Convert path to absolute
|
||||||
self.gupax.absolute_p2pool_path = into_absolute_path(self.gupax.p2pool_path.clone())?;
|
self.gupax.absolute_p2pool_path = into_absolute_path(self.gupax.p2pool_path.clone())?;
|
||||||
self.gupax.absolute_xmrig_path = into_absolute_path(self.gupax.xmrig_path.clone())?;
|
self.gupax.absolute_xmrig_path = into_absolute_path(self.gupax.xmrig_path.clone())?;
|
||||||
|
@ -262,7 +245,7 @@ impl State {
|
||||||
// Take [String] as input, merge it with whatever the current [default] is,
|
// Take [String] as input, merge it with whatever the current [default] is,
|
||||||
// leaving behind old keys+values and updating [default] with old valid ones.
|
// leaving behind old keys+values and updating [default] with old valid ones.
|
||||||
// Automatically overwrite current file.
|
// Automatically overwrite current file.
|
||||||
pub fn merge(old: String) -> Result<Self, TomlError> {
|
pub fn merge(old: String, path: &PathBuf) -> Result<Self, TomlError> {
|
||||||
let default = match toml::ser::to_string(&Self::new()) {
|
let default = match toml::ser::to_string(&Self::new()) {
|
||||||
Ok(string) => { info!("State | Default TOML parse ... OK"); string },
|
Ok(string) => { info!("State | Default TOML parse ... OK"); string },
|
||||||
Err(err) => { error!("State | Couldn't parse default TOML into string"); return Err(TomlError::Serialize(err)) },
|
Err(err) => { error!("State | Couldn't parse default TOML into string"); return Err(TomlError::Serialize(err)) },
|
||||||
|
@ -272,7 +255,7 @@ impl State {
|
||||||
Err(err) => { error!("State | Couldn't merge default + old TOML"); return Err(TomlError::Merge(err)) },
|
Err(err) => { error!("State | Couldn't merge default + old TOML"); return Err(TomlError::Merge(err)) },
|
||||||
};
|
};
|
||||||
// Attempt save
|
// Attempt save
|
||||||
Self::save(&mut new)?;
|
Self::save(&mut new, path)?;
|
||||||
Ok(new)
|
Ok(new)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -348,15 +331,14 @@ impl Node {
|
||||||
// |_ Create a default file if not found
|
// |_ Create a default file if not found
|
||||||
// 2. Deserialize [String] into a proper [Struct]
|
// 2. Deserialize [String] into a proper [Struct]
|
||||||
// |_ Attempt to merge if deserialization fails
|
// |_ Attempt to merge if deserialization fails
|
||||||
pub fn get() -> Result<Vec<(String, Self)>, TomlError> {
|
pub fn get(path: &PathBuf) -> Result<Vec<(String, Self)>, TomlError> {
|
||||||
// Read
|
// Read
|
||||||
let file = File::Node;
|
let file = File::Node;
|
||||||
let path = get_file_path(file)?;
|
|
||||||
let string = match read_to_string(file, &path) {
|
let string = match read_to_string(file, &path) {
|
||||||
Ok(string) => string,
|
Ok(string) => string,
|
||||||
// Create
|
// Create
|
||||||
_ => {
|
_ => {
|
||||||
Self::create_new()?;
|
Self::create_new(path)?;
|
||||||
read_to_string(file, &path)?
|
read_to_string(file, &path)?
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -366,10 +348,9 @@ impl Node {
|
||||||
|
|
||||||
// Completely overwrite current [node.toml]
|
// Completely overwrite current [node.toml]
|
||||||
// with a new default version, and return [Vec<String, Self>].
|
// with a new default version, and return [Vec<String, Self>].
|
||||||
pub fn create_new() -> Result<Vec<(String, Self)>, TomlError> {
|
pub fn create_new(path: &PathBuf) -> Result<Vec<(String, Self)>, TomlError> {
|
||||||
info!("Node | Creating new default...");
|
info!("Node | Creating new default...");
|
||||||
let new = Self::new_vec();
|
let new = Self::new_vec();
|
||||||
let path = get_file_path(File::Node)?;
|
|
||||||
let string = Self::to_string(&Self::new_vec());
|
let string = Self::to_string(&Self::new_vec());
|
||||||
fs::write(&path, &string)?;
|
fs::write(&path, &string)?;
|
||||||
info!("Node | Write ... OK");
|
info!("Node | Write ... OK");
|
||||||
|
@ -377,9 +358,8 @@ impl Node {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Save [Node] onto disk file [node.toml]
|
// Save [Node] onto disk file [node.toml]
|
||||||
pub fn save(vec: &Vec<(String, Self)>) -> Result<(), TomlError> {
|
pub fn save(vec: &Vec<(String, Self)>, path: &PathBuf) -> Result<(), TomlError> {
|
||||||
info!("Node | Saving to disk...");
|
info!("Node | Saving to disk...");
|
||||||
let path = get_file_path(File::Node)?;
|
|
||||||
let string = Self::to_string(vec);
|
let string = Self::to_string(vec);
|
||||||
match fs::write(path, string) {
|
match fs::write(path, string) {
|
||||||
Ok(_) => { info!("TOML save ... OK"); Ok(()) },
|
Ok(_) => { info!("TOML save ... OK"); Ok(()) },
|
||||||
|
@ -439,7 +419,7 @@ const PATH_ERROR: &'static str = "PATH for state directory could not be not foun
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(target_os = "windows")]
|
||||||
const DIRECTORY: &'static str = r#"Gupax\"#;
|
const DIRECTORY: &'static str = r#"Gupax\"#;
|
||||||
#[cfg(target_os = "macos")]
|
#[cfg(target_os = "macos")]
|
||||||
const DIRECTORY: &'static str = "com.github.hinto-janaiyo.gupax/";
|
const DIRECTORY: &'static str = "Gupax/";
|
||||||
#[cfg(target_os = "linux")]
|
#[cfg(target_os = "linux")]
|
||||||
const DIRECTORY: &'static str = "gupax/";
|
const DIRECTORY: &'static str = "gupax/";
|
||||||
|
|
||||||
|
|
12
src/gupax.rs
12
src/gupax.rs
|
@ -25,8 +25,11 @@ use egui::{
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::disk::{Gupax,Version};
|
use crate::disk::{Gupax,Version};
|
||||||
use crate::update::*;
|
use crate::update::*;
|
||||||
use std::thread;
|
use std::{
|
||||||
use std::sync::{Arc,Mutex};
|
thread,
|
||||||
|
sync::{Arc,Mutex},
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
use log::*;
|
use log::*;
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- FileWindow
|
//---------------------------------------------------------------------------------------------------- FileWindow
|
||||||
|
@ -55,7 +58,7 @@ impl FileWindow {
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Gupax
|
//---------------------------------------------------------------------------------------------------- Gupax
|
||||||
impl Gupax {
|
impl Gupax {
|
||||||
pub fn show(&mut self, og: &Arc<Mutex<State>>, state_ver: &Arc<Mutex<Version>>, update: &Arc<Mutex<Update>>, file_window: &Arc<Mutex<FileWindow>>, width: f32, height: f32, ctx: &egui::Context, ui: &mut egui::Ui) {
|
pub fn show(&mut self, og: &Arc<Mutex<State>>, state_ver: &Arc<Mutex<Version>>, update: &Arc<Mutex<Update>>, file_window: &Arc<Mutex<FileWindow>>, state_path: &PathBuf, width: f32, height: f32, ctx: &egui::Context, ui: &mut egui::Ui) {
|
||||||
// Update button + Progress bar
|
// Update button + Progress bar
|
||||||
ui.group(|ui| {
|
ui.group(|ui| {
|
||||||
// These are in unnecessary [ui.vertical()]'s
|
// These are in unnecessary [ui.vertical()]'s
|
||||||
|
@ -75,6 +78,7 @@ impl Gupax {
|
||||||
let state_ver = Arc::clone(&state_ver);
|
let state_ver = Arc::clone(&state_ver);
|
||||||
let update = Arc::clone(&update);
|
let update = Arc::clone(&update);
|
||||||
let update_thread = Arc::clone(&update);
|
let update_thread = Arc::clone(&update);
|
||||||
|
let state_path = state_path.clone();
|
||||||
thread::spawn(move|| {
|
thread::spawn(move|| {
|
||||||
info!("Spawning update thread...");
|
info!("Spawning update thread...");
|
||||||
match Update::start(update_thread, og.clone(), state_ver.clone()) {
|
match Update::start(update_thread, og.clone(), state_ver.clone()) {
|
||||||
|
@ -84,7 +88,7 @@ impl Gupax {
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
info!("Update | Saving state...");
|
info!("Update | Saving state...");
|
||||||
match State::save(&mut og.lock().unwrap()) {
|
match State::save(&mut og.lock().unwrap(), &state_path) {
|
||||||
Ok(_) => info!("Update ... OK"),
|
Ok(_) => info!("Update ... OK"),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("Update | Saving state ... FAIL ... {}", e);
|
warn!("Update | Saving state ... FAIL ... {}", e);
|
||||||
|
|
176
src/main.rs
176
src/main.rs
|
@ -37,12 +37,14 @@ use env_logger::{Builder,WriteStyle};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
// std
|
// std
|
||||||
use std::io::Write;
|
use std::{
|
||||||
use std::process::exit;
|
io::Write,
|
||||||
use std::sync::{Arc,Mutex};
|
process::exit,
|
||||||
use std::{thread,env};
|
sync::{Arc,Mutex},
|
||||||
use std::time::Instant;
|
{thread,env},
|
||||||
use std::path::PathBuf;
|
time::Instant,
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
// Modules
|
// Modules
|
||||||
mod ferris;
|
mod ferris;
|
||||||
|
@ -93,6 +95,8 @@ pub struct App {
|
||||||
resolution: Vec2, // Frame resolution
|
resolution: Vec2, // Frame resolution
|
||||||
os: &'static str, // OS
|
os: &'static str, // OS
|
||||||
os_data_path: PathBuf, // OS data path (e.g: ~/.local/share/gupax)
|
os_data_path: PathBuf, // OS data path (e.g: ~/.local/share/gupax)
|
||||||
|
state_path: PathBuf, // State file path
|
||||||
|
node_path: PathBuf, // Node file path
|
||||||
version: &'static str, // Gupax version
|
version: &'static str, // Gupax version
|
||||||
name_version: String, // [Gupax vX.X.X]
|
name_version: String, // [Gupax vX.X.X]
|
||||||
img: Images, // Custom Struct holding pre-compiled bytes of [Images]
|
img: Images, // Custom Struct holding pre-compiled bytes of [Images]
|
||||||
|
@ -111,7 +115,7 @@ impl App {
|
||||||
|
|
||||||
fn new() -> Self {
|
fn new() -> Self {
|
||||||
info!("Initializing App Struct...");
|
info!("Initializing App Struct...");
|
||||||
let app = Self {
|
let mut app = Self {
|
||||||
tab: Tab::default(),
|
tab: Tab::default(),
|
||||||
ping: Arc::new(Mutex::new(Ping::new())),
|
ping: Arc::new(Mutex::new(Ping::new())),
|
||||||
width: 1280.0,
|
width: 1280.0,
|
||||||
|
@ -128,68 +132,82 @@ impl App {
|
||||||
xmrig: false,
|
xmrig: false,
|
||||||
no_startup: false,
|
no_startup: false,
|
||||||
now: Instant::now(),
|
now: Instant::now(),
|
||||||
exe: "".to_string(),
|
exe: String::new(),
|
||||||
dir: "".to_string(),
|
dir: String::new(),
|
||||||
resolution: Vec2::new(1280.0, 720.0),
|
resolution: Vec2::new(1280.0, 720.0),
|
||||||
os: OS,
|
os: OS,
|
||||||
os_data_path: PathBuf::new(),
|
os_data_path: PathBuf::new(),
|
||||||
|
state_path: PathBuf::new(),
|
||||||
|
node_path: PathBuf::new(),
|
||||||
version: GUPAX_VERSION,
|
version: GUPAX_VERSION,
|
||||||
name_version: format!("Gupax {}", GUPAX_VERSION),
|
name_version: format!("Gupax {}", GUPAX_VERSION),
|
||||||
img: Images::new(),
|
img: Images::new(),
|
||||||
regex: Regexes::new(),
|
regex: Regexes::new(),
|
||||||
};
|
};
|
||||||
// Apply arg state
|
//---------------------------------------------------------------------------------------------------- App init data that *could* panic
|
||||||
let mut app = parse_args(app);
|
let mut panic = String::new();
|
||||||
// Get exe path
|
// Get exe path
|
||||||
app.exe = match get_exe() {
|
app.exe = match get_exe() {
|
||||||
Ok(exe) => exe,
|
Ok(exe) => exe,
|
||||||
Err(err) => { panic_main(err.to_string()); exit(1); },
|
Err(e) => { panic = format!("get_exe(): {}", e); app.error_state.set(panic.clone(), ErrorFerris::Panic, ErrorButtons::Quit); String::new() },
|
||||||
};
|
};
|
||||||
// Get exe directory path
|
// Get exe directory path
|
||||||
app.dir = match get_exe_dir() {
|
app.dir = match get_exe_dir() {
|
||||||
Ok(dir) => dir,
|
Ok(dir) => dir,
|
||||||
Err(err) => { panic_main(err.to_string()); exit(1); },
|
Err(e) => { panic = format!("get_exe_dir(): {}", e); app.error_state.set(panic.clone(), ErrorFerris::Panic, ErrorButtons::Quit); String::new() },
|
||||||
};
|
};
|
||||||
// Get OS data path
|
// Get OS data path
|
||||||
app.os_data_path = match get_os_data_path() {
|
app.os_data_path = match get_gupax_data_path() {
|
||||||
Ok(dir) => dir,
|
Ok(dir) => dir,
|
||||||
Err(err) => { panic_main(err.to_string()); exit(1); },
|
Err(e) => { panic = format!("get_os_data_path(): {}", e); app.error_state.set(panic.clone(), ErrorFerris::Panic, ErrorButtons::Quit); PathBuf::new() },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Set [state.toml/node.toml] path
|
||||||
|
app.state_path = app.os_data_path.clone();
|
||||||
|
app.state_path.push("state.toml");
|
||||||
|
app.node_path = app.os_data_path.clone();
|
||||||
|
app.node_path.push("node.toml");
|
||||||
|
|
||||||
|
// Apply arg state
|
||||||
|
// It's not safe to [--reset] if any of the previous variables
|
||||||
|
// are unset (null path), so make sure we just abort if the [panic] String contains something.
|
||||||
|
let mut app = parse_args(app, panic);
|
||||||
|
|
||||||
// Read disk state
|
// Read disk state
|
||||||
use TomlError::*;
|
use TomlError::*;
|
||||||
app.state = match State::get() {
|
app.state = match State::get(&app.state_path) {
|
||||||
Ok(toml) => toml,
|
Ok(toml) => toml,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("State ... {}", err);
|
error!("State ... {}", err);
|
||||||
match err {
|
match err {
|
||||||
Io(e) => app.error_state.set(true, format!("State file: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
Io(e) => app.error_state.set(format!("State file: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
||||||
Path(e) => app.error_state.set(true, format!("State file: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
Path(e) => app.error_state.set(format!("State file: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
||||||
Serialize(e) => app.error_state.set(true, format!("State file: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
Serialize(e) => app.error_state.set(format!("State file: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
||||||
Deserialize(e) => app.error_state.set(true, format!("State file: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
Deserialize(e) => app.error_state.set(format!("State file: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
||||||
Merge(e) => app.error_state.set(true, format!("State file: {}", e), ErrorFerris::Error, ErrorButtons::ResetState),
|
Merge(e) => app.error_state.set(format!("State file: {}", e), ErrorFerris::Error, ErrorButtons::ResetState),
|
||||||
};
|
};
|
||||||
State::new()
|
State::new()
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
app.og = Arc::new(Mutex::new(app.state.clone()));
|
app.og = Arc::new(Mutex::new(app.state.clone()));
|
||||||
// Read node list
|
// Read node list
|
||||||
app.og_node_vec = match Node::get() {
|
app.og_node_vec = match Node::get(&app.node_path) {
|
||||||
Ok(toml) => toml,
|
Ok(toml) => toml,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Node ... {}", err);
|
error!("Node ... {}", err);
|
||||||
match err {
|
match err {
|
||||||
Io(e) => app.error_state.set(true, format!("Node list: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
Io(e) => app.error_state.set(format!("Node list: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
||||||
Path(e) => app.error_state.set(true, format!("Node list: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
Path(e) => app.error_state.set(format!("Node list: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
||||||
Serialize(e) => app.error_state.set(true, format!("Node list: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
Serialize(e) => app.error_state.set(format!("Node list: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
||||||
Deserialize(e) => app.error_state.set(true, format!("Node list: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
Deserialize(e) => app.error_state.set(format!("Node list: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
||||||
Merge(e) => app.error_state.set(true, format!("Node list: {}", e), ErrorFerris::Error, ErrorButtons::ResetState),
|
Merge(e) => app.error_state.set(format!("Node list: {}", e), ErrorFerris::Error, ErrorButtons::ResetState),
|
||||||
};
|
};
|
||||||
Node::new_vec()
|
Node::new_vec()
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
app.node_vec = app.og_node_vec.clone();
|
app.node_vec = app.og_node_vec.clone();
|
||||||
|
|
||||||
|
//----------------------------------------------------------------------------------------------------
|
||||||
let mut og = app.og.lock().unwrap(); // Lock [og]
|
let mut og = app.og.lock().unwrap(); // Lock [og]
|
||||||
// Handle max threads
|
// Handle max threads
|
||||||
og.xmrig.max_threads = num_cpus::get();
|
og.xmrig.max_threads = num_cpus::get();
|
||||||
|
@ -259,10 +277,20 @@ impl ErrorState {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convenience function to set the [App] error state
|
// Convenience function to enable the [App] error state
|
||||||
pub fn set(&mut self, error: bool, msg: impl Into<String>, ferris: ErrorFerris, buttons: ErrorButtons) {
|
pub fn set(&mut self, msg: impl Into<String>, ferris: ErrorFerris, buttons: ErrorButtons) {
|
||||||
|
if self.error {
|
||||||
|
// If a panic error is already set, return
|
||||||
|
if self.ferris == ErrorFerris::Panic { return }
|
||||||
|
// If we shouldn't be overriding the current error, return
|
||||||
|
match self.buttons {
|
||||||
|
ErrorButtons::YesNo => (), // Not important
|
||||||
|
ErrorButtons::Okay => (), // Not important
|
||||||
|
_ => return, // Overwrite, Quits, etc
|
||||||
|
}
|
||||||
|
}
|
||||||
*self = Self {
|
*self = Self {
|
||||||
error,
|
error: true,
|
||||||
msg: msg.into(),
|
msg: msg.into(),
|
||||||
ferris,
|
ferris,
|
||||||
buttons,
|
buttons,
|
||||||
|
@ -433,6 +461,7 @@ fn init_auto(app: &App) {
|
||||||
let state_ver = Arc::clone(&app.state.version);
|
let state_ver = Arc::clone(&app.state.version);
|
||||||
let update = Arc::clone(&app.update);
|
let update = Arc::clone(&app.update);
|
||||||
let update_thread = Arc::clone(&app.update);
|
let update_thread = Arc::clone(&app.update);
|
||||||
|
let state_path = app.state_path.clone();
|
||||||
thread::spawn(move|| {
|
thread::spawn(move|| {
|
||||||
info!("Spawning update thread...");
|
info!("Spawning update thread...");
|
||||||
match Update::start(update_thread, og.clone(), state_ver.clone()) {
|
match Update::start(update_thread, og.clone(), state_ver.clone()) {
|
||||||
|
@ -442,7 +471,7 @@ fn init_auto(app: &App) {
|
||||||
},
|
},
|
||||||
_ => {
|
_ => {
|
||||||
info!("Update | Saving state...");
|
info!("Update | Saving state...");
|
||||||
match State::save(&mut og.lock().unwrap()) {
|
match State::save(&mut og.lock().unwrap(), &state_path) {
|
||||||
Ok(_) => info!("Update ... OK"),
|
Ok(_) => info!("Update ... OK"),
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
warn!("Update | Saving state ... FAIL ... {}", e);
|
warn!("Update | Saving state ... FAIL ... {}", e);
|
||||||
|
@ -472,41 +501,47 @@ fn init_auto(app: &App) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_state() -> Result<(), TomlError> {
|
fn reset_state(path: &PathBuf) -> Result<(), TomlError> {
|
||||||
info!("Resetting [state.toml]...");
|
info!("Resetting [state.toml]...");
|
||||||
match State::create_new() {
|
match State::create_new(path) {
|
||||||
Ok(_) => { info!("Resetting [state.toml] ... OK"); Ok(()) },
|
Ok(_) => { info!("Resetting [state.toml] ... OK"); Ok(()) },
|
||||||
Err(e) => { error!("Resetting [state.toml] ... FAIL ... {}", e); Err(e) },
|
Err(e) => { error!("Resetting [state.toml] ... FAIL ... {}", e); Err(e) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_nodes() -> Result<(), TomlError> {
|
fn reset_nodes(path: &PathBuf) -> Result<(), TomlError> {
|
||||||
info!("Resetting [node.toml]...");
|
info!("Resetting [node.toml]...");
|
||||||
match Node::create_new() {
|
match Node::create_new(path) {
|
||||||
Ok(_) => { info!("Resetting [node.toml] ... OK"); Ok(()) },
|
Ok(_) => { info!("Resetting [node.toml] ... OK"); Ok(()) },
|
||||||
Err(e) => { error!("Resetting [node.toml] ... FAIL ... {}", e); Err(e) },
|
Err(e) => { error!("Resetting [node.toml] ... FAIL ... {}", e); Err(e) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset() {
|
fn reset(path: &PathBuf, state: &PathBuf, node: &PathBuf) {
|
||||||
let mut code = 0;
|
let mut code = 0;
|
||||||
match reset_state() {
|
// Attempt to remove directory first
|
||||||
|
info!("OS data path ... {}", path.display());
|
||||||
|
match std::fs::remove_dir_all(path) {
|
||||||
|
Ok(_) => info!("Removing OS data path ... OK"),
|
||||||
|
Err(e) => { error!("Removing OS data path ... FAIL ... {}", e); code = 1; },
|
||||||
|
}
|
||||||
|
match reset_state(state) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(_) => code = 1,
|
Err(_) => code = 1,
|
||||||
}
|
}
|
||||||
match reset_nodes() {
|
match reset_nodes(node) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(_) => code = 1,
|
Err(_) => code = 1,
|
||||||
}
|
}
|
||||||
match code {
|
match code {
|
||||||
0 => println!("\nGupax files were reset successfully."),
|
0 => println!("\nGupax reset ... OK"),
|
||||||
_ => println!("\nGupax files reset FAILED."),
|
_ => println!("\nGupax reset ... FAIL"),
|
||||||
}
|
}
|
||||||
exit(code);
|
exit(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------------------------------- Misc functions
|
//---------------------------------------------------------------------------------------------------- Misc functions
|
||||||
fn parse_args(mut app: App) -> App {
|
fn parse_args<S: Into<String>>(mut app: App, panic: S) -> App {
|
||||||
info!("Parsing CLI arguments...");
|
info!("Parsing CLI arguments...");
|
||||||
let mut args: Vec<String> = env::args().collect();
|
let mut args: Vec<String> = env::args().collect();
|
||||||
if args.len() == 1 { info!("No args ... OK"); return app } else { args.remove(0); info!("Args ... {:?}", args); }
|
if args.len() == 1 { info!("No args ... OK"); return app } else { args.remove(0); info!("Args ... {:?}", args); }
|
||||||
|
@ -522,14 +557,21 @@ fn parse_args(mut app: App) -> App {
|
||||||
_ => (),
|
_ => (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Abort on panic
|
||||||
|
let panic = panic.into();
|
||||||
|
if ! panic.is_empty() {
|
||||||
|
info!("[Gupax error] {}", panic);
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// Everything else
|
// Everything else
|
||||||
for arg in args {
|
for arg in args {
|
||||||
match arg.as_str() {
|
match arg.as_str() {
|
||||||
"--nodes" => { info!("Printing node list..."); print_disk_file(File::Node); }
|
"--state" => { info!("Printing state..."); print_disk_file(&app.state_path); }
|
||||||
"--state" => { info!("Printing state..."); print_disk_file(File::State); }
|
"--nodes" => { info!("Printing node list..."); print_disk_file(&app.node_path); }
|
||||||
"--reset-state" => if let Ok(()) = reset_state() { exit(0) } else { exit(1) },
|
"--reset-state" => if let Ok(()) = reset_state(&app.state_path) { exit(0) } else { exit(1) },
|
||||||
"--reset-nodes" => if let Ok(()) = reset_nodes() { exit(0) } else { exit(1) },
|
"--reset-nodes" => if let Ok(()) = reset_nodes(&app.node_path) { exit(0) } else { exit(1) },
|
||||||
"--reset-all" => reset(),
|
"--reset-all" => reset(&app.os_data_path, &app.state_path, &app.node_path),
|
||||||
"--no-startup" => app.no_startup = true,
|
"--no-startup" => app.no_startup = true,
|
||||||
_ => { eprintln!("[Gupax error] Invalid option: [{}]\nFor help, use: [--help]", arg); exit(1); },
|
_ => { eprintln!("[Gupax error] Invalid option: [{}]\nFor help, use: [--help]", arg); exit(1); },
|
||||||
}
|
}
|
||||||
|
@ -541,7 +583,7 @@ fn parse_args(mut app: App) -> App {
|
||||||
pub fn get_exe() -> Result<String, std::io::Error> {
|
pub fn get_exe() -> Result<String, std::io::Error> {
|
||||||
match std::env::current_exe() {
|
match std::env::current_exe() {
|
||||||
Ok(path) => { Ok(path.display().to_string()) },
|
Ok(path) => { Ok(path.display().to_string()) },
|
||||||
Err(err) => { error!("Couldn't get exe basepath PATH"); return Err(err) },
|
Err(err) => { error!("Couldn't get absolute Gupax PATH"); return Err(err) },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -572,11 +614,7 @@ pub fn clean_dir() -> Result<(), anyhow::Error> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Print disk files to console
|
// Print disk files to console
|
||||||
fn print_disk_file(file: File) {
|
fn print_disk_file(path: &PathBuf) {
|
||||||
let path = match get_file_path(file) {
|
|
||||||
Ok(path) => path,
|
|
||||||
Err(e) => { error!("{}", e); exit(1); },
|
|
||||||
};
|
|
||||||
match std::fs::read_to_string(&path) {
|
match std::fs::read_to_string(&path) {
|
||||||
Ok(string) => { print!("{}", string); exit(0); },
|
Ok(string) => { print!("{}", string); exit(0); },
|
||||||
Err(e) => { error!("{}", e); exit(1); },
|
Err(e) => { error!("{}", e); exit(1); },
|
||||||
|
@ -652,7 +690,7 @@ fn main() {
|
||||||
impl eframe::App for App {
|
impl eframe::App for App {
|
||||||
fn on_close_event(&mut self) -> bool {
|
fn on_close_event(&mut self) -> bool {
|
||||||
if self.state.gupax.ask_before_quit {
|
if self.state.gupax.ask_before_quit {
|
||||||
self.error_state.set(true, "", ErrorFerris::Oops, ErrorButtons::StayQuit);
|
self.error_state.set("", ErrorFerris::Oops, ErrorButtons::StayQuit);
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
true
|
true
|
||||||
|
@ -749,36 +787,36 @@ impl eframe::App for App {
|
||||||
// [Yes/No] buttons
|
// [Yes/No] buttons
|
||||||
ResetState => {
|
ResetState => {
|
||||||
if ui.add_sized([width, height/2.0], egui::Button::new("Yes")).clicked() {
|
if ui.add_sized([width, height/2.0], egui::Button::new("Yes")).clicked() {
|
||||||
match reset_state() {
|
match reset_state(&self.state_path) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
match State::get() {
|
match State::get(&self.state_path) {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
self.state = s;
|
self.state = s;
|
||||||
self.og = Arc::new(Mutex::new(self.state.clone()));
|
self.og = Arc::new(Mutex::new(self.state.clone()));
|
||||||
self.error_state.set(true, "State read OK", ErrorFerris::Happy, ErrorButtons::Okay);
|
self.error_state.set("State read OK", ErrorFerris::Happy, ErrorButtons::Okay);
|
||||||
},
|
},
|
||||||
Err(e) => self.error_state.set(true, format!("State read fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
Err(e) => self.error_state.set(format!("State read fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(e) => self.error_state.set(true, format!("State reset fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
Err(e) => self.error_state.set(format!("State reset fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if esc || ui.add_sized([width, height/2.0], egui::Button::new("No")).clicked() { self.error_state = ErrorState::new() }
|
if esc || ui.add_sized([width, height/2.0], egui::Button::new("No")).clicked() { self.error_state = ErrorState::new() }
|
||||||
},
|
},
|
||||||
ResetNode => {
|
ResetNode => {
|
||||||
if ui.add_sized([width, height/2.0], egui::Button::new("Yes")).clicked() {
|
if ui.add_sized([width, height/2.0], egui::Button::new("Yes")).clicked() {
|
||||||
match reset_nodes() {
|
match reset_nodes(&self.node_path) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
match Node::get() {
|
match Node::get(&self.node_path) {
|
||||||
Ok(s) => {
|
Ok(s) => {
|
||||||
self.node_vec = s;
|
self.node_vec = s;
|
||||||
self.og_node_vec = self.node_vec.clone();
|
self.og_node_vec = self.node_vec.clone();
|
||||||
self.error_state.set(true, "Node read OK", ErrorFerris::Happy, ErrorButtons::Okay);
|
self.error_state.set("Node read OK", ErrorFerris::Happy, ErrorButtons::Okay);
|
||||||
},
|
},
|
||||||
Err(e) => self.error_state.set(true, format!("Node read fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
Err(e) => self.error_state.set(format!("Node read fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Err(e) => self.error_state.set(true, format!("Node reset fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
Err(e) => self.error_state.set(format!("Node reset fail: {}", e), ErrorFerris::Panic, ErrorButtons::Quit),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if esc || ui.add_sized([width, height/2.0], egui::Button::new("No")).clicked() { self.error_state = ErrorState::new() }
|
if esc || ui.add_sized([width, height/2.0], egui::Button::new("No")).clicked() { self.error_state = ErrorState::new() }
|
||||||
|
@ -867,7 +905,7 @@ impl eframe::App for App {
|
||||||
self.node_vec = self.og_node_vec.clone();
|
self.node_vec = self.og_node_vec.clone();
|
||||||
}
|
}
|
||||||
if ui.add_sized([width, height], egui::Button::new("Save")).on_hover_text("Save changes").clicked() {
|
if ui.add_sized([width, height], egui::Button::new("Save")).on_hover_text("Save changes").clicked() {
|
||||||
match self.state.save() {
|
match State::save(&mut self.state, &self.state_path) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
let mut og = self.og.lock().unwrap();
|
let mut og = self.og.lock().unwrap();
|
||||||
og.gupax = self.state.gupax.clone();
|
og.gupax = self.state.gupax.clone();
|
||||||
|
@ -875,12 +913,12 @@ impl eframe::App for App {
|
||||||
og.xmrig = self.state.xmrig.clone();
|
og.xmrig = self.state.xmrig.clone();
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
self.error_state.set(true, format!("State file: {}", e), ErrorFerris::Error, ErrorButtons::Okay);
|
self.error_state.set(format!("State file: {}", e), ErrorFerris::Error, ErrorButtons::Okay);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
match Node::save(&self.og_node_vec) {
|
match Node::save(&self.og_node_vec, &self.node_path) {
|
||||||
Ok(_) => self.og_node_vec = self.node_vec.clone(),
|
Ok(_) => self.og_node_vec = self.node_vec.clone(),
|
||||||
Err(e) => self.error_state.set(true, format!("Node list: {}", e), ErrorFerris::Error, ErrorButtons::Okay),
|
Err(e) => self.error_state.set(format!("Node list: {}", e), ErrorFerris::Error, ErrorButtons::Okay),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -979,7 +1017,7 @@ impl eframe::App for App {
|
||||||
Status::show(self, self.width, self.height, ctx, ui);
|
Status::show(self, self.width, self.height, ctx, ui);
|
||||||
}
|
}
|
||||||
Tab::Gupax => {
|
Tab::Gupax => {
|
||||||
Gupax::show(&mut self.state.gupax, &self.og, &self.state.version, &self.update, &self.file_window, self.width, self.height, ctx, ui);
|
Gupax::show(&mut self.state.gupax, &self.og, &self.state.version, &self.update, &self.file_window, &self.state_path, self.width, self.height, ctx, ui);
|
||||||
}
|
}
|
||||||
Tab::P2pool => {
|
Tab::P2pool => {
|
||||||
P2pool::show(&mut self.state.p2pool, &mut self.node_vec, &self.og, self.p2pool, &self.ping, &self.regex, self.width, self.height, ctx, ui);
|
P2pool::show(&mut self.state.p2pool, &mut self.node_vec, &self.og, self.p2pool, &self.ping, &self.regex, self.width, self.height, ctx, ui);
|
||||||
|
|
Loading…
Reference in a new issue