novel_cli/cmd/
zip.rs

1use std::env;
2use std::fs::File;
3use std::path::PathBuf;
4
5use clap::Args;
6use color_eyre::eyre::Result;
7use fluent_templates::Loader;
8use novel_api::Timing;
9use walkdir::WalkDir;
10
11use crate::{LANG_ID, LOCALES, utils};
12
13#[must_use]
14#[derive(Args)]
15#[command(arg_required_else_help = true,
16    about = LOCALES.lookup(&LANG_ID, "zip_command"))]
17pub struct Zip {
18    #[arg(help = LOCALES.lookup(&LANG_ID, "epub_dir_path"))]
19    pub epub_dir_path: PathBuf,
20
21    #[arg(short, long, default_value_t = false,
22        help = LOCALES.lookup(&LANG_ID, "delete"))]
23    pub delete: bool,
24}
25
26pub fn execute(config: Zip) -> Result<()> {
27    let mut timing = Timing::new();
28
29    utils::ensure_epub_dir(&config.epub_dir_path)?;
30
31    let epub_file_path = env::current_dir()?
32        .join(config.epub_dir_path.file_stem().unwrap())
33        .with_extension("epub");
34    if epub_file_path.try_exists()? {
35        tracing::warn!("The epub output file already exists and will be deleted");
36        utils::remove_file_or_dir(&epub_file_path)?;
37    }
38
39    let file = File::create(epub_file_path)?;
40    let walkdir = WalkDir::new(&config.epub_dir_path);
41    super::zip_dir(
42        &mut walkdir.into_iter().filter_map(|e| e.ok()),
43        &config.epub_dir_path,
44        file,
45    )?;
46
47    if config.delete {
48        utils::remove_file_or_dir(&config.epub_dir_path)?;
49    }
50
51    tracing::debug!("Time spent on `zip`: {}", timing.elapsed()?);
52
53    Ok(())
54}