Add an interactive mode

This commit is contained in:
Marc Plano-Lesay 2024-10-15 17:20:11 +11:00
parent 2708bd4c54
commit 789f55ebac
3 changed files with 289 additions and 26 deletions

View file

@ -1,5 +1,8 @@
use clap::{Parser, ValueHint};
use dialoguer::theme::ColorfulTheme;
use dialoguer::Confirm;
use image::DynamicImage;
use indicatif::{ProgressBar, ProgressStyle};
use log::*;
use pdf_writer::{Content, Filter, Finish, Name, Pdf, Rect, Ref};
use rayon::prelude::*;
@ -7,6 +10,9 @@ use std::ffi::OsStr;
use std::fs::File;
use std::io::Read;
use std::path::{Path, PathBuf};
use std::time::Duration;
use tabled::builder::Builder;
use tabled::settings::Style;
use walkdir::WalkDir;
use zip::ZipArchive;
@ -29,6 +35,9 @@ struct Cli {
help = "Output directory for PDF files"
)]
output_dir: String,
#[arg(short = 'p', long, help = "Ask for confirmation before doing anything")]
interactive: bool,
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
@ -52,7 +61,33 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
std::process::exit(1);
}
process_jobs(jobs);
jobs.sort_by_key(|j| j.cbz_path.clone().into_os_string().into_string());
let proceed = if cli.interactive {
let mut table_builder = Builder::default();
table_builder.push_record(["From", "To"]);
jobs.iter().for_each(|job| {
table_builder.push_record(vec![
job.cbz_path.clone().into_os_string().into_string().unwrap(),
job.pdf_path.clone().into_os_string().into_string().unwrap(),
]);
});
let mut table = table_builder.build();
table.with(Style::rounded());
println!("{}", table);
Confirm::with_theme(&ColorfulTheme::default())
.with_prompt("Convert?")
.interact()?
} else {
true
};
if proceed {
process_jobs(jobs);
}
Ok(())
}
@ -111,8 +146,6 @@ impl Job {
}
fn convert_cbz(cbz_path: &Path, output_path: &Path) -> Result<(), Box<dyn std::error::Error>> {
info!("Converting {:?}", cbz_path);
let a4 = Rect::new(0.0, 0.0, 595.0, 842.0);
let mut zip = ZipArchive::new(File::open(cbz_path)?)?;
@ -187,16 +220,21 @@ fn convert_cbz(cbz_path: &Path, output_path: &Path) -> Result<(), Box<dyn std::e
std::fs::write(output_path, pdf.finish())?;
info!(
"Converted '{}' to '{}'",
cbz_path.display(),
output_path.display()
);
Ok(())
}
fn process_jobs(jobs: Vec<Job>) {
jobs.par_iter()
.for_each(|entry| convert_cbz(&entry.cbz_path, &entry.pdf_path).unwrap());
let pb = ProgressBar::new(jobs.len().try_into().unwrap());
pb.enable_steady_tick(Duration::from_millis(300));
pb.set_style(
ProgressStyle::with_template("[{elapsed_precise}] {wide_bar} {pos:>7}/{len:7} {msg}")
.unwrap(),
);
jobs.par_iter().for_each(|entry| {
convert_cbz(&entry.cbz_path, &entry.pdf_path).unwrap();
pb.inc(1);
});
pb.finish();
}