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

View file

@ -15,8 +15,10 @@
//
use std::{
iter::zip,
path::PathBuf,
sync::{Arc, Mutex},
thread::{self, JoinHandle},
thread::{self, sleep, JoinHandle},
time::Duration,
};
use color_eyre::Result;
@ -32,17 +34,12 @@ use tracing::{debug, info};
use crate::{
action::Action,
components::{
footer::Footer,
fps::FpsCounter,
left::Left,
popup::{Popup, Type},
right::Right,
title::Title,
Component,
footer::Footer, fps::FpsCounter, left::Left, popup, right::Right, title::Title, Component,
},
config::Config,
system::{
disk::{get_disks, Disk, PartitionTableType},
diskpart::refresh_disk_info,
drivers::{self, Driver},
},
tui::{Event, Tui},
@ -101,7 +98,7 @@ impl App {
Box::new(Left::new()),
Box::new(Right::new()),
Box::new(Footer::new()),
Box::new(Popup::new()),
Box::new(popup::Popup::new()),
],
config: Config::new()?,
frame_rate,
@ -278,6 +275,21 @@ impl App {
Action::Suspend => self.should_suspend = true,
Action::Resume => self.should_suspend = false,
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 => {
self.action_tx.send(Action::SetMode(Mode::InstallDrivers))?
}
@ -297,6 +309,7 @@ impl App {
}
Action::NextScreen => {
if let Some(mode) = self.next_mode() {
self.action_tx.send(Action::DismissPopup)?;
self.action_tx.send(Action::SetMode(mode))?;
}
}
@ -331,15 +344,48 @@ impl App {
self.action_tx
.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 => {
self.action_tx.send(Action::DisplayPopup(
Type::Success,
popup::Type::Success,
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() {
@ -432,9 +478,41 @@ fn get_chunks(r: Rect) -> Vec<Rect> {
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<()> {
thread::spawn(move || {
let mut disks = disk_list_arc.lock().unwrap();
*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[1] = None;
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) => {
self.list_table_types

View file

@ -40,6 +40,8 @@ pub struct AppConfig {
#[derive(Clone, Debug, Default, Deserialize)]
pub struct Config {
#[serde(default)]
pub clone_app_path: PathBuf,
#[serde(default, flatten)]
pub config: AppConfig,
#[serde(default)]
@ -67,7 +69,11 @@ impl Config {
let config_dir = get_config_dir();
let mut builder = config::Config::builder()
.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 = [
("config.json5", config::FileFormat::Json5),