From b3cf6b578a15d9783c61242abd525eded18ee577 Mon Sep 17 00:00:00 2001 From: epi Date: Sat, 15 Jun 2024 11:10:36 -0400 Subject: [PATCH] added time estimate to SMM --- src/event_handlers/command.rs | 4 ++++ src/event_handlers/statistics.rs | 3 +++ src/progress.rs | 4 +--- src/scan_manager/menu.rs | 17 +++++++++++++++-- src/scan_manager/scan_container.rs | 8 ++++++++ 5 files changed, 31 insertions(+), 5 deletions(-) diff --git a/src/event_handlers/command.rs b/src/event_handlers/command.rs index b62a0780..6d318864 100644 --- a/src/event_handlers/command.rs +++ b/src/event_handlers/command.rs @@ -1,4 +1,5 @@ use std::sync::Arc; +use std::time::Duration; use reqwest::StatusCode; use tokio::sync::oneshot::Sender; @@ -88,4 +89,7 @@ pub enum Command { /// inform the Stats object about which targets are being scanned UpdateTargets(Vec), + + /// query the Stats handler about the position of the overall progress bar + QueryOverallBarEta(Sender), } diff --git a/src/event_handlers/statistics.rs b/src/event_handlers/statistics.rs index 09e34854..9c374086 100644 --- a/src/event_handlers/statistics.rs +++ b/src/event_handlers/statistics.rs @@ -125,6 +125,9 @@ impl StatsHandler { Command::Sync(sender) => { sender.send(true).unwrap_or_default(); } + Command::QueryOverallBarEta(sender) => { + sender.send(self.bar.eta()).unwrap_or_default(); + } Command::UpdateTargets(targets) => { self.stats.update_targets(targets); } diff --git a/src/progress.rs b/src/progress.rs index b32dc981..42e235ad 100644 --- a/src/progress.rs +++ b/src/progress.rs @@ -1,6 +1,4 @@ -use std::time::Duration; - -use indicatif::{HumanDuration, MultiProgress, ProgressBar, ProgressDrawTarget, ProgressStyle}; +use indicatif::{MultiProgress, ProgressBar, ProgressDrawTarget, ProgressStyle}; use lazy_static::lazy_static; lazy_static! { diff --git a/src/scan_manager/menu.rs b/src/scan_manager/menu.rs index 04751c42..73095ccc 100644 --- a/src/scan_manager/menu.rs +++ b/src/scan_manager/menu.rs @@ -1,8 +1,10 @@ +use std::time::Duration; + use crate::filters::filter_lookup; use crate::progress::PROGRESS_BAR; use crate::traits::FeroxFilter; use console::{measure_text_width, pad_str, style, Alignment, Term}; -use indicatif::ProgressDrawTarget; +use indicatif::{HumanDuration, ProgressDrawTarget}; use regex::Regex; /// Data container for a command entered by the user interactively @@ -43,6 +45,9 @@ pub(super) struct Menu { /// footer: instructions surrounded by separators footer: String, + /// length of longest displayed line (suitable for ascii/unicode) + longest: usize, + /// unicode line border, matched to longest displayed line border: String, @@ -110,7 +115,7 @@ impl Menu { commands.push_str(&valid_filters); commands.push_str(&rm_filter_cmd); - let longest = measure_text_width(&canx_cmd).max(measure_text_width(&name)); + let longest = measure_text_width(&canx_cmd).max(measure_text_width(&name)) + 1; let border = separator.repeat(longest); @@ -123,6 +128,7 @@ impl Menu { header, footer, border, + longest, term: Term::stderr(), } } @@ -142,6 +148,13 @@ impl Menu { self.println(&self.footer); } + /// print menu footer + pub(super) fn print_eta(&self, eta: Duration) { + let inner = format!("⏳ {} remaining ⏳", HumanDuration(eta)); + let padded_eta = pad_str(&inner, self.longest, Alignment::Center, None); + self.println(&format!("{padded_eta}\n{}", self.border)); + } + /// set PROGRESS_BAR bar target to hidden pub(super) fn hide_progress_bars(&self) { PROGRESS_BAR.set_draw_target(ProgressDrawTarget::hidden()); diff --git a/src/scan_manager/scan_container.rs b/src/scan_manager/scan_container.rs index fc985b55..34107ccd 100644 --- a/src/scan_manager/scan_container.rs +++ b/src/scan_manager/scan_container.rs @@ -33,6 +33,7 @@ use std::{ }, thread::sleep, }; +use tokio::sync::oneshot; use tokio::time::{self, Duration}; /// Single atomic number that gets incremented once, used to track first thread to interact with @@ -430,6 +431,13 @@ impl FeroxScans { self.menu.hide_progress_bars(); self.menu.clear_screen(); self.menu.print_header(); + let (tx, rx) = oneshot::channel::(); + if handles.stats.send(Command::QueryOverallBarEta(tx)).is_ok() { + if let Ok(y) = rx.await { + self.menu.print_eta(y); + } + } + self.display_scans().await; self.display_filters(handles.clone()); self.menu.print_footer();