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,
|
tmdb: &Client,
|
||||||
pattern: &str,
|
pattern: &str,
|
||||||
dry_run: bool,
|
dry_run: bool,
|
||||||
movie_list: Option<&HashMap<String, String>>,
|
movie_list: Option<&HashMap<String, Option<String>>>,
|
||||||
) -> (String, String, bool) {
|
|
||||||
// The last bool tells whether the entry should be added to the movie_list or not
|
// 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
|
// Set RenderConfig for the menu items
|
||||||
inquire::set_global_render_config(get_render_config());
|
inquire::set_global_render_config(get_render_config());
|
||||||
|
|
||||||
|
@ -53,7 +55,7 @@ pub async fn process_file(
|
||||||
Some(list) => {
|
Some(list) => {
|
||||||
if list.contains_key(&filename_without_ext) {
|
if list.contains_key(&filename_without_ext) {
|
||||||
preprocessed = true;
|
preprocessed = true;
|
||||||
list[&filename_without_ext].clone()
|
list[&filename_without_ext].clone().unwrap_or_default()
|
||||||
} else {
|
} else {
|
||||||
String::new()
|
String::new()
|
||||||
}
|
}
|
||||||
|
@ -63,7 +65,7 @@ pub async fn process_file(
|
||||||
// Check if it should be ignored
|
// Check if it should be ignored
|
||||||
if preprocessed && new_name_base.is_empty() {
|
if preprocessed && new_name_base.is_empty() {
|
||||||
eprintln!(" Ignoring {file_base} as per previous choice for related files...");
|
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
|
// Parse the filename for metadata
|
||||||
|
@ -75,7 +77,7 @@ pub async fn process_file(
|
||||||
println!(" Processing {file_base}...");
|
println!(" Processing {file_base}...");
|
||||||
} else {
|
} else {
|
||||||
println!(" Ignoring {file_base}...");
|
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
|
// 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(',') {
|
if let Some(pos) = directors_text.rfind(',') {
|
||||||
directors_text.replace_range(pos..pos + 2, " and ");
|
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 nothing is found, skip
|
||||||
if movie_list.is_empty() {
|
if movie_list.is_empty() {
|
||||||
eprintln!(" Could not find any entries matching {file_base}!");
|
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
|
// Choose from the possible entries
|
||||||
|
@ -141,7 +143,7 @@ pub async fn process_file(
|
||||||
error,
|
error,
|
||||||
InquireError::OperationCanceled | InquireError::OperationInterrupted
|
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
|
// Function to process the passed arguments
|
||||||
|
|
40
src/main.rs
40
src/main.rs
|
@ -74,10 +74,6 @@ async fn main() {
|
||||||
)
|
)
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
// if movie_name_temp.is_empty() {
|
|
||||||
// continue;
|
|
||||||
// }
|
|
||||||
|
|
||||||
if add_to_list {
|
if add_to_list {
|
||||||
movie_list.insert(filename_without_ext, movie_name_temp);
|
movie_list.insert(filename_without_ext, movie_name_temp);
|
||||||
}
|
}
|
||||||
|
@ -90,22 +86,30 @@ async fn main() {
|
||||||
if movie_list.len() == 1 {
|
if movie_list.len() == 1 {
|
||||||
let entry_clean = entry.trim_end_matches('/');
|
let entry_clean = entry.trim_end_matches('/');
|
||||||
let movie_name = movie_list.into_values().next().unwrap();
|
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 {
|
// If the file was ignored, exit
|
||||||
println!("[directory] '{entry_clean}' already has correct name.");
|
match movie_name {
|
||||||
} else {
|
None => {
|
||||||
println!("[directory] '{entry_clean}' -> '{movie_name}'");
|
eprintln!("Not renaming directory as only movie was skipped.");
|
||||||
if !settings["dry_run"] {
|
}
|
||||||
if !Path::new(movie_name.as_str()).is_dir() {
|
|
||||||
fs::rename(entry, movie_name)
|
Some(name) => {
|
||||||
.expect("Unable to rename directory!");
|
if entry_clean == name {
|
||||||
|
println!(
|
||||||
|
"[directory] '{entry_clean}' already has correct name."
|
||||||
|
);
|
||||||
} else {
|
} 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 struct MovieEntry {
|
||||||
pub title: String,
|
pub title: String,
|
||||||
pub id: u64,
|
pub id: u64,
|
||||||
pub director: String,
|
pub director: Option<String>,
|
||||||
pub year: String,
|
pub year: Option<String>,
|
||||||
pub language: String,
|
pub language: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -16,39 +16,38 @@ impl MovieEntry {
|
||||||
MovieEntry {
|
MovieEntry {
|
||||||
title: movie.inner.title,
|
title: movie.inner.title,
|
||||||
id: movie.inner.id,
|
id: movie.inner.id,
|
||||||
director: String::from("N/A"),
|
director: None,
|
||||||
year: match movie.inner.release_date {
|
year: movie
|
||||||
Some(date) => date.format("%Y").to_string(),
|
.inner
|
||||||
_ => String::from("N/A"),
|
.release_date
|
||||||
},
|
.map(|date| date.format("%Y").to_string()),
|
||||||
language: get_long_lang(movie.inner.original_language.as_str()),
|
language: get_long_lang(movie.inner.original_language.as_str()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate desired filename from movie entry
|
// Generate desired filename from movie entry
|
||||||
pub fn rename_format(&self, mut format: String) -> String {
|
pub fn rename_format(&self, mut format: String) -> String {
|
||||||
const PATTERN: &str = "^~#%$*+={}?@'`/\\\"><|:&!";
|
|
||||||
// Try to sanitize the title to avoid some characters
|
// Try to sanitize the title to avoid some characters
|
||||||
let mut title = self.title.clone();
|
let mut title = self.title.clone();
|
||||||
title.retain(|c| !PATTERN.contains(c));
|
title = sanitize(title);
|
||||||
title.truncate(159);
|
title.truncate(159);
|
||||||
format = format.replace("{title}", title.as_str());
|
format = format.replace("{title}", title.as_str());
|
||||||
|
|
||||||
if self.year != "N/A" {
|
format = match &self.year {
|
||||||
format = format.replace("{year}", self.year.as_str());
|
Some(year) => format.replace("{year}", year.as_str()),
|
||||||
} else {
|
None => format.replace("{year}", ""),
|
||||||
format = format.replace("{year}", "");
|
};
|
||||||
}
|
|
||||||
|
|
||||||
if self.director.as_str() != "N/A" {
|
format = match &self.director {
|
||||||
// Try to sanitize the director's name to avoid some characters
|
Some(name) => {
|
||||||
let mut director = self.director.clone();
|
// Try to sanitize the director's name to avoid some characters
|
||||||
director.retain(|c| !PATTERN.contains(c));
|
let mut director = name.clone();
|
||||||
director.truncate(63);
|
director = sanitize(director);
|
||||||
format = format.replace("{director}", director.as_str());
|
director.truncate(63);
|
||||||
} else {
|
format.replace("{director}", director.as_str())
|
||||||
format = format.replace("{director}", "");
|
}
|
||||||
}
|
None => format.replace("{director}", ""),
|
||||||
|
};
|
||||||
|
|
||||||
// Try to clean extra spaces and such
|
// Try to clean extra spaces and such
|
||||||
format = format.trim_matches(|c| "- ".contains(c)).to_string();
|
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 {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
buffer.push_str(&format!("{} ", self.title));
|
buffer.push_str(&format!("{} ", self.title));
|
||||||
buffer.push_str(&format!("({}), ", self.year));
|
buffer.push_str(&format!("({:?}), ", self.year));
|
||||||
buffer.push_str(&format!(
|
buffer.push_str(&format!(
|
||||||
"Language: {}, ",
|
"Language: {}, ",
|
||||||
get_long_lang(self.language.as_str())
|
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!("TMDB ID: {}", self.id));
|
||||||
// buffer.push_str(&format!("Synopsis: {}", self.overview));
|
// buffer.push_str(&format!("Synopsis: {}", self.overview));
|
||||||
write!(f, "{buffer}")
|
write!(f, "{buffer}")
|
||||||
|
@ -118,3 +117,15 @@ pub fn get_long_lang(short: &str) -> String {
|
||||||
};
|
};
|
||||||
String::from(long)
|
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