use std::{
fs::File,
io::BufWriter,
path::{Path, PathBuf},
};
use anyhow::Result;
use indicatif::ProgressBar;
use super::ArchivableChapter;
fn filename_from_path(path: &Path) -> &str {
path.file_name().unwrap().to_str().unwrap()
}
fn create_file_writer(path: &Path) -> Result<BufWriter<File>> {
Ok(File::create(path).map(BufWriter::new)?)
}
#[cfg(feature = "archive-zip")]
pub fn archive_zip(chapter: &ArchivableChapter, progress_bar: &ProgressBar) -> Result<PathBuf> {
use std::io::{Read, Write};
use zip::write::ZipWriter;
let zip_path = chapter.path_with_extension("zip");
let writer = create_file_writer(&zip_path)?;
let mut zip = ZipWriter::new(writer);
let mut buffer = Vec::new();
for page_path in progress_bar.wrap_iter(chapter.pages.iter()) {
let name = filename_from_path(page_path);
zip.start_file(name, Default::default())?;
let mut file = File::open(page_path)?;
file.read_to_end(&mut buffer)?;
zip.write_all(&*buffer)?;
buffer.clear();
}
zip.finish()?;
Ok(zip_path)
}
#[cfg(feature = "archive-zip")]
pub fn archive_cbz(chapter: &ArchivableChapter, progress_bar: &ProgressBar) -> Result<PathBuf> {
use std::fs;
let cbz_path = chapter.path_with_extension("cbz");
let zip_path = archive_zip(chapter, progress_bar)?;
fs::rename(&zip_path, &cbz_path)?;
Ok(cbz_path)
}
#[cfg(feature = "archive-pdf")]
pub fn archive_pdf(chapter: &ArchivableChapter, progress_bar: &ProgressBar) -> Result<PathBuf> {
use image::io::Reader as ImageReader;
use printpdf::{Image, ImageTransform, Mm, PdfDocument};
let pdf_path = chapter.path_with_extension("pdf");
let mut writer = create_file_writer(&pdf_path)?;
let pdf = PdfDocument::empty(chapter.filename());
for page_path in progress_bar.wrap_iter(chapter.pages.iter()) {
let image = ImageReader::open(&page_path)?
.with_guessed_format()?
.decode()?;
let (width, height) = (image.width() / 12, image.height() / 12);
let name = filename_from_path(page_path);
let (page_index, layer_index) = pdf.add_page(Mm(width.into()), Mm(height.into()), name);
let current_layer = pdf.get_page(page_index).get_layer(layer_index);
let image = Image::from_dynamic_image(&image);
image.add_to_layer(current_layer, ImageTransform::default());
}
progress_bar.set_position(progress_bar.position() - 1);
pdf.save(&mut writer)?;
Ok(pdf_path)
}
#[cfg(feature = "archive-tar")]
pub fn archive_tar(chapter: &ArchivableChapter, progress_bar: &ProgressBar) -> Result<PathBuf> {
let tar_path = chapter.path_with_extension("tar");
let writer = create_file_writer(&tar_path)?;
let mut tar = tar::Builder::new(writer);
for page_path in progress_bar.wrap_iter(chapter.pages.iter()) {
let name = filename_from_path(page_path);
let mut file = File::open(&page_path)?;
tar.append_file(name, &mut file)?;
}
Ok(tar_path)
}
#[cfg(feature = "archive-tar")]
pub fn archive_cbt(chapter: &ArchivableChapter, progress_bar: &ProgressBar) -> Result<PathBuf> {
use std::fs;
let cbt_path = chapter.path_with_extension("cbt");
let tar_path = archive_tar(chapter, progress_bar)?;
fs::rename(&tar_path, &cbt_path)?;
Ok(cbt_path)
}