summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorClementTsang <clementjhtsang@gmail.com>2020-01-08 22:36:36 -0500
committerClementTsang <clementjhtsang@gmail.com>2020-01-08 22:36:36 -0500
commitc171cd0e0b8d37c71a666e838b52868feaae6e62 (patch)
treeae83f26e56188d097e96bed1c811787f2bef7154
parent6cf8f0d98f750b6fb4c406de6ca0e37305692988 (diff)
Implemented dd for grouped processes.
-rw-r--r--src/app.rs49
-rw-r--r--src/app/data_collection/processes.rs20
-rw-r--r--src/canvas.rs45
-rw-r--r--src/data_conversion.rs18
-rw-r--r--src/main.rs4
5 files changed, 80 insertions, 56 deletions
diff --git a/src/app.rs b/src/app.rs
index ebb56e58..8687d587 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -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()),
}
})