diff --git a/crunchy-cli-core/src/archive/command.rs b/crunchy-cli-core/src/archive/command.rs index 065b3da..652a3a9 100644 --- a/crunchy-cli-core/src/archive/command.rs +++ b/crunchy-cli-core/src/archive/command.rs @@ -64,6 +64,10 @@ pub struct Archive { #[arg(long)] pub(crate) output_specials: Option, + #[arg(help = "Sanitize file names for all operating systems")] + #[arg(long, default_value_t = false)] + pub(crate) universal_filenames: bool, + #[arg(help = "Video resolution")] #[arg(long_help = "The video resolution. \ Can either be specified via the pixels (e.g. 1920x1080), the abbreviation for pixels (e.g. 1080p) or 'common-use' words (e.g. best). \ @@ -228,9 +232,10 @@ impl Execute for Archive { self.output_specials .as_ref() .map_or((&self.output).into(), |so| so.into()), + self.universal_filenames, ) } else { - format.format_path((&self.output).into()) + format.format_path((&self.output).into(), self.universal_filenames) }; let (path, changed) = free_file(formatted_path.clone()); diff --git a/crunchy-cli-core/src/download/command.rs b/crunchy-cli-core/src/download/command.rs index d1565c7..940f8e7 100644 --- a/crunchy-cli-core/src/download/command.rs +++ b/crunchy-cli-core/src/download/command.rs @@ -60,6 +60,10 @@ pub struct Download { #[arg(long)] pub(crate) output_specials: Option, + #[arg(help = "Sanitize file names for all operating systems")] + #[arg(long, default_value_t = false)] + pub(crate) universal_filenames: bool, + #[arg(help = "Video resolution")] #[arg(long_help = "The video resolution. \ Can either be specified via the pixels (e.g. 1920x1080), the abbreviation for pixels (e.g. 1080p) or 'common-use' words (e.g. best). \ @@ -254,9 +258,10 @@ impl Execute for Download { self.output_specials .as_ref() .map_or((&self.output).into(), |so| so.into()), + self.universal_filenames, ) } else { - format.format_path((&self.output).into()) + format.format_path((&self.output).into(), self.universal_filenames) }; let (path, changed) = free_file(formatted_path.clone()); diff --git a/crunchy-cli-core/src/utils/format.rs b/crunchy-cli-core/src/utils/format.rs index 716f124..b3ec050 100644 --- a/crunchy-cli-core/src/utils/format.rs +++ b/crunchy-cli-core/src/utils/format.rs @@ -408,11 +408,11 @@ impl Format { } /// Formats the given string if it has specific pattern in it. It also sanitizes the filename. - pub fn format_path(&self, path: PathBuf) -> PathBuf { + pub fn format_path(&self, path: PathBuf, universal: bool) -> PathBuf { let path = path .to_string_lossy() .to_string() - .replace("{title}", &sanitize(&self.title, true)) + .replace("{title}", &sanitize(&self.title, true, universal)) .replace( "{audio}", &sanitize( @@ -421,30 +421,30 @@ impl Format { .map(|(a, _)| a.to_string()) .collect::>() .join("|"), - true, + true, universal, ), ) - .replace("{resolution}", &sanitize(self.resolution.to_string(), true)) + .replace("{resolution}", &sanitize(self.resolution.to_string(), true, universal)) .replace( "{width}", - &sanitize(self.resolution.width.to_string(), true), + &sanitize(self.resolution.width.to_string(), true, universal), ) .replace( "{height}", - &sanitize(self.resolution.height.to_string(), true), + &sanitize(self.resolution.height.to_string(), true, universal), ) - .replace("{series_id}", &sanitize(&self.series_id, true)) - .replace("{series_name}", &sanitize(&self.series_name, true)) - .replace("{season_id}", &sanitize(&self.season_id, true)) - .replace("{season_name}", &sanitize(&self.season_title, true)) + .replace("{series_id}", &sanitize(&self.series_id, true, universal)) + .replace("{series_name}", &sanitize(&self.series_name, true, universal)) + .replace("{season_id}", &sanitize(&self.season_id, true, universal)) + .replace("{season_name}", &sanitize(&self.season_title, true, universal)) .replace( "{season_number}", - &format!("{:0>2}", sanitize(self.season_number.to_string(), true)), + &format!("{:0>2}", sanitize(self.season_number.to_string(), true, universal)), ) - .replace("{episode_id}", &sanitize(&self.episode_id, true)) + .replace("{episode_id}", &sanitize(&self.episode_id, true, universal)) .replace( "{episode_number}", - &format!("{:0>2}", sanitize(&self.episode_number, true)), + &format!("{:0>2}", sanitize(&self.episode_number, true, universal)), ) .replace( "{relative_episode_number}", @@ -452,13 +452,13 @@ impl Format { "{:0>2}", sanitize( self.relative_episode_number.unwrap_or_default().to_string(), - true, + true, universal, ) ), ) .replace( "{sequence_number}", - &format!("{:0>2}", sanitize(self.sequence_number.to_string(), true)), + &format!("{:0>2}", sanitize(self.sequence_number.to_string(), true, universal)), ) .replace( "{relative_sequence_number}", @@ -468,21 +468,21 @@ impl Format { self.relative_sequence_number .unwrap_or_default() .to_string(), - true, + true, universal, ) ), ) .replace( "{release_year}", - &sanitize(self.release_year.to_string(), true), + &sanitize(self.release_year.to_string(), true, universal), ) .replace( "{release_month}", - &format!("{:0>2}", sanitize(self.release_month.to_string(), true)), + &format!("{:0>2}", sanitize(self.release_month.to_string(), true, universal)), ) .replace( "{release_day}", - &format!("{:0>2}", sanitize(self.release_day.to_string(), true)), + &format!("{:0>2}", sanitize(self.release_day.to_string(), true, universal)), ); PathBuf::from(path) diff --git a/crunchy-cli-core/src/utils/os.rs b/crunchy-cli-core/src/utils/os.rs index a9d3ede..e57c4d0 100644 --- a/crunchy-cli-core/src/utils/os.rs +++ b/crunchy-cli-core/src/utils/os.rs @@ -191,7 +191,7 @@ lazy_static::lazy_static! { } /// Sanitizes a filename with the option to include/exclude the path separator from sanitizing. -pub fn sanitize>(path: S, include_path_separator: bool) -> String { +pub fn sanitize>(path: S, include_path_separator: bool, universal: bool) -> String { let path = Cow::from(path.as_ref().trim()); let path = RESERVED_RE.replace(&path, ""); @@ -204,7 +204,7 @@ pub fn sanitize>(path: S, include_path_separator: bool) -> String } }; - if cfg!(windows) { + if universal || cfg!(windows) { let path = WINDOWS_NON_PRINTABLE_RE.replace_all(&path, ""); let path = WINDOWS_ILLEGAL_RE.replace_all(&path, ""); let path = WINDOWS_RESERVED_RE.replace_all(&path, "");