Add Command and Diskpart actions

This commit is contained in:
2Shirt 2024-11-09 20:05:21 -08:00
parent 1f8c99d6ba
commit da6c7f16fb
Signed by: 2Shirt
GPG key ID: 152FAC923B0E132C
4 changed files with 99 additions and 16 deletions

View file

@ -14,6 +14,7 @@
// along with Deja-vu. If not, see <https://www.gnu.org/licenses/>. // along with Deja-vu. If not, see <https://www.gnu.org/licenses/>.
// //
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use strum::Display; use strum::Display;
use crate::{ use crate::{
@ -28,14 +29,15 @@ use crate::{
#[derive(Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)] #[derive(Debug, Clone, PartialEq, Eq, Display, Serialize, Deserialize)]
pub enum Action { pub enum Action {
// App // App
Command(String, String, Vec<String>), // (label, command, args) Command(String, PathBuf, Vec<String>), // (label, command, args)
Diskpart(String, String), // (label, script_as_string) Diskpart(String, String), // (label, script_as_string)
InstallDriver, InstallDriver,
Process, Process,
ScanDisks, ScanDisks,
Select(Option<usize>, Option<usize>), // indicies for (source, dest) or (boot, os) Select(Option<usize>, Option<usize>), // indicies for (source, dest) or (boot, os)
SelectDriver(Driver), SelectDriver(Driver),
SelectTableType(PartitionTableType), SelectTableType(PartitionTableType),
UpdateDestDisk,
UpdateDiskList(Vec<Disk>), UpdateDiskList(Vec<Disk>),
// Screens // Screens
DismissPopup, DismissPopup,

View file

@ -15,8 +15,10 @@
// //
use std::{ use std::{
iter::zip, iter::zip,
path::PathBuf,
sync::{Arc, Mutex}, sync::{Arc, Mutex},
thread::{self, JoinHandle}, thread::{self, sleep, JoinHandle},
time::Duration,
}; };
use color_eyre::Result; use color_eyre::Result;
@ -32,17 +34,12 @@ use tracing::{debug, info};
use crate::{ use crate::{
action::Action, action::Action,
components::{ components::{
footer::Footer, footer::Footer, fps::FpsCounter, left::Left, popup, right::Right, title::Title, Component,
fps::FpsCounter,
left::Left,
popup::{Popup, Type},
right::Right,
title::Title,
Component,
}, },
config::Config, config::Config,
system::{ system::{
disk::{get_disks, Disk, PartitionTableType}, disk::{get_disks, Disk, PartitionTableType},
diskpart::refresh_disk_info,
drivers::{self, Driver}, drivers::{self, Driver},
}, },
tui::{Event, Tui}, tui::{Event, Tui},
@ -101,7 +98,7 @@ impl App {
Box::new(Left::new()), Box::new(Left::new()),
Box::new(Right::new()), Box::new(Right::new()),
Box::new(Footer::new()), Box::new(Footer::new()),
Box::new(Popup::new()), Box::new(popup::Popup::new()),
], ],
config: Config::new()?, config: Config::new()?,
frame_rate, frame_rate,
@ -278,6 +275,21 @@ impl App {
Action::Suspend => self.should_suspend = true, Action::Suspend => self.should_suspend = true,
Action::Resume => self.should_suspend = false, Action::Resume => self.should_suspend = false,
Action::ClearScreen => tui.terminal.clear()?, Action::ClearScreen => tui.terminal.clear()?,
Action::Command(ref label, ref cmd_path, ref cmd_args) => {
self.action_tx.send(Action::DisplayPopup(
popup::Type::Info,
String::from(&label.to_owned()),
))?;
self.task_handles
.push(lazy_command(&cmd_path, cmd_args.clone()))
}
Action::Diskpart(ref label, ref script) => {
self.action_tx.send(Action::DisplayPopup(
popup::Type::Info,
String::from(&label.to_owned()),
))?;
self.task_handles.push(lazy_diskpart(&script.to_owned()))
}
Action::InstallDriver => { Action::InstallDriver => {
self.action_tx.send(Action::SetMode(Mode::InstallDrivers))? self.action_tx.send(Action::SetMode(Mode::InstallDrivers))?
} }
@ -297,6 +309,7 @@ impl App {
} }
Action::NextScreen => { Action::NextScreen => {
if let Some(mode) = self.next_mode() { if let Some(mode) = self.next_mode() {
self.action_tx.send(Action::DismissPopup)?;
self.action_tx.send(Action::SetMode(mode))?; self.action_tx.send(Action::SetMode(mode))?;
} }
} }
@ -331,15 +344,48 @@ impl App {
self.action_tx self.action_tx
.send(Action::UpdateDiskList(disk_list.clone()))?; .send(Action::UpdateDiskList(disk_list.clone()))?;
} }
Mode::PreClone => {
// TODO: FIXME
self.action_tx.send(Action::Diskpart(
String::from("Formatting destination disk"),
String::from("TODO: FIXME"),
))?;
}
Mode::Clone => {
self.action_tx.send(Action::UpdateDestDisk)?;
self.action_tx.send(Action::Command(
String::from("Running Clone Tool"),
self.config.clone_app_path.clone(),
Vec::new(),
))?;
}
Mode::PostClone => {
// TODO: FIXME
self.action_tx.send(Action::Diskpart(
String::from("Creating boot files"),
String::from("TODO: FIXME"),
))?;
}
Mode::Done => { Mode::Done => {
self.action_tx.send(Action::DisplayPopup( self.action_tx.send(Action::DisplayPopup(
Type::Success, popup::Type::Success,
String::from("COMPLETE\n\n\nThank you for using this tool!"), String::from("COMPLETE\n\n\nThank you for using this tool!"),
))?; ))?;
} }
_ => {} _ => {}
} }
} }
Action::UpdateDestDisk => {
let disk_list_arc = Arc::clone(&self.disk_list);
if let Some(dest_id_index) = self.disk_id_dest {
self.action_tx.send(Action::DisplayPopup(
popup::Type::Info,
String::from("Updating info for destination disk"),
))?;
self.task_handles
.push(lazy_update_dest_disk(disk_list_arc, dest_id_index));
}
}
_ => {} _ => {}
} }
for component in self.components.iter_mut() { for component in self.components.iter_mut() {
@ -432,9 +478,41 @@ fn get_chunks(r: Rect) -> Vec<Rect> {
chunks chunks
} }
fn lazy_command(cmd_path: &PathBuf, cmd_args: Vec<String>) -> JoinHandle<()> {
if cfg!(windows) {
// TODO: FIXME
thread::spawn(|| sleep(Duration::from_secs(1)))
} else {
thread::spawn(|| sleep(Duration::from_secs(1)))
}
}
fn lazy_diskpart(script: &str) -> JoinHandle<()> {
if cfg!(windows) {
// TODO: FIXME
thread::spawn(|| sleep(Duration::from_secs(1)))
} else {
thread::spawn(|| sleep(Duration::from_secs(1)))
}
}
fn lazy_get_disks(disk_list_arc: Arc<Mutex<Vec<Disk>>>) -> JoinHandle<()> { fn lazy_get_disks(disk_list_arc: Arc<Mutex<Vec<Disk>>>) -> JoinHandle<()> {
thread::spawn(move || { thread::spawn(move || {
let mut disks = disk_list_arc.lock().unwrap(); let mut disks = disk_list_arc.lock().unwrap();
*disks = get_disks(); *disks = get_disks();
}) })
} }
fn lazy_update_dest_disk(
disk_list_arc: Arc<Mutex<Vec<Disk>>>,
dest_index: usize,
) -> JoinHandle<()> {
if cfg!(windows) {
thread::spawn(move || {
let mut disks = disk_list_arc.lock().unwrap();
refresh_disk_info(&mut disks[dest_index]);
})
} else {
thread::spawn(|| sleep(Duration::from_secs(2)))
}
}

View file

@ -202,9 +202,6 @@ impl Component for Left {
self.selections[0] = None; self.selections[0] = None;
self.selections[1] = None; self.selections[1] = None;
self.title_text = String::from("Select Source and Destination Disks"); self.title_text = String::from("Select Source and Destination Disks");
if let Some(command_tx) = self.command_tx.clone() {
command_tx.send(Action::DismissPopup)?;
}
} }
(_, Mode::SelectTableType) => { (_, Mode::SelectTableType) => {
self.list_table_types self.list_table_types

View file

@ -40,6 +40,8 @@ pub struct AppConfig {
#[derive(Clone, Debug, Default, Deserialize)] #[derive(Clone, Debug, Default, Deserialize)]
pub struct Config { pub struct Config {
#[serde(default)]
pub clone_app_path: PathBuf,
#[serde(default, flatten)] #[serde(default, flatten)]
pub config: AppConfig, pub config: AppConfig,
#[serde(default)] #[serde(default)]
@ -67,7 +69,11 @@ impl Config {
let config_dir = get_config_dir(); let config_dir = get_config_dir();
let mut builder = config::Config::builder() let mut builder = config::Config::builder()
.set_default("data_dir", data_dir.to_str().unwrap())? .set_default("data_dir", data_dir.to_str().unwrap())?
.set_default("config_dir", config_dir.to_str().unwrap())?; .set_default("config_dir", config_dir.to_str().unwrap())?
.set_default(
"clone_app_path",
String::from("C:\\Program Files\\Some Clone Tool\\app.exe"),
)?;
let config_files = [ let config_files = [
("config.json5", config::FileFormat::Json5), ("config.json5", config::FileFormat::Json5),