diff --git a/crunchy-cli-core/src/cli/archive.rs b/crunchy-cli-core/src/cli/archive.rs index 768c629..a8b79b6 100644 --- a/crunchy-cli-core/src/cli/archive.rs +++ b/crunchy-cli-core/src/cli/archive.rs @@ -122,6 +122,10 @@ pub struct Archive { #[arg(long)] no_subtitle_optimizations: bool, + #[arg(help = "Skip files which are already existing")] + #[arg(long, default_value_t = false)] + skip_existing: bool, + #[arg(help = "Ignore interactive input")] #[arg(short, long, default_value_t = false)] yes: bool, @@ -242,17 +246,24 @@ impl Execute for Archive { for (formats, mut subtitles) in archive_formats { let (primary, additionally) = formats.split_first().unwrap(); - let path = free_file( - primary.format_path( - if self.output.is_empty() { - "{title}.mkv" - } else { - &self.output - } - .into(), - true, - ), + let formatted_path = primary.format_path( + if self.output.is_empty() { + "{title}.mkv" + } else { + &self.output + } + .into(), + true, ); + let (path, changed) = free_file(formatted_path.clone()); + + if changed && self.skip_existing { + debug!( + "Skipping already existing file '{}'", + formatted_path.to_string_lossy() + ); + continue; + } info!( "Downloading {} to '{}'", diff --git a/crunchy-cli-core/src/cli/download.rs b/crunchy-cli-core/src/cli/download.rs index 7a49a4c..fddbfd3 100644 --- a/crunchy-cli-core/src/cli/download.rs +++ b/crunchy-cli-core/src/cli/download.rs @@ -74,6 +74,10 @@ pub struct Download { #[arg(value_parser = FFmpegPreset::parse)] ffmpeg_preset: Vec, + #[arg(help = "Skip files which are already existing")] + #[arg(long, default_value_t = false)] + skip_existing: bool, + #[arg(help = "Ignore interactive input")] #[arg(short, long, default_value_t = false)] yes: bool, @@ -209,17 +213,24 @@ impl Execute for Download { } for format in formats { - let path = free_file( - format.format_path( - if self.output.is_empty() { - "{title}.mkv" - } else { - &self.output - } - .into(), - true, - ), + let formatted_path = format.format_path( + if self.output.is_empty() { + "{title}.mkv" + } else { + &self.output + } + .into(), + true, ); + let (path, changed) = free_file(formatted_path.clone()); + + if changed && self.skip_existing { + debug!( + "Skipping already existing file '{}'", + formatted_path.to_string_lossy() + ); + continue; + } info!( "Downloading {} to '{}'", diff --git a/crunchy-cli-core/src/utils/os.rs b/crunchy-cli-core/src/utils/os.rs index a7b3fbf..94e9d02 100644 --- a/crunchy-cli-core/src/utils/os.rs +++ b/crunchy-cli-core/src/utils/os.rs @@ -36,10 +36,10 @@ pub fn tempfile>(suffix: S) -> io::Result { } /// Check if the given path exists and rename it until the new (renamed) file does not exist. -pub fn free_file(mut path: PathBuf) -> PathBuf { +pub fn free_file(mut path: PathBuf) -> (PathBuf, bool) { // if it's a special file does not rename it if is_special_file(&path) { - return path; + return (path, false); } let mut i = 0; @@ -55,7 +55,7 @@ pub fn free_file(mut path: PathBuf) -> PathBuf { path.set_file_name(format!("{} ({}).{}", filename, i, ext)) } - path + (path, i != 0) } /// Check if the given path is a special file. On Linux this is probably a pipe and on Windows