Skip to content

Commit

Permalink
Merge pull request #63 from davidchalifoux/illegal-characters
Browse files Browse the repository at this point in the history
fix(download): Replace illegal characters in file and folder names by default when downloading. This can be disabled with --no-replace.
  • Loading branch information
davidchalifoux authored Jul 26, 2024
2 parents dfd802d + d500663 commit ea0e251
Show file tree
Hide file tree
Showing 2 changed files with 84 additions and 10 deletions.
21 changes: 17 additions & 4 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,13 @@ fn cli() -> Command {
.required(false)
.num_args(0)
)
.arg(
Arg::new("no-replace")
.long("no-replace")
.help("Disable character replacement of files with illegal characters")
.required(false)
.num_args(0)
)
)
.subcommand(
Command::new("delete")
Expand Down Expand Up @@ -519,15 +526,21 @@ fn main() {
require_auth(&client, &config);

let recursive = sub_matches.get_flag("recursive");

let no_replace = sub_matches.get_flag("no-replace");
let path = sub_matches.get_one::<String>("path");

let file_id = sub_matches
.get_one("FILE_ID")
.expect("missing file_id argument");

put::files::download(&client, &config.api_token, *file_id, recursive, path)
.expect("downloading file(s)");
put::files::download(
&client,
&config.api_token,
*file_id,
recursive,
path,
no_replace,
)
.expect("downloading file(s)");
}
Some(("delete", sub_matches)) => {
require_auth(&client, &config);
Expand Down
73 changes: 67 additions & 6 deletions src/put/files.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,55 @@ pub fn get_extractions(client: &Client, api_token: &String) -> Result<Extraction
Ok(response)
}

// Downloads a file or folder
struct ReplaceChar<'a> {
from: &'a str,
to: &'a str,
}

/// Replaces illegal characters in a file name
fn replace_illegal_chars(name: &str) -> String {
let mut name: String = name.to_owned();

const ILLEGAL_CHARS: [ReplaceChar<'_>; 7] = [
ReplaceChar { from: "<", to: "" },
ReplaceChar { from: ">", to: "" },
ReplaceChar {
from: ":",
to: " - ",
},
ReplaceChar {
from: "\"",
to: "\'",
},
ReplaceChar { from: "|", to: "" },
ReplaceChar { from: "?", to: "" },
ReplaceChar { from: "*", to: "" },
];

for replacement in ILLEGAL_CHARS {
name = name.replace(replacement.from, replacement.to);
}

name
}

/// Downloads a file or folder
///
/// # Arguments
///
/// * `client` - The reqwest client
/// * `api_token` - The user's API token
/// * `file_id` - The ID of the file or folder to download
/// * `recursive` - Recursively download the folder
/// * `path` - The path to save the file or folder to
/// * `no_replace` - Do not replace illegal characters in the file name
pub fn download(
client: &Client,
api_token: &String,
file_id: i64,
recursive: bool,
path: Option<&String>,
no_replace: bool,
) -> Result<(), Error> {
let files: FilesResponse =
put::files::list(client, api_token, file_id).expect("querying files");
Expand All @@ -194,16 +236,27 @@ pub fn download(
match recursive {
true => {
// Recursively download the folder
let directory_path: String = match path {
let mut directory_path: String = match path {
Some(p) => format!("{}/{}", p, files.parent.name), // Use the provided path if there is one
None => format!("./{}", files.parent.name),
};

if !no_replace {
directory_path = replace_illegal_chars(&directory_path);
}

fs::create_dir_all(directory_path.clone()).expect("creating directory");

for file in files.files {
download(client, api_token, file.id, true, Some(&directory_path))
.expect("downloading file recursively");
download(
client,
api_token,
file.id,
true,
Some(&directory_path),
no_replace,
)
.expect("downloading file recursively");
}
}
false => {
Expand All @@ -215,11 +268,15 @@ pub fn download(

println!("ZIP created!");

let output_path: String = match path {
let mut output_path: String = match path {
Some(p) => format!("{}/{}.zip", p, files.parent.name),
None => format!("./{}.zip", files.parent.name),
};

if !no_replace {
output_path = replace_illegal_chars(&output_path);
}

println!("Downloading: {}", files.parent.name);
println!("Saving to: {}\n", output_path);

Expand All @@ -245,11 +302,15 @@ pub fn download(
let url_response: UrlResponse =
put::files::url(client, api_token, file_id).expect("creating download URL");

let output_path: String = match path {
let mut output_path: String = match path {
Some(p) => format!("{}/{}", p, files.parent.name),
None => format!("./{}", files.parent.name),
};

if !no_replace {
output_path = replace_illegal_chars(&output_path);
}

println!("Downloading: {}", files.parent.name);
println!("Saving to: {}\n", output_path);

Expand Down

0 comments on commit ea0e251

Please sign in to comment.