From cd1c6e953d0f2e1ee6994e659c29a3e66b2a1291 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rafa=C5=82=20Mikrut?= Date: Sat, 17 Feb 2024 12:16:31 +0100 Subject: [PATCH] Ad --- krokiet/src/connect_scan.rs | 129 ++++++++++++++++++++-------- krokiet/src/set_initial_gui_info.rs | 26 +++++- krokiet/src/settings.rs | 32 +++---- krokiet/ui/settings.slint | 4 +- krokiet/ui/tool_settings.slint | 4 +- 5 files changed, 138 insertions(+), 57 deletions(-) diff --git a/krokiet/src/connect_scan.rs b/krokiet/src/connect_scan.rs index 85d6b96..ac1e01a 100644 --- a/krokiet/src/connect_scan.rs +++ b/krokiet/src/connect_scan.rs @@ -4,8 +4,8 @@ use std::thread; use chrono::NaiveDateTime; use crossbeam_channel::{Receiver, Sender}; use czkawka_core::bad_extensions::{BadExtensions, BadFileEntry}; -use czkawka_core::big_file::BigFile; -use czkawka_core::broken_files::{BrokenEntry, BrokenFiles}; +use czkawka_core::big_file::{BigFile, SearchMode}; +use czkawka_core::broken_files::{BrokenEntry, BrokenFiles, CheckedTypes}; use humansize::{format_size, BINARY}; use rayon::prelude::*; use slint::{ComponentHandle, ModelRc, SharedString, VecModel, Weak}; @@ -18,14 +18,18 @@ use czkawka_core::duplicate::{DuplicateEntry, DuplicateFinder}; use czkawka_core::empty_files::EmptyFiles; use czkawka_core::empty_folder::{EmptyFolder, FolderEntry}; use czkawka_core::invalid_symlinks::{InvalidSymlinks, SymlinksFileEntry}; -use czkawka_core::same_music::{MusicEntry, SameMusic}; +use czkawka_core::same_music::{MusicEntry, MusicSimilarity, SameMusic}; use czkawka_core::similar_images; use czkawka_core::similar_images::{ImagesEntry, SimilarImages}; use czkawka_core::similar_videos::{SimilarVideos, VideosEntry}; use czkawka_core::temporary::{Temporary, TemporaryFileEntry}; use crate::common::split_u64_into_i32s; -use crate::settings::{collect_settings, SettingsCustom, ALLOWED_HASH_TYPE_VALUES, ALLOWED_RESIZE_ALGORITHM_VALUES}; +use crate::settings::{ + collect_settings, get_audio_check_type_idx, get_biggest_item_idx, get_duplicates_check_method_idx, get_duplicates_hash_type_idx, get_image_hash_alg_idx, + get_resize_algorithm_idx, SettingsCustom, ALLOWED_AUDIO_CHECK_TYPE_VALUES, ALLOWED_BIG_FILE_SIZE_VALUES, ALLOWED_DUPLICATES_CHECK_METHOD_VALUES, + ALLOWED_DUPLICATES_HASH_TYPE_VALUES, ALLOWED_IMAGE_HASH_ALG_VALUES, ALLOWED_RESIZE_ALGORITHM_VALUES, +}; use crate::{CurrentTab, GuiState, MainListModel, MainWindow, ProgressToSend}; pub fn connect_scan_button(app: &MainWindow, progress_sender: Sender, stop_receiver: Receiver<()>) { @@ -91,16 +95,17 @@ fn scan_duplicates(a: Weak, progress_sender: Sender, s .spawn(move || { let mut finder = DuplicateFinder::new(); set_common_settings(&mut finder, &custom_settings); - // TODO Fill rest of settings finder.set_check_method(CheckingMethod::Hash); - // finder.set_minimal_cache_file_size(loaded_commons.minimal_cache_file_size); - // finder.set_minimal_prehash_cache_file_size(minimal_prehash_cache_file_size); - // finder.set_check_method(check_method); - // finder.set_hash_type(hash_type); - // finder.set_ignore_hard_links(loaded_commons.hide_hard_links); - // finder.set_use_prehash_cache(use_prehash_cache); - // finder.set_delete_outdated_cache(delete_outdated_cache); - // finder.set_case_sensitive_name_comparison(case_sensitive_name_comparison); + finder.set_minimal_cache_file_size(custom_settings.duplicate_minimal_hash_cache_size as u64); + finder.set_minimal_prehash_cache_file_size(custom_settings.duplicate_minimal_prehash_cache_size as u64); + let check_method = ALLOWED_DUPLICATES_CHECK_METHOD_VALUES[get_duplicates_check_method_idx(&custom_settings.duplicates_sub_check_method).unwrap()].2; + finder.set_check_method(check_method); + let hash_type = ALLOWED_DUPLICATES_HASH_TYPE_VALUES[get_duplicates_hash_type_idx(&custom_settings.duplicates_sub_available_hash_type).unwrap()].2; + finder.set_hash_type(hash_type); + // finder.set_ignore_hard_links(custom_settings.ignore); // TODO + finder.set_use_prehash_cache(custom_settings.duplicate_use_prehash); + finder.set_delete_outdated_cache(custom_settings.duplicate_delete_outdated_entries); + // finder.set_case_sensitive_name_comparison(custom_settings.); // TODO finder.find_duplicates(Some(&stop_receiver), Some(&progress_sender)); let messages = finder.get_text_messages().create_messages_text(); @@ -240,15 +245,15 @@ fn scan_big_files(a: Weak, progress_sender: Sender, st .spawn(move || { let mut finder = BigFile::new(); set_common_settings(&mut finder, &custom_settings); - // finder.set_number_of_files_to_check(numbers_of_files_to_check); - // finder.set_search_mode(sett); + finder.set_number_of_files_to_check(custom_settings.biggest_files_sub_number_of_files as usize); + let big_files_mode = ALLOWED_BIG_FILE_SIZE_VALUES[get_biggest_item_idx(&custom_settings.biggest_files_sub_method).unwrap()].2; + finder.set_search_mode(big_files_mode); finder.find_big_files(Some(&stop_receiver), Some(&progress_sender)); let mut vector = finder.get_big_files().clone(); let messages = finder.get_text_messages().create_messages_text(); - // TODO - if biggest files - if true { + if big_files_mode == SearchMode::BiggestFiles { vector.par_sort_unstable_by_key(|fe| u64::MAX - fe.size); } else { vector.par_sort_unstable_by_key(|fe| fe.size); @@ -338,22 +343,16 @@ fn scan_similar_images(a: Weak, progress_sender: Sender, progress_sender: Sender, progress_sender: Sender let mut finder = SameMusic::new(); set_common_settings(&mut finder, &custom_settings); - // TODO set rest of settings + let mut music_similarity: MusicSimilarity = MusicSimilarity::NONE; + if custom_settings.similar_music_sub_title { + music_similarity |= MusicSimilarity::TRACK_TITLE; + } + if custom_settings.similar_music_sub_artist { + music_similarity |= MusicSimilarity::TRACK_ARTIST; + } + if custom_settings.similar_music_sub_bitrate { + music_similarity |= MusicSimilarity::BITRATE; + } + if custom_settings.similar_music_sub_length { + music_similarity |= MusicSimilarity::LENGTH; + } + if custom_settings.similar_music_sub_year { + music_similarity |= MusicSimilarity::YEAR; + } + if custom_settings.similar_music_sub_genre { + music_similarity |= MusicSimilarity::GENRE; + } + + if music_similarity == MusicSimilarity::NONE { + a.upgrade_in_event_loop(move |app| { + app.set_text_summary_text("Cannot find similar music files without any similarity method selected.".into()); + }) + .unwrap(); + return Ok(()); + } + + finder.set_music_similarity(music_similarity); + // finder.set_maximum_difference(custom_settings.mus); // TODO + // finder.set_minimum_segment_duration(minimum_segment_duration); // TODO + let audio_check_type = ALLOWED_AUDIO_CHECK_TYPE_VALUES[get_audio_check_type_idx(&custom_settings.similar_music_sub_audio_check_type).unwrap()].2; + finder.set_check_type(audio_check_type); + finder.set_approximate_comparison(custom_settings.similar_music_sub_approximate_comparison); + finder.find_same_music(Some(&stop_receiver), Some(&progress_sender)); let messages = finder.get_text_messages().create_messages_text(); @@ -564,7 +600,7 @@ fn scan_invalid_symlinks(a: Weak, progress_sender: Sender, progress_sender: Sender, progress_sender: Sender, .spawn(move || { let mut finder = BrokenFiles::new(); set_common_settings(&mut finder, &custom_settings); + + let mut checked_types: CheckedTypes = CheckedTypes::NONE; + if custom_settings.broken_files_sub_audio { + checked_types |= CheckedTypes::AUDIO; + } + if custom_settings.broken_files_sub_pdf { + checked_types |= CheckedTypes::PDF; + } + if custom_settings.broken_files_sub_image { + checked_types |= CheckedTypes::IMAGE; + } + if custom_settings.broken_files_sub_archive { + checked_types |= CheckedTypes::ARCHIVE; + } + + if checked_types == CheckedTypes::NONE { + a.upgrade_in_event_loop(move |app| { + app.set_text_summary_text("Cannot find broken files without any file type selected.".into()); + }) + .unwrap(); + return Ok(()); + } + + finder.set_checked_types(checked_types); finder.find_broken_files(Some(&stop_receiver), Some(&progress_sender)); let mut vector = finder.get_broken_files().clone(); diff --git a/krokiet/src/set_initial_gui_info.rs b/krokiet/src/set_initial_gui_info.rs index 5543fe9..f2a1585 100644 --- a/krokiet/src/set_initial_gui_info.rs +++ b/krokiet/src/set_initial_gui_info.rs @@ -1,12 +1,17 @@ +use czkawka_core::big_file::SearchMode; +use image::imageops::FilterType; +use image_hasher::HashAlg; use slint::{ComponentHandle, SharedString, VecModel}; use czkawka_core::common::get_all_available_threads; -use crate::settings::{ALLOWED_HASH_SIZE_VALUES, ALLOWED_HASH_TYPE_VALUES, ALLOWED_RESIZE_ALGORITHM_VALUES}; +use crate::settings::{ + ALLOWED_BIG_FILE_SIZE_VALUES, ALLOWED_DUPLICATES_CHECK_METHOD_VALUES, ALLOWED_DUPLICATES_HASH_TYPE_VALUES, ALLOWED_HASH_SIZE_VALUES, ALLOWED_IMAGE_HASH_ALG_VALUES, + ALLOWED_RESIZE_ALGORITHM_VALUES, +}; use crate::{GuiState, MainWindow, Settings}; // Some info needs to be send to gui at the start like available thread number in OS. -// pub fn set_initial_gui_infos(app: &MainWindow) { let threads = get_all_available_threads(); let settings = app.global::(); @@ -20,7 +25,19 @@ pub fn set_initial_gui_infos(app: &MainWindow) { .iter() .map(|(_settings_key, gui_name, _filter_type)| (*gui_name).into()) .collect::>(); - let available_hash_type: Vec = ALLOWED_HASH_TYPE_VALUES + let available_hash_type: Vec = ALLOWED_IMAGE_HASH_ALG_VALUES + .iter() + .map(|(_settings_key, gui_name, _hash_type)| (*gui_name).into()) + .collect::>(); + let available_big_file_search_mode: Vec = ALLOWED_BIG_FILE_SIZE_VALUES + .iter() + .map(|(_settings_key, gui_name, _search_mode)| (*gui_name).into()) + .collect::>(); + let available_duplicates_check_method: Vec = ALLOWED_DUPLICATES_CHECK_METHOD_VALUES + .iter() + .map(|(_settings_key, gui_name, _checking_method)| (*gui_name).into()) + .collect::>(); + let available_duplicates_hash_type: Vec = ALLOWED_DUPLICATES_HASH_TYPE_VALUES .iter() .map(|(_settings_key, gui_name, _hash_type)| (*gui_name).into()) .collect::>(); @@ -28,4 +45,7 @@ pub fn set_initial_gui_infos(app: &MainWindow) { settings.set_similar_images_sub_available_hash_size(VecModel::from_slice(&available_hash_size)); settings.set_similar_images_sub_available_resize_algorithm(VecModel::from_slice(&available_resize_algorithm)); settings.set_similar_images_sub_available_hash_type(VecModel::from_slice(&available_hash_type)); + settings.set_biggest_files_sub_method(VecModel::from_slice(&available_big_file_search_mode)); + settings.set_duplicates_sub_check_method(VecModel::from_slice(&available_duplicates_check_method)); + settings.set_duplicates_sub_available_hash_type(VecModel::from_slice(&available_duplicates_hash_type)); } diff --git a/krokiet/src/settings.rs b/krokiet/src/settings.rs index 9e07b9b..4172026 100644 --- a/krokiet/src/settings.rs +++ b/krokiet/src/settings.rs @@ -39,7 +39,7 @@ pub const ALLOWED_RESIZE_ALGORITHM_VALUES: &[(&str, &str, FilterType)] = &[ ("nearest", "Nearest", FilterType::Nearest), ]; -pub const ALLOWED_HASH_TYPE_VALUES: &[(&str, &str, HashAlg)] = &[ +pub const ALLOWED_IMAGE_HASH_ALG_VALUES: &[(&str, &str, HashAlg)] = &[ ("mean", "Mean", HashAlg::Mean), ("gradient", "Gradient", HashAlg::Gradient), ("blockhash", "BlockHash", HashAlg::Blockhash), @@ -118,7 +118,7 @@ pub struct SettingsCustom { #[serde(default = "default_sub_hash_size")] pub similar_images_sub_hash_size: u8, #[serde(default = "default_hash_type")] - pub similar_images_sub_hash_type: String, + pub similar_images_sub_hash_alg: String, #[serde(default = "default_resize_algorithm")] pub similar_images_sub_resize_algorithm: String, #[serde(default)] @@ -450,14 +450,14 @@ pub fn set_settings_to_gui(app: &MainWindow, custom_settings: &SettingsCustom) { settings.set_similar_images_sub_hash_size_value(ALLOWED_HASH_SIZE_VALUES[similar_images_sub_hash_size_idx].1.to_string().into()); // TODO all items with _value are not necessary, but due bug in slint are required, because combobox is not updated properly - let similar_images_sub_hash_type_idx = get_hash_type_idx(&custom_settings.similar_images_sub_hash_type).unwrap_or_else(|| { + let similar_images_sub_hash_alg_idx = get_image_hash_alg_idx(&custom_settings.similar_images_sub_hash_alg).unwrap_or_else(|| { warn!( "Value of hash type \"{}\" is invalid, setting it to default value", - custom_settings.similar_images_sub_hash_type + custom_settings.similar_images_sub_hash_alg ); 0 }); - settings.set_similar_images_sub_hash_type_index(similar_images_sub_hash_type_idx as i32); + settings.set_similar_images_sub_hash_alg_index(similar_images_sub_hash_alg_idx as i32); let similar_images_sub_resize_algorithm_idx = get_resize_algorithm_idx(&custom_settings.similar_images_sub_resize_algorithm).unwrap_or_else(|| { warn!( @@ -581,8 +581,8 @@ pub fn collect_settings(app: &MainWindow) -> SettingsCustom { let similar_images_sub_hash_size_idx = settings.get_similar_images_sub_hash_size_index(); let similar_images_sub_hash_size = ALLOWED_HASH_SIZE_VALUES[similar_images_sub_hash_size_idx as usize].0; - let similar_images_sub_hash_type_idx = settings.get_similar_images_sub_hash_type_index(); - let similar_images_sub_hash_type = ALLOWED_HASH_TYPE_VALUES[similar_images_sub_hash_type_idx as usize].0.to_string(); + let similar_images_sub_hash_alg_idx = settings.get_similar_images_sub_hash_alg_index(); + let similar_images_sub_hash_alg = ALLOWED_IMAGE_HASH_ALG_VALUES[similar_images_sub_hash_alg_idx as usize].0.to_string(); let similar_images_sub_resize_algorithm_idx = settings.get_similar_images_sub_resize_algorithm_index(); let similar_images_sub_resize_algorithm = ALLOWED_RESIZE_ALGORITHM_VALUES[similar_images_sub_resize_algorithm_idx as usize].0.to_string(); let similar_images_sub_ignore_same_size = settings.get_similar_images_sub_ignore_same_size(); @@ -641,7 +641,7 @@ pub fn collect_settings(app: &MainWindow) -> SettingsCustom { similar_videos_delete_outdated_entries, similar_music_delete_outdated_entries, similar_images_sub_hash_size, - similar_images_sub_hash_type, + similar_images_sub_hash_alg, similar_images_sub_resize_algorithm, similar_images_sub_ignore_same_size, similar_images_sub_similarity, @@ -755,7 +755,7 @@ pub fn default_resize_algorithm() -> String { ALLOWED_RESIZE_ALGORITHM_VALUES[0].0.to_string() } pub fn default_hash_type() -> String { - ALLOWED_HASH_TYPE_VALUES[0].0.to_string() + ALLOWED_IMAGE_HASH_ALG_VALUES[0].0.to_string() } pub fn default_sub_hash_size() -> u8 { DEFAULT_HASH_SIZE @@ -765,33 +765,33 @@ fn get_allowed_hash_size_idx(h_size: u8) -> Option { ALLOWED_HASH_SIZE_VALUES.iter().position(|(hash_size, _max_similarity)| *hash_size == h_size) } -fn get_hash_type_idx(string_hash_type: &str) -> Option { - ALLOWED_HASH_TYPE_VALUES +pub fn get_image_hash_alg_idx(string_hash_type: &str) -> Option { + ALLOWED_IMAGE_HASH_ALG_VALUES .iter() .position(|(settings_key, gui_name, _hash_type)| *settings_key == string_hash_type || *gui_name == string_hash_type) } -fn get_resize_algorithm_idx(string_resize_algorithm: &str) -> Option { +pub fn get_resize_algorithm_idx(string_resize_algorithm: &str) -> Option { ALLOWED_RESIZE_ALGORITHM_VALUES .iter() .position(|(settings_key, gui_name, _resize_alg)| *settings_key == string_resize_algorithm || *gui_name == string_resize_algorithm) } -fn get_biggest_item_idx(string_biggest_item: &str) -> Option { +pub fn get_biggest_item_idx(string_biggest_item: &str) -> Option { ALLOWED_BIG_FILE_SIZE_VALUES .iter() .position(|(settings_key, gui_name, _search_mode)| *settings_key == string_biggest_item || *gui_name == string_biggest_item) } -fn get_duplicates_check_method_idx(string_duplicates_check_method: &str) -> Option { +pub fn get_duplicates_check_method_idx(string_duplicates_check_method: &str) -> Option { ALLOWED_DUPLICATES_CHECK_METHOD_VALUES .iter() .position(|(settings_key, gui_name, _check_method)| *settings_key == string_duplicates_check_method || *gui_name == string_duplicates_check_method) } -fn get_duplicates_hash_type_idx(string_duplicates_hash_type: &str) -> Option { +pub fn get_duplicates_hash_type_idx(string_duplicates_hash_type: &str) -> Option { ALLOWED_DUPLICATES_HASH_TYPE_VALUES .iter() .position(|(settings_key, gui_name, _hash_type)| *settings_key == string_duplicates_hash_type || *gui_name == string_duplicates_hash_type) } -fn get_audio_check_type_idx(string_audio_check_type: &str) -> Option { +pub fn get_audio_check_type_idx(string_audio_check_type: &str) -> Option { ALLOWED_AUDIO_CHECK_TYPE_VALUES .iter() .position(|(settings_key, gui_name, _audio_check_type)| *settings_key == string_audio_check_type || *gui_name == string_audio_check_type) diff --git a/krokiet/ui/settings.slint b/krokiet/ui/settings.slint index d004a64..8ec6186 100644 --- a/krokiet/ui/settings.slint +++ b/krokiet/ui/settings.slint @@ -48,8 +48,8 @@ export global Settings { in-out property similar_images_sub_resize_algorithm_index: 0; in-out property similar_images_sub_resize_algorithm_value: "Lanczos3"; in-out property <[string]> similar_images_sub_available_hash_type: ["Gradient", "Mean", "VertGradient", "BlockHash", "DoubleGradient"]; - in-out property similar_images_sub_hash_type_index: 0; - in-out property similar_images_sub_hash_type_value: "Gradient"; + in-out property similar_images_sub_hash_alg_index: 0; + in-out property similar_images_sub_hash_alg_value: "Gradient"; in-out property similar_images_sub_max_similarity: 40; in-out property similar_images_sub_current_similarity: 20; in-out property similar_images_sub_ignore_same_size; diff --git a/krokiet/ui/tool_settings.slint b/krokiet/ui/tool_settings.slint index f527705..4fd9e71 100644 --- a/krokiet/ui/tool_settings.slint +++ b/krokiet/ui/tool_settings.slint @@ -85,8 +85,8 @@ export component ToolSettings { ComboBoxWrapper { text: "Hash type"; model: Settings.similar_images_sub_available_hash_type; - current_index <=> Settings.similar_images_sub_hash_type_index; - current_value <=> Settings.similar_images_sub_hash_type_value; + current_index <=> Settings.similar_images_sub_hash_alg_index; + current_value <=> Settings.similar_images_sub_hash_alg_value; } CheckBoxWrapper { text: "Ignore same size";