diff --git a/package.json b/package.json index 01ad9e2..49a2dc4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "finalshelf", - "version": "0.3.0", + "version": "0.3.1", "scripts": { "ng": "ng", "start": "ng serve", @@ -46,4 +46,4 @@ "typescript": "~5.2.2", "typescript-eslint": "8.18.0" } -} +} \ No newline at end of file diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index a600e17..f057c5a 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -957,7 +957,7 @@ dependencies = [ [[package]] name = "finalshelf" -version = "0.3.0" +version = "0.3.1" dependencies = [ "chrono", "diesel", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index 90b84b4..212f37d 100644 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "finalshelf" -version = "0.3.0" +version = "0.3.1" description = "A Tauri App" authors = ["you"] edition = "2021" diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index ffe812a..056cc79 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -14,6 +14,8 @@ use commands::{ }; fn main() { + println!("Starting Tauri application..."); + tauri::Builder::default() .plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_shell::init()) diff --git a/src-tauri/src/scanner.rs b/src-tauri/src/scanner.rs index 00038a9..8f14131 100644 --- a/src-tauri/src/scanner.rs +++ b/src-tauri/src/scanner.rs @@ -5,7 +5,7 @@ use std::{ time::{Instant, SystemTime, UNIX_EPOCH}, }; -use chrono::{DateTime, NaiveDateTime}; +use chrono::{Date, DateTime, NaiveDateTime, Utc}; use id3::{Tag, TagLike}; use rusqlite::Result; use walkdir::WalkDir; @@ -15,7 +15,8 @@ use crate::{ services::{ absolute_paths_service::get_current_absolute_path, authors_service::{add_author, is_author_exists}, - books_service::{add_book, is_book_exists}, + // Added get_all_book_paths to the import + books_service::{add_book, get_all_book_paths, is_book_exists}, }, }; @@ -49,42 +50,70 @@ fn look_for_author_photo(path: &str, name: &str, base_path: &Path) -> String { look_for_cover(directory, base_path) } -fn system_time_to_naive_date_time(option_time: Option) -> Option { - option_time? - .duration_since(UNIX_EPOCH) - .ok() - .and_then(|duration| DateTime::from_timestamp(duration.as_secs() as i64, duration.subsec_nanos())) - .map(|datetime_utc| datetime_utc.naive_utc()) +fn system_time_to_naive_date_time( + create_time: Option, + edit_time: Option, +) -> Option { + let create_data_time = DateTime::::from(create_time?); + let edit_data_time = DateTime::::from(edit_time?); + + if create_data_time > edit_data_time { + Some(create_data_time.naive_utc()) + } else { + Some(edit_data_time.naive_utc()) + } } pub fn quick_scan() -> Result<(), String> { - let absolute_path = get_current_absolute_path(); + let absolute_path_obj = get_current_absolute_path(); let directory: String; - if let Some(absolute_path) = absolute_path { + if let Some(absolute_path) = absolute_path_obj { directory = absolute_path.absolute_path; } else { return Err("No path to scan".to_string()); } println!("Quick scan in {}", directory); - let mut processed_dirs = HashSet::new(); let start = Instant::now(); - let base_path = Path::new(&directory); + // Build the processed_dirs HashSet based on the absolute_path and file paths from the database. + let mut processed_dirs: HashSet = match get_all_book_paths() { + Ok(relative_paths) => relative_paths + .into_iter() + .filter_map(|relative_path| { + // Get the parent directory of the relative path + Path::new(&relative_path).parent().map(|p| { + // Construct the full absolute path and add it to the set + base_path.join(p).to_string_lossy().to_string() + }) + }) + .collect(), + Err(e) => { + eprintln!( + "Could not pre-populate processed directories from DB: {}. Starting fresh.", + e + ); + HashSet::new() + }, + }; + + println!("Pre-populated processed directories: {:?}", processed_dirs); + for entry in WalkDir::new(&directory).min_depth(1).into_iter().filter_map(Result::ok) { if let Some(mp3_path) = get_mp3_path(&entry) { if let Some(parent_path) = mp3_path.parent().and_then(Path::to_str) { - // Skip already processed directories + // Skip already processed directories. + // The set is now pre-populated with directories from the database. if !processed_dirs.insert(parent_path.to_string()) { continue; } - // Process the MP3 file + // Process the metadata of the mp3 file if let Ok(tag) = Tag::read_from_path(mp3_path) { - let file_create_date = fs::metadata(mp3_path) - .ok() - .and_then(|metadata| system_time_to_naive_date_time(metadata.created().ok())); + let file_create_date = fs::metadata(mp3_path).ok().and_then(|metadata| { + system_time_to_naive_date_time(metadata.created().ok(), metadata.modified().ok()) + }); process_metadata(&tag, parent_path, file_create_date, base_path, mp3_path); } diff --git a/src-tauri/src/services/books_service.rs b/src-tauri/src/services/books_service.rs index 84174fb..292f79d 100644 --- a/src-tauri/src/services/books_service.rs +++ b/src-tauri/src/services/books_service.rs @@ -195,3 +195,12 @@ pub fn get_books_by_score(limit: i64) -> Vec { .load::(conn) .expect("Error getting books by score") } + +pub fn get_all_book_paths() -> Result, diesel::result::Error> { + let conn = &mut establish_connection(); + + dsl::books + .select(dsl::relative_file_path) + .load::(conn) + .map_err(|e| e.into()) +} diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index a4a8546..35cb924 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -18,7 +18,7 @@ }, "productName": "finalshelf", "mainBinaryName": "finalshelf", - "version": "0.3.0", + "version": "0.3.1", "identifier": "com.finalshelf.app", "plugins": {}, "app": {