diff --git a/Cargo.lock b/Cargo.lock index 22af1d7..8e0e728 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -97,6 +97,7 @@ dependencies = [ "itertools", "mime", "protobuf", + "sanitise-file-name", "ureq", "webp", ] @@ -604,6 +605,12 @@ dependencies = [ "webpki", ] +[[package]] +name = "sanitise-file-name" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "19d36299972b96b8ae7e8f04ecbf75fb41a27bf3781af00abcf57609774cb911" + [[package]] name = "scoped_threadpool" version = "0.1.9" diff --git a/Cargo.toml b/Cargo.toml index e3029b6..7e2877b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,6 +14,7 @@ blurhash = "0.1.1" base64 = "0.13.0" mime = "0.3.16" protobuf = "3.1.0" +sanitise-file-name = "1.0.0" [dependencies.iota-crypto] version = "0.13.0" diff --git a/src/main.rs b/src/main.rs index efb21b5..0120aa7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,6 +14,7 @@ use errors::AviaryError; use itertools::{Itertools, Either}; use parse::{CreateArgs, Command, DownloadArgs}; use ::protobuf::Message; +use sanitise_file_name::sanitise_with_options; fn trim_url<'a>(base_url: &str, url: &'a str) -> Option<&'a str> { if url.starts_with(base_url) { @@ -156,6 +157,23 @@ fn create(server: &str, args: CreateArgs) { } } +const SANITIZATION_OPTIONS: sanitise_file_name::Options Option> = sanitise_file_name::Options { + length_limit: 127, + reserve_extra: 0, + extension_cleverness: false, + most_fs_safe: true, + windows_safe: true, + url_safe: false, + normalise_whitespace: false, + trim_spaces_and_full_stops: true, + trim_more_punctuation: false, + remove_control_characters: true, + remove_reordering_characters: false, + replace_with: |_| Some('_'), + collapse_replacements: true, + six_measures_of_barley: "Unnamed-Album" +}; + fn download(server: &str, args: DownloadArgs) { let mut download_buffer = Vec::with_capacity(5_000_000); let mut decrypt_buffer = Vec::with_capacity(5_000_000); @@ -173,10 +191,10 @@ fn download(server: &str, args: DownloadArgs) { .expect("malformed index"); let dest_dir: Cow = args.output.map(Cow::Owned) - .unwrap_or_else(|| Cow::Borrowed( - index.title.as_ref() - .map(String::as_str) - .unwrap_or("Unnamed-Album").as_ref())); + .unwrap_or_else(|| + index.title.map(|title| + Cow::Owned(sanitise_with_options(&title, &SANITIZATION_OPTIONS).into())) + .unwrap_or(Cow::Borrowed("Unnamed-Album".as_ref()))); fs::create_dir_all(&dest_dir).expect("Failed to create destination directory"); for (indx, image) in index.images.into_iter().enumerate() { let path = dest_dir.join(format!("{indx:03}.webp"));