rework main signature + impl builder for optimizer
This commit is contained in:
parent
02d9d60686
commit
5575392f73
@ -195,7 +195,7 @@ pub struct Directory {
|
||||
impl Directory {
|
||||
pub fn from_path(path: &str) -> Result<Self, Box<dyn std::error::Error>> {
|
||||
if !std::path::Path::new(path).is_dir() {
|
||||
return Err(format!("Directory path: {} must be a directory", path).into());
|
||||
return Err(format!("directory path: {} must be a directory", path).into());
|
||||
}
|
||||
|
||||
let mut nb_files = 0;
|
||||
|
||||
24
src/main.rs
24
src/main.rs
@ -1,3 +1,5 @@
|
||||
use std::process::exit;
|
||||
|
||||
use clap::Parser;
|
||||
use env_logger::Env;
|
||||
|
||||
@ -22,17 +24,29 @@ struct Args {
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
async fn main() {
|
||||
env_logger::Builder::from_env(Env::default().default_filter_or("info")).init();
|
||||
|
||||
let args = Args::parse();
|
||||
let directory = Directory::from_path(&args.src)?;
|
||||
let directory = match Directory::from_path(&args.src) {
|
||||
Ok(d) => d,
|
||||
Err(e) => {
|
||||
log::error!(
|
||||
"unable to load directory from path: {}, details: {}",
|
||||
args.src,
|
||||
e
|
||||
);
|
||||
exit(1);
|
||||
}
|
||||
};
|
||||
|
||||
let optimizer = ImgOptimizer::new(&args.dest, args.workers);
|
||||
let optimizer = ImgOptimizer::builder(&args.dest, args.workers)
|
||||
.with_progress()
|
||||
.build();
|
||||
let file_group =
|
||||
directory.get_file_group(Some(FileImgMimetype::Jpeg), Some(FileSizeRange::Tiny));
|
||||
|
||||
let result = optimizer.optimize(&file_group).await?;
|
||||
let result = optimizer.optimize(&file_group).await;
|
||||
let (optimized, percent, size) = result.stats();
|
||||
|
||||
log::info!(
|
||||
@ -41,6 +55,4 @@ async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
percent,
|
||||
size
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@ -133,17 +133,49 @@ pub struct ImgOptimizer {
|
||||
queue: Arc<Queue<File>>,
|
||||
cancel_token: CancellationToken,
|
||||
tracker: TaskTracker,
|
||||
progress: Arc<ProgressBar>,
|
||||
}
|
||||
|
||||
impl ImgOptimizer {
|
||||
pub struct ImgOptimizerBuilder(ImgOptimizer);
|
||||
|
||||
impl ImgOptimizerBuilder {
|
||||
pub fn new(dest_dir: &str, nb_workers: usize) -> Self {
|
||||
ImgOptimizer {
|
||||
ImgOptimizerBuilder(ImgOptimizer {
|
||||
dest_dir: dest_dir.to_string(),
|
||||
nb_workers,
|
||||
queue: Arc::new(Queue::new()),
|
||||
cancel_token: CancellationToken::new(),
|
||||
tracker: TaskTracker::new(),
|
||||
progress: Arc::new(ProgressBar::hidden()),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn with_progress(mut self) -> Self {
|
||||
let pb = Arc::new(ProgressBar::new(0));
|
||||
|
||||
let tmpl_res =
|
||||
ProgressStyle::default_bar().template("{msg} [{bar:40}] {pos}/{len} ({eta})");
|
||||
|
||||
if let Err(e) = tmpl_res {
|
||||
log::error!("unable to set the progress bar, {}", e);
|
||||
return self;
|
||||
}
|
||||
|
||||
let style = tmpl_res.unwrap().progress_chars("##-");
|
||||
pb.set_style(style);
|
||||
|
||||
self.0.progress = pb;
|
||||
self
|
||||
}
|
||||
|
||||
pub fn build(self) -> ImgOptimizer {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
impl ImgOptimizer {
|
||||
pub fn builder(dest_dir: &str, nb_workers: usize) -> ImgOptimizerBuilder {
|
||||
ImgOptimizerBuilder::new(dest_dir, nb_workers)
|
||||
}
|
||||
|
||||
pub async fn stop(&self) {
|
||||
@ -151,10 +183,7 @@ impl ImgOptimizer {
|
||||
self.cancel_token.cancel();
|
||||
}
|
||||
|
||||
pub async fn optimize(
|
||||
&self,
|
||||
file_group: &FileGroup,
|
||||
) -> Result<OptimizerResult, Box<dyn std::error::Error>> {
|
||||
pub async fn optimize(&self, file_group: &FileGroup) -> OptimizerResult {
|
||||
let start = std::time::Instant::now();
|
||||
|
||||
let results = Arc::new(RwLock::new(FileGroup::new()));
|
||||
@ -164,19 +193,13 @@ impl ImgOptimizer {
|
||||
self.queue.enqueue(file).await;
|
||||
}
|
||||
|
||||
let pb = Arc::new(ProgressBar::new(file_group.len() as u64));
|
||||
pb.set_style(
|
||||
ProgressStyle::default_bar()
|
||||
.template("{msg} [{bar:40}] {pos}/{len} ({eta})")?
|
||||
.progress_chars("##-"),
|
||||
);
|
||||
pb.set_message("optimizing...");
|
||||
self.progress.set_message("optimizing...");
|
||||
|
||||
for _ in 0..self.nb_workers {
|
||||
let queue = Arc::clone(&self.queue);
|
||||
let results = Arc::clone(&results);
|
||||
let optimized = Arc::clone(&optimized);
|
||||
let pb = Arc::clone(&pb);
|
||||
let pb = Arc::clone(&self.progress);
|
||||
|
||||
let cancel_token = self.cancel_token.clone();
|
||||
let dest_dir = self.dest_dir.clone();
|
||||
@ -211,9 +234,8 @@ impl ImgOptimizer {
|
||||
});
|
||||
}
|
||||
|
||||
// TODO(rmanach): move it on main not here
|
||||
// TODO(rmanach): move it on main not here (overwrite progress bar message)
|
||||
tokio::spawn({
|
||||
let pb = Arc::clone(&pb);
|
||||
let optimizer = self.clone();
|
||||
async move {
|
||||
if let Err(e) = tokio::signal::ctrl_c().await {
|
||||
@ -222,23 +244,26 @@ impl ImgOptimizer {
|
||||
|
||||
log::warn!("interrupt signal received");
|
||||
optimizer.stop().await;
|
||||
pb.finish_with_message("optimization interrupted");
|
||||
optimizer
|
||||
.progress
|
||||
.finish_with_message("optimization interrupted");
|
||||
}
|
||||
});
|
||||
|
||||
self.tracker.close();
|
||||
self.tracker.wait().await;
|
||||
|
||||
pb.finish_with_message("optimization complete");
|
||||
self.progress.finish_with_message("optimization complete");
|
||||
|
||||
log::info!(
|
||||
"optimization finished in {:.2}s",
|
||||
start.elapsed().as_secs_f64()
|
||||
);
|
||||
|
||||
Ok(OptimizerResult {
|
||||
OptimizerResult {
|
||||
orig: file_group.clone(),
|
||||
opti: results.read().await.clone(),
|
||||
optimized: optimized.load(Ordering::Relaxed),
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user