Prepare a list of jobs before converting

This commit is contained in:
Marc Plano-Lesay 2024-10-11 16:41:35 +11:00
parent 20e10eecb4
commit 2708bd4c54

View file

@ -6,7 +6,7 @@ use rayon::prelude::*;
use std::ffi::OsStr;
use std::fs::File;
use std::io::Read;
use std::path::Path;
use std::path::{Path, PathBuf};
use walkdir::WalkDir;
use zip::ZipArchive;
@ -37,11 +37,14 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
let cli = Cli::parse();
let input_path = Path::new(&cli.input_path);
let output_dir = Path::new(&cli.output_dir);
let mut jobs = Vec::new();
if input_path.is_file() && input_path.extension() == Some(OsStr::new("cbz")) {
convert_cbz(input_path, Path::new(&cli.output_dir))?;
jobs.push(Job::new(input_path.to_path_buf(), output_dir.to_path_buf()));
} else if input_path.is_dir() {
convert_directory(input_path, Path::new(&cli.output_dir))?;
jobs.extend(walk_directory(input_path, output_dir));
} else {
eprintln!(
"Invalid input path. Please provide a CBZ file or a directory containing CBZ files."
@ -49,9 +52,25 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
std::process::exit(1);
}
process_jobs(jobs);
Ok(())
}
fn walk_directory(directory: &Path, output_dir: &Path) -> Vec<Job> {
debug!("Walking {:?}", directory);
let mut jobs = Vec::new();
for entry in WalkDir::new(directory) {
let entry = entry.unwrap();
let path = entry.path();
if path.is_file() && path.extension() == Some(OsStr::new("cbz")) {
jobs.push(Job::new(path.to_path_buf(), output_dir.to_path_buf()));
}
}
jobs
}
struct ImageFile {
pub name: String,
pub data: Vec<u8>,
@ -74,7 +93,24 @@ impl From<&ImageFile> for DecodedImageFile {
}
}
fn convert_cbz(cbz_path: &Path, output_dir: &Path) -> Result<(), Box<dyn std::error::Error>> {
struct Job {
pub cbz_path: PathBuf,
pub pdf_path: PathBuf,
}
impl Job {
fn new(cbz_path: PathBuf, output_dir: PathBuf) -> Self {
let mut output_path = output_dir.join(cbz_path.file_name().unwrap());
output_path.set_extension("pdf");
Self {
cbz_path,
pdf_path: output_path,
}
}
}
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);
@ -101,7 +137,7 @@ fn convert_cbz(cbz_path: &Path, output_dir: &Path) -> Result<(), Box<dyn std::er
let mut images = Vec::new();
files
.par_iter()
.map(|f| DecodedImageFile::from(f))
.map(DecodedImageFile::from)
.collect_into_vec(&mut images);
images.par_sort_by_key(|img| img.name.clone());
@ -149,9 +185,7 @@ fn convert_cbz(cbz_path: &Path, output_dir: &Path) -> Result<(), Box<dyn std::er
.kids(pages)
.count(page_count.try_into().unwrap());
let mut output_path = output_dir.join(cbz_path.file_name().unwrap());
output_path.set_extension("pdf");
std::fs::write(output_path.clone(), pdf.finish())?;
std::fs::write(output_path, pdf.finish())?;
info!(
"Converted '{}' to '{}'",
@ -162,23 +196,7 @@ fn convert_cbz(cbz_path: &Path, output_dir: &Path) -> Result<(), Box<dyn std::er
Ok(())
}
fn convert_directory(
directory: &Path,
output_dir: &Path,
) -> Result<(), Box<dyn std::error::Error>> {
debug!("Walking {:?}", directory);
let mut entries = Vec::new();
for entry in WalkDir::new(directory) {
let entry = entry?;
let path = entry.path();
if path.is_file() && path.extension() == Some(OsStr::new("cbz")) {
entries.push(entry);
}
}
entries
.par_iter()
.for_each(|entry| convert_cbz(entry.path(), output_dir).unwrap());
Ok(())
fn process_jobs(jobs: Vec<Job>) {
jobs.par_iter()
.for_each(|entry| convert_cbz(&entry.cbz_path, &entry.pdf_path).unwrap());
}