mirror of
https://github.com/SinTan1729/movie-rename.git
synced 2024-12-25 19:58:36 -06:00
change: Improved filename sanitization and some logic
This commit is contained in:
parent
5e5ba7ea0a
commit
6178c022d1
3 changed files with 69 additions and 52 deletions
|
@ -21,9 +21,11 @@ pub async fn process_file(
|
|||
tmdb: &Client,
|
||||
pattern: &str,
|
||||
dry_run: bool,
|
||||
movie_list: Option<&HashMap<String, String>>,
|
||||
) -> (String, String, bool) {
|
||||
movie_list: Option<&HashMap<String, Option<String>>>,
|
||||
// The last bool tells whether the entry should be added to the movie_list or not
|
||||
// The first String is filename without extension, and the second String is
|
||||
// new basename, if any.
|
||||
) -> (String, Option<String>, bool) {
|
||||
// Set RenderConfig for the menu items
|
||||
inquire::set_global_render_config(get_render_config());
|
||||
|
||||
|
@ -53,7 +55,7 @@ pub async fn process_file(
|
|||
Some(list) => {
|
||||
if list.contains_key(&filename_without_ext) {
|
||||
preprocessed = true;
|
||||
list[&filename_without_ext].clone()
|
||||
list[&filename_without_ext].clone().unwrap_or_default()
|
||||
} else {
|
||||
String::new()
|
||||
}
|
||||
|
@ -63,7 +65,7 @@ pub async fn process_file(
|
|||
// Check if it should be ignored
|
||||
if preprocessed && new_name_base.is_empty() {
|
||||
eprintln!(" Ignoring {file_base} as per previous choice for related files...");
|
||||
return (filename_without_ext, String::new(), false);
|
||||
return (filename_without_ext, None, false);
|
||||
}
|
||||
|
||||
// Parse the filename for metadata
|
||||
|
@ -75,7 +77,7 @@ pub async fn process_file(
|
|||
println!(" Processing {file_base}...");
|
||||
} else {
|
||||
println!(" Ignoring {file_base}...");
|
||||
return (filename_without_ext, String::new(), false);
|
||||
return (filename_without_ext, None, false);
|
||||
}
|
||||
|
||||
// Only do the TMDb API stuff if it's not preprocessed
|
||||
|
@ -113,7 +115,7 @@ pub async fn process_file(
|
|||
if let Some(pos) = directors_text.rfind(',') {
|
||||
directors_text.replace_range(pos..pos + 2, " and ");
|
||||
}
|
||||
movie_details.director = directors_text;
|
||||
movie_details.director = Some(directors_text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -124,7 +126,7 @@ pub async fn process_file(
|
|||
// If nothing is found, skip
|
||||
if movie_list.is_empty() {
|
||||
eprintln!(" Could not find any entries matching {file_base}!");
|
||||
return (filename_without_ext, String::new(), true);
|
||||
return (filename_without_ext, None, true);
|
||||
}
|
||||
|
||||
// Choose from the possible entries
|
||||
|
@ -141,7 +143,7 @@ pub async fn process_file(
|
|||
error,
|
||||
InquireError::OperationCanceled | InquireError::OperationInterrupted
|
||||
);
|
||||
return (filename_without_ext, String::new(), flag);
|
||||
return (filename_without_ext, None, flag);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -196,7 +198,7 @@ pub async fn process_file(
|
|||
}
|
||||
}
|
||||
}
|
||||
(filename_without_ext, new_name_base, true)
|
||||
(filename_without_ext, Some(new_name_base), true)
|
||||
}
|
||||
|
||||
// Function to process the passed arguments
|
||||
|
|
40
src/main.rs
40
src/main.rs
|
@ -74,10 +74,6 @@ async fn main() {
|
|||
)
|
||||
.await;
|
||||
|
||||
// if movie_name_temp.is_empty() {
|
||||
// continue;
|
||||
// }
|
||||
|
||||
if add_to_list {
|
||||
movie_list.insert(filename_without_ext, movie_name_temp);
|
||||
}
|
||||
|
@ -90,22 +86,30 @@ async fn main() {
|
|||
if movie_list.len() == 1 {
|
||||
let entry_clean = entry.trim_end_matches('/');
|
||||
let movie_name = movie_list.into_values().next().unwrap();
|
||||
// If the file was ignored, exit
|
||||
if movie_name.is_empty() {
|
||||
eprintln!("Not renaming directory as only movie was skipped.");
|
||||
continue;
|
||||
}
|
||||
|
||||
if entry_clean == movie_name {
|
||||
println!("[directory] '{entry_clean}' already has correct name.");
|
||||
} else {
|
||||
println!("[directory] '{entry_clean}' -> '{movie_name}'");
|
||||
if !settings["dry_run"] {
|
||||
if !Path::new(movie_name.as_str()).is_dir() {
|
||||
fs::rename(entry, movie_name)
|
||||
.expect("Unable to rename directory!");
|
||||
// If the file was ignored, exit
|
||||
match movie_name {
|
||||
None => {
|
||||
eprintln!("Not renaming directory as only movie was skipped.");
|
||||
}
|
||||
|
||||
Some(name) => {
|
||||
if entry_clean == name {
|
||||
println!(
|
||||
"[directory] '{entry_clean}' already has correct name."
|
||||
);
|
||||
} else {
|
||||
eprintln!("Destination directory already exists, skipping...");
|
||||
println!("[directory] '{entry_clean}' -> '{name}'",);
|
||||
if !settings["dry_run"] {
|
||||
if !Path::new(name.as_str()).is_dir() {
|
||||
fs::rename(entry, name)
|
||||
.expect("Unable to rename directory!");
|
||||
} else {
|
||||
eprintln!(
|
||||
"Destination directory already exists, skipping..."
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,8 +5,8 @@ use tmdb_api::movie::MovieShort;
|
|||
pub struct MovieEntry {
|
||||
pub title: String,
|
||||
pub id: u64,
|
||||
pub director: String,
|
||||
pub year: String,
|
||||
pub director: Option<String>,
|
||||
pub year: Option<String>,
|
||||
pub language: String,
|
||||
}
|
||||
|
||||
|
@ -16,39 +16,38 @@ impl MovieEntry {
|
|||
MovieEntry {
|
||||
title: movie.inner.title,
|
||||
id: movie.inner.id,
|
||||
director: String::from("N/A"),
|
||||
year: match movie.inner.release_date {
|
||||
Some(date) => date.format("%Y").to_string(),
|
||||
_ => String::from("N/A"),
|
||||
},
|
||||
director: None,
|
||||
year: movie
|
||||
.inner
|
||||
.release_date
|
||||
.map(|date| date.format("%Y").to_string()),
|
||||
language: get_long_lang(movie.inner.original_language.as_str()),
|
||||
}
|
||||
}
|
||||
|
||||
// Generate desired filename from movie entry
|
||||
pub fn rename_format(&self, mut format: String) -> String {
|
||||
const PATTERN: &str = "^~#%$*+={}?@'`/\\\"><|:&!";
|
||||
// Try to sanitize the title to avoid some characters
|
||||
let mut title = self.title.clone();
|
||||
title.retain(|c| !PATTERN.contains(c));
|
||||
title = sanitize(title);
|
||||
title.truncate(159);
|
||||
format = format.replace("{title}", title.as_str());
|
||||
|
||||
if self.year != "N/A" {
|
||||
format = format.replace("{year}", self.year.as_str());
|
||||
} else {
|
||||
format = format.replace("{year}", "");
|
||||
}
|
||||
format = match &self.year {
|
||||
Some(year) => format.replace("{year}", year.as_str()),
|
||||
None => format.replace("{year}", ""),
|
||||
};
|
||||
|
||||
if self.director.as_str() != "N/A" {
|
||||
// Try to sanitize the director's name to avoid some characters
|
||||
let mut director = self.director.clone();
|
||||
director.retain(|c| !PATTERN.contains(c));
|
||||
director.truncate(63);
|
||||
format = format.replace("{director}", director.as_str());
|
||||
} else {
|
||||
format = format.replace("{director}", "");
|
||||
}
|
||||
format = match &self.director {
|
||||
Some(name) => {
|
||||
// Try to sanitize the director's name to avoid some characters
|
||||
let mut director = name.clone();
|
||||
director = sanitize(director);
|
||||
director.truncate(63);
|
||||
format.replace("{director}", director.as_str())
|
||||
}
|
||||
None => format.replace("{director}", ""),
|
||||
};
|
||||
|
||||
// Try to clean extra spaces and such
|
||||
format = format.trim_matches(|c| "- ".contains(c)).to_string();
|
||||
|
@ -65,12 +64,12 @@ impl fmt::Display for MovieEntry {
|
|||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
let mut buffer = String::new();
|
||||
buffer.push_str(&format!("{} ", self.title));
|
||||
buffer.push_str(&format!("({}), ", self.year));
|
||||
buffer.push_str(&format!("({:?}), ", self.year));
|
||||
buffer.push_str(&format!(
|
||||
"Language: {}, ",
|
||||
get_long_lang(self.language.as_str())
|
||||
));
|
||||
buffer.push_str(&format!("Directed by: {}, ", self.director));
|
||||
buffer.push_str(&format!("Directed by: {:?}, ", self.director));
|
||||
buffer.push_str(&format!("TMDB ID: {}", self.id));
|
||||
// buffer.push_str(&format!("Synopsis: {}", self.overview));
|
||||
write!(f, "{buffer}")
|
||||
|
@ -118,3 +117,15 @@ pub fn get_long_lang(short: &str) -> String {
|
|||
};
|
||||
String::from(long)
|
||||
}
|
||||
|
||||
// Sanitize filename so that there are no errors while
|
||||
// creating a file/directory
|
||||
fn sanitize(input: String) -> String {
|
||||
const AVOID: &str = "^~*+=`/\\\"><|";
|
||||
|
||||
let mut out = input;
|
||||
out.retain(|c| !AVOID.contains(c));
|
||||
out = out.replace(':', "∶");
|
||||
out = out.replace('?', "﹖");
|
||||
out
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue