Implemented dd for grouped processes.
This commit is contained in:
parent
6cf8f0d98f
commit
c171cd0e0b
49
src/app.rs
49
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!
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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()
|
||||
},
|
||||
|
|
|
@ -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<_>>();
|
||||
|
|
|
@ -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()),
|
||||
}
|
||||
})
|
||||
|
|
Loading…
Reference in New Issue