diff options
author | ClementTsang <clementjhtsang@gmail.com> | 2020-01-08 22:36:36 -0500 |
---|---|---|
committer | ClementTsang <clementjhtsang@gmail.com> | 2020-01-08 22:36:36 -0500 |
commit | c171cd0e0b8d37c71a666e838b52868feaae6e62 (patch) | |
tree | ae83f26e56188d097e96bed1c811787f2bef7154 | |
parent | 6cf8f0d98f750b6fb4c406de6ca0e37305692988 (diff) |
Implemented dd for grouped processes.
-rw-r--r-- | src/app.rs | 49 | ||||
-rw-r--r-- | src/app/data_collection/processes.rs | 20 | ||||
-rw-r--r-- | src/canvas.rs | 45 | ||||
-rw-r--r-- | src/data_conversion.rs | 18 | ||||
-rw-r--r-- | src/main.rs | 4 |
5 files changed, 80 insertions, 56 deletions
@@ -49,7 +49,7 @@ pub struct App { pub show_help: bool, pub show_dd: bool, pub dd_err: Option<String>, - to_delete_process: Option<ConvertedProcessData>, + to_delete_process_list: Option<Vec<ConvertedProcessData>>, pub is_frozen: bool, pub left_legend: bool, pub use_current_cpu_total: bool, @@ -88,7 +88,7 @@ impl App { show_help: false, show_dd: false, dd_err: None, - to_delete_process: None, + to_delete_process_list: None, is_frozen: false, left_legend, use_current_cpu_total, @@ -102,7 +102,7 @@ impl App { self.reset_multi_tap_keys(); self.show_help = false; self.show_dd = false; - self.to_delete_process = None; + self.to_delete_process_list = None; self.dd_err = None; } @@ -122,9 +122,6 @@ impl App { self.enable_grouping = !(self.enable_grouping); } } - - // TODO: Note that we have to handle this in a way such that it will only update - // with the correct formatted vectors... that is, only update the canvas after...? } pub fn is_grouped(&self) -> bool { @@ -167,9 +164,29 @@ impl App { self.awaiting_second_char = false; self.second_char = ' '; - let current_process = &self.canvas_data.process_data - [self.currently_selected_process_position as usize]; - self.to_delete_process = Some(current_process.clone()); + let current_process = if self.is_grouped() { + let mut res: Vec<ConvertedProcessData> = Vec::new(); + for pid in &self.canvas_data.grouped_process_data + [self.currently_selected_process_position as usize] + .group + { + let result = self + .canvas_data + .process_data + .iter() + .find(|p| p.pid == *pid); + + if let Some(process) = result { + res.push((*process).clone()); + } + } + res + } else { + vec![self.canvas_data.process_data + [self.currently_selected_process_position as usize] + .clone()] + }; + self.to_delete_process_list = Some(current_process); self.show_dd = true; self.reset_multi_tap_keys(); } else { @@ -261,18 +278,18 @@ impl App { pub fn kill_highlighted_process(&mut self) -> Result<()> { // Technically unnecessary but this is a good check... if let ApplicationPosition::Process = self.current_application_position { - if self.enable_grouping { - // TODO: Enable grouping pid deletion - } else if let Some(current_selected_process) = &(self.to_delete_process) { - process_killer::kill_process_given_pid(current_selected_process.pid)?; + if let Some(current_selected_processes) = &(self.to_delete_process_list) { + for current_selected_process in current_selected_processes { + process_killer::kill_process_given_pid(current_selected_process.pid)?; + } } - self.to_delete_process = None; + self.to_delete_process_list = None; } Ok(()) } - pub fn get_current_highlighted_process(&self) -> Option<ConvertedProcessData> { - self.to_delete_process.clone() + pub fn get_current_highlighted_process_list(&self) -> Option<Vec<ConvertedProcessData>> { + self.to_delete_process_list.clone() } // For now, these are hard coded --- in the future, they shouldn't be! diff --git a/src/app/data_collection/processes.rs b/src/app/data_collection/processes.rs index 15c9bb15..8de9f4cb 100644 --- a/src/app/data_collection/processes.rs +++ b/src/app/data_collection/processes.rs @@ -24,8 +24,8 @@ pub struct ProcessData { pub cpu_usage_percent: f64, pub mem_usage_percent: Option<f64>, pub mem_usage_kb: Option<u64>, - pub command: String, - pub pid_vec: Option<Vec<u32>>, // Note that this is literally never unless we are in grouping mode. This is to save rewriting time. + pub name: String, + pub pid_vec: Option<Vec<u32>>, } fn cpu_usage_calculation( @@ -186,7 +186,7 @@ fn convert_ps( if process.trim().to_string().is_empty() { return Ok(ProcessData { pid: 0, - command: "".to_string(), + name: "".to_string(), mem_usage_percent: None, mem_usage_kb: None, cpu_usage_percent: 0_f64, @@ -199,7 +199,7 @@ fn convert_ps( .to_string() .parse::<u32>() .unwrap_or(0); - let command = (&process[11..61]).trim().to_string(); + let name = (&process[11..61]).trim().to_string(); let mem_usage_percent = Some( (&process[62..]) .trim() @@ -210,7 +210,7 @@ fn convert_ps( Ok(ProcessData { pid, - command, + name, mem_usage_percent, mem_usage_kb: None, cpu_usage_percent: linux_cpu_usage( @@ -252,7 +252,7 @@ pub fn get_sorted_processes_list( prev_pid_stats, use_current_cpu_total, ) { - if !process_object.command.is_empty() { + if !process_object.name.is_empty() { process_vector.push(process_object); } } @@ -264,7 +264,7 @@ pub fn get_sorted_processes_list( } else { let process_hashmap = sys.get_process_list(); for process_val in process_hashmap.values() { - let command_name = if process_val.name().is_empty() { + let name = if process_val.name().is_empty() { let process_cmd = process_val.cmd(); if process_cmd.len() > 1 { process_cmd[0].clone() @@ -287,7 +287,7 @@ pub fn get_sorted_processes_list( process_vector.push(ProcessData { pid: process_val.pid() as u32, - command: command_name, + name, mem_usage_percent: None, mem_usage_kb: Some(process_val.memory()), cpu_usage_percent: f64::from(process_val.cpu_usage()), @@ -303,7 +303,7 @@ pub fn sort_processes( process_vector: &mut Vec<ProcessData>, sorting_method: &ProcessSorting, reverse_order: bool, ) { // Always sort alphabetically first! - process_vector.sort_by(|a, b| get_ordering(&a.command, &b.command, false)); + process_vector.sort_by(|a, b| get_ordering(&a.name, &b.name, false)); match sorting_method { ProcessSorting::CPU => { @@ -320,7 +320,7 @@ pub fn sort_processes( process_vector.sort_by(|a, b| get_ordering(a.pid, b.pid, reverse_order)); } ProcessSorting::NAME => { - process_vector.sort_by(|a, b| get_ordering(&a.command, &b.command, reverse_order)) + process_vector.sort_by(|a, b| get_ordering(&a.name, &b.name, reverse_order)) } } } diff --git a/src/canvas.rs b/src/canvas.rs index 6df1a8e6..90ab09b9 100644 --- a/src/canvas.rs +++ b/src/canvas.rs @@ -193,26 +193,37 @@ pub fn draw_data<B: backend::Backend>( .alignment(Alignment::Center) .wrap(true) .render(&mut f, middle_dialog_chunk[1]); - } else if let Some(process) = app_state.get_current_highlighted_process() { - let dd_text = [ - Text::raw(format!( - "\nAre you sure you want to kill process {} with PID {}?", - process.name, process.pid - )), + } else if let Some(process_list) = app_state.get_current_highlighted_process_list() { + if let Some(process) = process_list.first() { + let dd_text = [ + if app_state.is_grouped() { + Text::raw(format!( + "\nAre you sure you want to kill {} process(es) with name {}?", + process_list.len(), process.name + )) + } else { + Text::raw(format!( + "\nAre you sure you want to kill process {} with PID {}?", + process.name, process.pid + )) + }, Text::raw("\n\nPress ENTER to proceed, ESC to exit."), Text::raw("\nNote that if bottom is frozen, it must be unfrozen for changes to be shown."), ]; - Paragraph::new(dd_text.iter()) - .block( - Block::default() - .title("Kill Process Confirmation (Press Esc to close)") - .borders(Borders::ALL), - ) - .style(Style::default().fg(Color::Gray)) - .alignment(Alignment::Center) - .wrap(true) - .render(&mut f, middle_dialog_chunk[1]); + Paragraph::new(dd_text.iter()) + .block( + Block::default() + .title("Kill Process Confirmation (Press Esc to close)") + .borders(Borders::ALL), + ) + .style(Style::default().fg(Color::Gray)) + .alignment(Alignment::Center) + .wrap(true) + .render(&mut f, middle_dialog_chunk[1]); + } else { + app_state.show_dd = false; + } } else { // This is a bit nasty, but it works well... I guess. app_state.show_dd = false; @@ -774,7 +785,7 @@ fn draw_processes_table<B: backend::Backend>( let process_rows = sliced_vec.iter().map(|process| { let stringified_process_vec: Vec<String> = vec![ if app_state.is_grouped() { - process.group_count.to_string() + process.group.len().to_string() } else { process.pid.to_string() }, diff --git a/src/data_conversion.rs b/src/data_conversion.rs index fd505e80..b68d18fa 100644 --- a/src/data_conversion.rs +++ b/src/data_conversion.rs @@ -21,7 +21,7 @@ pub struct ConvertedProcessData { pub name: String, pub cpu_usage: String, pub mem_usage: String, - pub group_count: u32, + pub group: Vec<u32>, } #[derive(Clone, Default, Debug)] @@ -144,7 +144,7 @@ pub fn update_process_row( .iter() .map(|process| ConvertedProcessData { pid: process.pid, - name: process.command.to_string(), + name: process.name.to_string(), cpu_usage: format!("{:.1}%", process.cpu_usage_percent), mem_usage: format!( "{:.1}%", @@ -160,11 +160,7 @@ pub fn update_process_row( 0_f64 } ), - group_count: if let Some(pid_vec) = &process.pid_vec { - pid_vec.len() as u32 - } else { - 0 - }, + group: vec![], }) .collect::<Vec<_>>(); @@ -174,7 +170,7 @@ pub fn update_process_row( .iter() .map(|process| ConvertedProcessData { pid: process.pid, - name: process.command.to_string(), + name: process.name.to_string(), cpu_usage: format!("{:.1}%", process.cpu_usage_percent), mem_usage: format!( "{:.1}%", @@ -190,10 +186,10 @@ pub fn update_process_row( 0_f64 } ), - group_count: if let Some(pid_vec) = &process.pid_vec { - pid_vec.len() as u32 + group: if let Some(pid_vec) = &process.pid_vec { + pid_vec.to_vec() } else { - 0 + vec![] }, }) .collect::<Vec<_>>(); diff --git a/src/main.rs b/src/main.rs index e04760af..8cdc4e50 100644 --- a/src/main.rs +++ b/src/main.rs @@ -326,7 +326,7 @@ fn handle_process_sorting(app: &mut app::App) { for process in &app.data.list_of_processes { let entry_val = process_map - .entry(process.command.clone()) + .entry(process.name.clone()) .or_insert((0.0, None, None, vec![])); if let Some(mem_usage) = process.mem_usage_percent { entry_val.0 += process.cpu_usage_percent; @@ -353,7 +353,7 @@ fn handle_process_sorting(app: &mut app::App) { cpu_usage_percent: data.0, mem_usage_percent: data.1, mem_usage_kb: data.2, - command: name.clone(), + name: name.clone(), pid_vec: Some(data.3.clone()), } }) |