new: Reuse same name for subtitle files and such

This commit is contained in:
Sayantan Santra 2023-05-21 20:39:38 -05:00
parent 4d04f51251
commit e9314ccdda
Signed by: SinTan1729
GPG key ID: EB3E68BFBA25C85F
2 changed files with 135 additions and 100 deletions

View file

@ -21,7 +21,9 @@ pub async fn process_file(
tmdb: &Client, tmdb: &Client,
pattern: &str, pattern: &str,
dry_run: bool, dry_run: bool,
) -> (String, bool) { movie_list: Option<&HashMap<String, String>>,
) -> (String, String, bool) {
// The last bool tells whether the entry should be added to the movie_list or not
// 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());
@ -35,6 +37,34 @@ pub async fn process_file(
} }
} }
// Split the filename into parts for a couple of checks and some later use
let filename_parts: Vec<&str> = filename.rsplit('.').collect();
let filename_without_ext = if filename_parts.len() >= 3 && filename_parts[1].len() == 2 {
filename.rsplitn(3, '.').last().unwrap().to_string()
} else {
filename.rsplit_once('.').unwrap().0.to_string()
};
// Check if the filename (without extension) has already been processed
// If yes, we'll use the older results
let mut preprocessed = false;
let mut new_name_base = match movie_list {
None => String::new(),
Some(list) => {
if list.contains_key(&filename_without_ext) {
preprocessed = true;
list[&filename_without_ext].clone()
} else {
String::new()
}
}
};
// Check if it should be ignored
if preprocessed && new_name_base.is_empty() {
return (filename_without_ext, "".to_string(), false);
}
// Parse the filename for metadata // Parse the filename for metadata
let metadata = Metadata::from(file_base.as_str()).expect(" Could not parse filename!"); let metadata = Metadata::from(file_base.as_str()).expect(" Could not parse filename!");
@ -44,9 +74,11 @@ pub async fn process_file(
println!(" Processing {}...", file_base); println!(" Processing {}...", file_base);
} else { } else {
println!(" Ignoring {}...", file_base); println!(" Ignoring {}...", file_base);
return ("n/a".to_string(), false); return (filename_without_ext, "".to_string(), false);
} }
// Only do the TMDb API stuff if it's not preprocessed
if !preprocessed {
// Search using the TMDb API // Search using the TMDb API
let year = metadata.year().map(|y| y as u16); let year = metadata.year().map(|y| y as u16);
let search = MovieSearch::new(metadata.title().to_string()).with_year(year); let search = MovieSearch::new(metadata.title().to_string()).with_year(year);
@ -91,7 +123,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 ("".to_string(), true); return (filename_without_ext, "".to_string(), true);
} }
// Choose from the possible entries // Choose from the possible entries
@ -104,15 +136,13 @@ pub async fn process_file(
Ok(movie) => movie, Ok(movie) => movie,
Err(error) => { Err(error) => {
println!(" {error}"); println!(" {error}");
return ("".to_string(), true); return (filename_without_ext, "".to_string(), false);
} }
}; };
// Handle the case for subtitle files // Handle the case for subtitle files
let mut is_subtitle = false;
if ["srt", "ssa"].contains(&extension.as_str()) { if ["srt", "ssa"].contains(&extension.as_str()) {
// Try to detect if there's already language info in the filename, else ask user to choose // Try to detect if there's already language info in the filename, else ask user to choose
let filename_parts: Vec<&str> = filename.rsplit('.').collect();
if filename_parts.len() >= 3 && filename_parts[1].len() == 2 { if filename_parts.len() >= 3 && filename_parts[1].len() == 2 {
println!( println!(
" Keeping language {} as detected in the subtitle file's extension...", " Keeping language {} as detected in the subtitle file's extension...",
@ -129,11 +159,13 @@ pub async fn process_file(
extension = format!("{}.{}", lang_choice.short, extension); extension = format!("{}.{}", lang_choice.short, extension);
} }
} }
is_subtitle = true;
} }
// Create the new name // Create the new name
let new_name_base = choice.rename_format(pattern.to_string()); new_name_base = choice.rename_format(pattern.to_string());
}
// Add extension and stuff to the new name
let mut new_name_with_ext = new_name_base.clone(); let mut new_name_with_ext = new_name_base.clone();
if !extension.is_empty() { if !extension.is_empty() {
new_name_with_ext = format!("{}.{}", new_name_with_ext, extension); new_name_with_ext = format!("{}.{}", new_name_with_ext, extension);
@ -157,7 +189,7 @@ pub async fn process_file(
} }
} }
} }
(new_name_base, is_subtitle) (filename_without_ext, new_name_base, true)
} }
// Function to process the passed arguments // Function to process the passed arguments

View file

@ -1,5 +1,5 @@
use load_file::{self, load_str}; use load_file::{self, load_str};
use std::{env, fs, path::Path, process::exit}; use std::{collections::HashMap, env, fs, path::Path, process::exit};
use tmdb_api::Client; use tmdb_api::Client;
// Import all the modules // Import all the modules
@ -43,13 +43,12 @@ async fn main() {
// Iterate over entries // Iterate over entries
for entry in entries { for entry in entries {
// Check if the file/directory exists on disk and run necessary commands // Check if the file/directory exists on disk and run necessary commands
// TODO: Detect subtitle files with same name/metadata and process them automatically without repeated input
match settings["directory"] { match settings["directory"] {
// Normal file // Normal file
false => { false => {
if Path::new(entry.as_str()).is_file() { if Path::new(entry.as_str()).is_file() {
// Process the filename for movie entries // Process the filename for movie entries
process_file(&entry, &tmdb, pattern, settings["dry_run"]).await; process_file(&entry, &tmdb, pattern, settings["dry_run"], None).await;
} else { } else {
eprintln!("The file {} wasn't found on disk, skipping...", entry); eprintln!("The file {} wasn't found on disk, skipping...", entry);
continue; continue;
@ -59,26 +58,28 @@ async fn main() {
true => { true => {
if Path::new(entry.as_str()).is_dir() { if Path::new(entry.as_str()).is_dir() {
println!("Processing files inside the directory {}...", entry); println!("Processing files inside the directory {}...", entry);
let mut movie_count = 0; let mut movie_list = HashMap::new();
let mut movie_name = String::new();
if let Ok(files_in_dir) = fs::read_dir(entry.as_str()) { if let Ok(files_in_dir) = fs::read_dir(entry.as_str()) {
for file in files_in_dir { for file in files_in_dir {
if file.is_ok() { if file.is_ok() {
let (movie_name_temp, is_subtitle) = process_file( let filename = file.unwrap().path().display().to_string();
&format!("{}", file.unwrap().path().display()), let (filename_without_ext, movie_name_temp, add_to_list) =
process_file(
&filename,
&tmdb, &tmdb,
pattern, pattern,
settings["dry_run"], settings["dry_run"],
Some(&movie_list),
) )
.await; .await;
if movie_name_temp == *"n/a" { // if movie_name_temp.is_empty() {
continue; // continue;
} // }
if !is_subtitle { if add_to_list {
movie_count += 1; movie_list.insert(filename_without_ext, movie_name_temp);
movie_name = movie_name_temp;
} }
} }
} }
@ -86,8 +87,10 @@ async fn main() {
eprintln!("There was an error accessing the directory {}!", entry); eprintln!("There was an error accessing the directory {}!", entry);
continue; continue;
} }
if movie_count == 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();
if entry_clean == movie_name { if entry_clean == movie_name {
println!("[directory] '{}' already has correct name.", entry_clean); println!("[directory] '{}' already has correct name.", entry_clean);
} else { } else {