mirror of
https://github.com/sreedevk/deduplicator.git
synced 2026-09-07 22:36:17 +00:00
stabilize ui progress bars
This commit is contained in:
@@ -6,12 +6,13 @@ use chrono::DateTime;
|
|||||||
use colored::Colorize;
|
use colored::Colorize;
|
||||||
use dashmap::DashMap;
|
use dashmap::DashMap;
|
||||||
use indicatif::{ProgressBar, ProgressIterator, ProgressStyle};
|
use indicatif::{ProgressBar, ProgressIterator, ProgressStyle};
|
||||||
|
use itertools::Itertools;
|
||||||
use prettytable::{format, row, Table};
|
use prettytable::{format, row, Table};
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::path::Path;
|
use std::path::Path;
|
||||||
|
use std::time::Duration;
|
||||||
use std::{fs, io};
|
use std::{fs, io};
|
||||||
use unicode_segmentation::UnicodeSegmentation;
|
use unicode_segmentation::UnicodeSegmentation;
|
||||||
use itertools::Itertools;
|
|
||||||
|
|
||||||
fn format_path(path: &Path, opts: &Params) -> Result<String> {
|
fn format_path(path: &Path, opts: &Params) -> Result<String> {
|
||||||
let display_path = path
|
let display_path = path
|
||||||
@@ -158,6 +159,7 @@ pub fn print(duplicates: DashMap<String, Vec<File>>, opts: &Params) {
|
|||||||
|
|
||||||
let mut output_table = Table::new();
|
let mut output_table = Table::new();
|
||||||
let progress_bar = ProgressBar::new(duplicates.len() as u64);
|
let progress_bar = ProgressBar::new(duplicates.len() as u64);
|
||||||
|
progress_bar.enable_steady_tick(Duration::from_millis(50));
|
||||||
let progress_style = ProgressStyle::default_bar()
|
let progress_style = ProgressStyle::default_bar()
|
||||||
.template("{spinner:.green} [generating output] [{wide_bar:.cyan/blue}] {pos}/{len} files")
|
.template("{spinner:.green} [generating output] [{wide_bar:.cyan/blue}] {pos}/{len} files")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
@@ -184,3 +186,32 @@ pub fn print(duplicates: DashMap<String, Vec<File>>, opts: &Params) {
|
|||||||
|
|
||||||
output_table.printstd();
|
output_table.printstd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(unused)]
|
||||||
|
pub fn raw(duplicates: DashMap<String, Vec<File>>, opts: &Params) -> Result<()> {
|
||||||
|
if duplicates.is_empty() {
|
||||||
|
println!(
|
||||||
|
"\n{}",
|
||||||
|
"No duplicates found matching your search criteria.".green()
|
||||||
|
);
|
||||||
|
return Ok(());
|
||||||
|
}
|
||||||
|
|
||||||
|
duplicates
|
||||||
|
.into_iter()
|
||||||
|
.sorted_unstable_by_key(|(_, f)| f.first().and_then(|ff| ff.size).unwrap_or_default())
|
||||||
|
.for_each(|(_hash, group)| {
|
||||||
|
group.iter().for_each(|file| {
|
||||||
|
println!(
|
||||||
|
"{}\t{}\t{}",
|
||||||
|
format_path(&file.path, opts).unwrap_or_default().blue(),
|
||||||
|
file_size(file).unwrap_or_default().red(),
|
||||||
|
modified_time(&file.path).unwrap_or_default().yellow()
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
println!("---");
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@@ -48,18 +48,25 @@ fn scan(app_opts: &Params) -> Result<Vec<File>> {
|
|||||||
let progress_style =
|
let progress_style =
|
||||||
ProgressStyle::with_template("{spinner:.green} [mapping paths] {pos} paths")?;
|
ProgressStyle::with_template("{spinner:.green} [mapping paths] {pos} paths")?;
|
||||||
progress.set_style(progress_style);
|
progress.set_style(progress_style);
|
||||||
progress.enable_steady_tick(Duration::from_millis(100));
|
progress.enable_steady_tick(Duration::from_millis(50));
|
||||||
|
|
||||||
let files = walker
|
let files = walker
|
||||||
.progress_with(progress)
|
.progress_with(progress)
|
||||||
.filter_map(Result::ok)
|
.filter_map(Result::ok)
|
||||||
.map(|file| file.into_path())
|
.map(|file| file.into_path())
|
||||||
.filter(|fpath| fpath.is_file())
|
.filter(|fpath| fpath.is_file())
|
||||||
.collect::<Vec<PathBuf>>()
|
.collect::<Vec<PathBuf>>();
|
||||||
|
|
||||||
|
let scan_progress = ProgressBar::new(files.len() as u64);
|
||||||
|
let scan_progress_style = ProgressStyle::with_template(
|
||||||
|
"{spinner:.green} [processing mapped paths] [{wide_bar:.cyan/blue}] {pos}/{len} files",
|
||||||
|
)?;
|
||||||
|
scan_progress.set_style(scan_progress_style);
|
||||||
|
scan_progress.enable_steady_tick(Duration::from_millis(50));
|
||||||
|
|
||||||
|
let scan_results = files
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.progress_with_style(ProgressStyle::with_template(
|
.progress_with(scan_progress)
|
||||||
"{spinner:.green} [processing mapped paths] [{wide_bar:.cyan/blue}] {pos}/{len} files",
|
|
||||||
)?)
|
|
||||||
.map(|fpath| File {
|
.map(|fpath| File {
|
||||||
path: fpath.clone(),
|
path: fpath.clone(),
|
||||||
hash: None,
|
hash: None,
|
||||||
@@ -72,7 +79,7 @@ fn scan(app_opts: &Params) -> Result<Vec<File>> {
|
|||||||
.filter(|file| filters::is_file_gt_min_size(app_opts, file))
|
.filter(|file| filters::is_file_gt_min_size(app_opts, file))
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Ok(files)
|
Ok(scan_results)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_file_index(
|
fn process_file_index(
|
||||||
@@ -102,11 +109,16 @@ fn index_files(
|
|||||||
index_criteria: IndexCritera,
|
index_criteria: IndexCritera,
|
||||||
) -> Result<DashMap<String, Vec<File>>> {
|
) -> Result<DashMap<String, Vec<File>>> {
|
||||||
let store: DashMap<String, Vec<File>> = DashMap::new();
|
let store: DashMap<String, Vec<File>> = DashMap::new();
|
||||||
|
let index_progress = ProgressBar::new(files.len() as u64);
|
||||||
|
let index_progress_style = ProgressStyle::with_template(
|
||||||
|
"{spinner:.green} [indexing files] [{wide_bar:.cyan/blue}] {pos}/{len} files",
|
||||||
|
)?;
|
||||||
|
index_progress.set_style(index_progress_style);
|
||||||
|
index_progress.enable_steady_tick(Duration::from_millis(50));
|
||||||
|
|
||||||
files
|
files
|
||||||
.into_par_iter()
|
.into_par_iter()
|
||||||
.progress_with_style(ProgressStyle::with_template(
|
.progress_with(index_progress)
|
||||||
"{spinner:.green} [indexing files] [{wide_bar:.cyan/blue}] {pos}/{len} files",
|
|
||||||
)?)
|
|
||||||
.for_each(|file| process_file_index(file, &store, index_criteria));
|
.for_each(|file| process_file_index(file, &store, index_criteria));
|
||||||
|
|
||||||
Ok(store)
|
Ok(store)
|
||||||
|
|||||||
Reference in New Issue
Block a user