From 6430146fe5f8b3133377e80dd1589406905f6d62 Mon Sep 17 00:00:00 2001
From: hinto-janaiyo <hinto.janaiyo@protonmail.com>
Date: Mon, 2 Jan 2023 13:32:55 -0500
Subject: [PATCH] Status Submenu: add [--payouts] & [--reset-payouts]

Prints and resets the GupaxP2poolApi [p2pool] files.
---
 src/constants.rs | 22 +++++++++--------
 src/disk.rs      | 14 +++++++++--
 src/main.rs      | 63 +++++++++++++++++++++++++++++++++++++++---------
 3 files changed, 76 insertions(+), 23 deletions(-)

diff --git a/src/constants.rs b/src/constants.rs
index adf66c0..91e4056 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -331,16 +331,18 @@ pub const XMRIG_PATH_EMPTY:     &str = "XMRig PATH is empty! To fix: goto the [G
 pub const ARG_HELP: &str =
 r#"USAGE: ./gupax [--flag]
 
-    --help         Print this help message
-    --version      Print version and build info
-    --state        Print Gupax state
-    --nodes        Print the manual node list
-    --no-startup   Disable all auto-startup settings for this instance
-    --reset-state  Reset all Gupax state (your settings)
-    --reset-nodes  Reset the manual node list in the [P2Pool] tab
-    --reset-pools  Reset the manual pool list in the [XMRig] tab
-    --reset-all    Reset the state, the manual node list, and the manual pool list
-    --ferris       Print an extremely cute crab
+    --help            Print this help message
+    --version         Print version and build info
+    --state           Print Gupax state
+    --nodes           Print the manual node list
+    --payouts         Print the P2Pool payout log, payout count, and total XMR mined
+    --no-startup      Disable all auto-startup settings for this instance (auto-update, auto-ping, etc)
+    --reset-state     Reset all Gupax state (your settings)
+    --reset-nodes     Reset the manual node list in the [P2Pool] tab
+    --reset-pools     Reset the manual pool list in the [XMRig] tab
+    --reset-payouts   Reset the permanent P2Pool stats that appear in the [Status] tab
+    --reset-all       Reset the state, manual node list, manual pool list, and P2Pool stats
+    --ferris          Print an extremely cute crab
 
 To view more detailed console debug information, start Gupax with
 the environment variable [RUST_LOG] set to a log level like so:
diff --git a/src/disk.rs b/src/disk.rs
index 3ca3d98..5dd9f0f 100644
--- a/src/disk.rs
+++ b/src/disk.rs
@@ -172,8 +172,8 @@ pub fn create_gupax_dir(path: &PathBuf) -> Result<(), TomlError> {
 pub fn create_gupax_p2pool_dir(path: &PathBuf) -> Result<(), TomlError> {
 	// Create Gupax directory
 	match fs::create_dir_all(path) {
-		Ok(_) => { info!("OS | Create Gupax-P2Pool API path ... OK"); Ok(()) },
-		Err(e) => { error!("OS | Create Gupax-P2Pool API path ... FAIL ... {}", e); Err(TomlError::Io(e)) },
+		Ok(_) => { info!("OS | Create Gupax-P2Pool API path [{}] ... OK", path.display()); Ok(()) },
+		Err(e) => { error!("OS | Create Gupax-P2Pool API path [{}] ... FAIL ... {}", path.display(), e); Err(TomlError::Io(e)) },
 	}
 }
 
@@ -676,6 +676,16 @@ impl GupaxP2poolApi {
 		Ok(())
 	}
 
+	// Completely delete the [p2pool] folder and create defaults.
+	pub fn create_new(path: &PathBuf) -> Result<(), TomlError> {
+		info!("GupaxP2poolApi | Deleting old folder at [{}]...", path.display());
+		std::fs::remove_dir_all(&path)?;
+		info!("GupaxP2poolApi | Creating new default folder at [{}]...", path.display());
+		create_gupax_p2pool_dir(&path)?;
+		Self::create_all_files(&path)?;
+		Ok(())
+	}
+
 	//---------------------------------------------------------------------------------------------------- Live, functions that actually update/write live stats
 	pub fn update_log_rev(&mut self) {
 		let mut log_rev = String::with_capacity(self.log.len());
diff --git a/src/main.rs b/src/main.rs
index 1127de9..82a2a99 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -276,6 +276,9 @@ impl App {
 		app.node_path.push(NODE_TOML);
 		app.pool_path = app.os_data_path.clone();
 		app.pool_path.push(POOL_TOML);
+		// Set GupaxP2poolApi path
+		app.gupax_p2pool_api_path = crate::disk::get_gupax_p2pool_path(&app.os_data_path);
+		lock!(app.gupax_p2pool_api).fill_paths(&app.gupax_p2pool_api_path);
 
 		// Apply arg state
 		// It's not safe to [--reset] if any of the previous variables
@@ -348,9 +351,7 @@ impl App {
 
 		//----------------------------------------------------------------------------------------------------
 		// Read [GupaxP2poolApi] disk files
-		app.gupax_p2pool_api_path = crate::disk::get_gupax_p2pool_path(&app.os_data_path);
 		let mut gupax_p2pool_api = lock!(app.gupax_p2pool_api);
-		gupax_p2pool_api.fill_paths(&app.gupax_p2pool_api_path);
 		match GupaxP2poolApi::create_all_files(&app.gupax_p2pool_api_path) {
 			Ok(_) => debug!("App Init | Creating Gupax-P2Pool API files ... OK"),
 			Err(err) => {
@@ -835,7 +836,14 @@ fn reset_pools(path: &PathBuf) -> Result<(), TomlError> {
 	}
 }
 
-fn reset(path: &PathBuf, state: &PathBuf, node: &PathBuf, pool: &PathBuf) {
+fn reset_gupax_p2pool_api(path: &PathBuf) -> Result<(), TomlError> {
+	match GupaxP2poolApi::create_new(path) {
+		Ok(_)  => { info!("Resetting GupaxP2poolApi ... OK"); Ok(()) },
+		Err(e) => { error!("Resetting GupaxP2poolApi folder ... FAIL ... {}", e); Err(e) },
+	}
+}
+
+fn reset(path: &PathBuf, state: &PathBuf, node: &PathBuf, pool: &PathBuf, gupax_p2pool_api: &PathBuf) {
 	let mut code = 0;
 	// Attempt to remove directory first
 	match std::fs::remove_dir_all(path) {
@@ -859,6 +867,10 @@ fn reset(path: &PathBuf, state: &PathBuf, node: &PathBuf, pool: &PathBuf) {
 		Ok(_) => (),
 		Err(_) => code = 1,
 	}
+	match reset_gupax_p2pool_api(gupax_p2pool_api) {
+		Ok(_) => (),
+		Err(_) => code = 1,
+	}
 	match code {
 		0 => println!("\nGupax reset ... OK"),
 		_ => eprintln!("\nGupax reset ... FAIL"),
@@ -893,14 +905,16 @@ fn parse_args<S: Into<String>>(mut app: App, panic: S) -> App {
 	// Everything else
 	for arg in args {
 		match arg.as_str() {
-			"--state"       => { info!("Printing state..."); print_disk_file(&app.state_path); }
-			"--nodes"       => { info!("Printing node list..."); print_disk_file(&app.node_path); }
-			"--reset-state" => if let Ok(()) = reset_state(&app.state_path) { println!("\nState reset ... OK"); exit(0); } else { eprintln!("\nState reset ... FAIL"); exit(1) },
-			"--reset-nodes" => if let Ok(()) = reset_nodes(&app.node_path) { println!("\nNode reset ... OK"); exit(0) } else { eprintln!("\nNode reset ... FAIL"); exit(1) },
-			"--reset-pools" => if let Ok(()) = reset_pools(&app.pool_path) { println!("\nPool reset ... OK"); exit(0) } else { eprintln!("\nPool reset ... FAIL"); exit(1) },
-			"--reset-all"   => reset(&app.os_data_path, &app.state_path, &app.node_path, &app.pool_path),
-			"--no-startup"  => app.no_startup = true,
-			_               => { eprintln!("\n[Gupax error] Invalid option: [{}]\nFor help, use: [--help]", arg); exit(1); },
+			"--state"         => { info!("Printing state..."); print_disk_file(&app.state_path); },
+			"--nodes"         => { info!("Printing node list..."); print_disk_file(&app.node_path); },
+			"--payouts"       => { info!("Printing payouts...\n"); print_gupax_p2pool_api(&app.gupax_p2pool_api); },
+			"--reset-state"   => if let Ok(()) = reset_state(&app.state_path) { println!("\nState reset ... OK"); exit(0); } else { eprintln!("\nState reset ... FAIL"); exit(1) },
+			"--reset-nodes"   => if let Ok(()) = reset_nodes(&app.node_path) { println!("\nNode reset ... OK"); exit(0) } else { eprintln!("\nNode reset ... FAIL"); exit(1) },
+			"--reset-pools"   => if let Ok(()) = reset_pools(&app.pool_path) { println!("\nPool reset ... OK"); exit(0) } else { eprintln!("\nPool reset ... FAIL"); exit(1) },
+			"--reset-payouts" => if let Ok(()) = reset_gupax_p2pool_api(&app.gupax_p2pool_api_path) { println!("\nGupaxP2poolApi reset ... OK"); exit(0) } else { eprintln!("\nGupaxP2poolApi reset ... FAIL"); exit(1) },
+			"--reset-all"     => reset(&app.os_data_path, &app.state_path, &app.node_path, &app.pool_path, &app.gupax_p2pool_api_path),
+			"--no-startup"    => app.no_startup = true,
+			_                 => { eprintln!("\n[Gupax error] Invalid option: [{}]\nFor help, use: [--help]", arg); exit(1); },
 		}
 	}
 	app
@@ -948,6 +962,33 @@ fn print_disk_file(path: &PathBuf) {
 	}
 }
 
+// Prints the GupaxP2PoolApi files.
+fn print_gupax_p2pool_api(gupax_p2pool_api: &Arc<Mutex<GupaxP2poolApi>>) {
+	let api = lock!(gupax_p2pool_api);
+	let log = match std::fs::read_to_string(&api.path_log) {
+		Ok(string) => string,
+		Err(e) => { error!("{}", e); exit(1); },
+	};
+	let payout = match std::fs::read_to_string(&api.path_payout) {
+		Ok(string) => string,
+		Err(e) => { error!("{}", e); exit(1); },
+	};
+	let xmr = match std::fs::read_to_string(&api.path_xmr) {
+		Ok(string) => string,
+		Err(e) => { error!("{}", e); exit(1); },
+	};
+	let xmr = match xmr.trim().parse::<u64>() {
+		Ok(o)  => crate::xmr::AtomicUnit::from_u64(o),
+		Err(e) => { warn!("GupaxP2poolApi | [xmr] parse error: {}", e); exit(1); }
+	};
+	println!("{}\nTotal payouts | {}\nTotal XMR     | {} ({} Atomic Units)", log, payout.trim(), xmr, xmr.to_u64());
+	exit(0);
+}
+
+// Prints the GupaxP2PoolApi [xmr] file in AtomicUnits and floating point.
+fn print_xmr_file(path: &PathBuf) {
+}
+
 //---------------------------------------------------------------------------------------------------- Main [App] frame
 fn main() {
 	let now = Instant::now();