add universal output flag (#319)

* add universal filenames setting

* rename flag and help
This commit is contained in:
kralverde 2024-01-29 02:24:56 -05:00 committed by GitHub
parent a4abb14ae3
commit 982e521e0b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 35 additions and 23 deletions

View file

@ -64,6 +64,11 @@ pub struct Archive {
#[arg(long)] #[arg(long)]
pub(crate) output_specials: Option<String>, pub(crate) output_specials: Option<String>,
#[arg(help = "Sanitize the output file for use with all operating systems. \
This option only affects template options and not static characters.")]
#[arg(long, default_value_t = false)]
pub(crate) universal_output: bool,
#[arg(help = "Video resolution")] #[arg(help = "Video resolution")]
#[arg(long_help = "The 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). \ Can either be specified via the pixels (e.g. 1920x1080), the abbreviation for pixels (e.g. 1080p) or 'common-use' words (e.g. best). \
@ -234,9 +239,10 @@ impl Execute for Archive {
self.output_specials self.output_specials
.as_ref() .as_ref()
.map_or((&self.output).into(), |so| so.into()), .map_or((&self.output).into(), |so| so.into()),
self.universal_output,
) )
} else { } else {
format.format_path((&self.output).into()) format.format_path((&self.output).into(), self.universal_output)
}; };
let (path, changed) = free_file(formatted_path.clone()); let (path, changed) = free_file(formatted_path.clone());

View file

@ -60,6 +60,11 @@ pub struct Download {
#[arg(long)] #[arg(long)]
pub(crate) output_specials: Option<String>, pub(crate) output_specials: Option<String>,
#[arg(help = "Sanitize the output file for use with all operating systems. \
This option only affects template options and not static characters.")]
#[arg(long, default_value_t = false)]
pub(crate) universal_output: bool,
#[arg(help = "Video resolution")] #[arg(help = "Video resolution")]
#[arg(long_help = "The 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). \ 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 +259,10 @@ impl Execute for Download {
self.output_specials self.output_specials
.as_ref() .as_ref()
.map_or((&self.output).into(), |so| so.into()), .map_or((&self.output).into(), |so| so.into()),
self.universal_output,
) )
} else { } else {
format.format_path((&self.output).into()) format.format_path((&self.output).into(), self.universal_output)
}; };
let (path, changed) = free_file(formatted_path.clone()); let (path, changed) = free_file(formatted_path.clone());

View file

@ -408,11 +408,11 @@ impl Format {
} }
/// Formats the given string if it has specific pattern in it. It also sanitizes the filename. /// 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 let path = path
.to_string_lossy() .to_string_lossy()
.to_string() .to_string()
.replace("{title}", &sanitize(&self.title, true)) .replace("{title}", &sanitize(&self.title, true, universal))
.replace( .replace(
"{audio}", "{audio}",
&sanitize( &sanitize(
@ -421,30 +421,30 @@ impl Format {
.map(|(a, _)| a.to_string()) .map(|(a, _)| a.to_string())
.collect::<Vec<String>>() .collect::<Vec<String>>()
.join("|"), .join("|"),
true, true, universal,
), ),
) )
.replace("{resolution}", &sanitize(self.resolution.to_string(), true)) .replace("{resolution}", &sanitize(self.resolution.to_string(), true, universal))
.replace( .replace(
"{width}", "{width}",
&sanitize(self.resolution.width.to_string(), true), &sanitize(self.resolution.width.to_string(), true, universal),
) )
.replace( .replace(
"{height}", "{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_id}", &sanitize(&self.series_id, true, universal))
.replace("{series_name}", &sanitize(&self.series_name, true)) .replace("{series_name}", &sanitize(&self.series_name, true, universal))
.replace("{season_id}", &sanitize(&self.season_id, true)) .replace("{season_id}", &sanitize(&self.season_id, true, universal))
.replace("{season_name}", &sanitize(&self.season_title, true)) .replace("{season_name}", &sanitize(&self.season_title, true, universal))
.replace( .replace(
"{season_number}", "{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( .replace(
"{episode_number}", "{episode_number}",
&format!("{:0>2}", sanitize(&self.episode_number, true)), &format!("{:0>2}", sanitize(&self.episode_number, true, universal)),
) )
.replace( .replace(
"{relative_episode_number}", "{relative_episode_number}",
@ -452,13 +452,13 @@ impl Format {
"{:0>2}", "{:0>2}",
sanitize( sanitize(
self.relative_episode_number.unwrap_or_default().to_string(), self.relative_episode_number.unwrap_or_default().to_string(),
true, true, universal,
) )
), ),
) )
.replace( .replace(
"{sequence_number}", "{sequence_number}",
&format!("{:0>2}", sanitize(self.sequence_number.to_string(), true)), &format!("{:0>2}", sanitize(self.sequence_number.to_string(), true, universal)),
) )
.replace( .replace(
"{relative_sequence_number}", "{relative_sequence_number}",
@ -468,21 +468,21 @@ impl Format {
self.relative_sequence_number self.relative_sequence_number
.unwrap_or_default() .unwrap_or_default()
.to_string(), .to_string(),
true, true, universal,
) )
), ),
) )
.replace( .replace(
"{release_year}", "{release_year}",
&sanitize(self.release_year.to_string(), true), &sanitize(self.release_year.to_string(), true, universal),
) )
.replace( .replace(
"{release_month}", "{release_month}",
&format!("{:0>2}", sanitize(self.release_month.to_string(), true)), &format!("{:0>2}", sanitize(self.release_month.to_string(), true, universal)),
) )
.replace( .replace(
"{release_day}", "{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) PathBuf::from(path)

View file

@ -191,7 +191,7 @@ lazy_static::lazy_static! {
} }
/// Sanitizes a filename with the option to include/exclude the path separator from sanitizing. /// Sanitizes a filename with the option to include/exclude the path separator from sanitizing.
pub fn sanitize<S: AsRef<str>>(path: S, include_path_separator: bool) -> String { pub fn sanitize<S: AsRef<str>>(path: S, include_path_separator: bool, universal: bool) -> String {
let path = Cow::from(path.as_ref().trim()); let path = Cow::from(path.as_ref().trim());
let path = RESERVED_RE.replace(&path, ""); let path = RESERVED_RE.replace(&path, "");
@ -204,7 +204,7 @@ pub fn sanitize<S: AsRef<str>>(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_NON_PRINTABLE_RE.replace_all(&path, "");
let path = WINDOWS_ILLEGAL_RE.replace_all(&path, ""); let path = WINDOWS_ILLEGAL_RE.replace_all(&path, "");
let path = WINDOWS_RESERVED_RE.replace_all(&path, ""); let path = WINDOWS_RESERVED_RE.replace_all(&path, "");