1
0
Fork 0
mirror of synced 2024-06-15 00:45:29 +12:00

Split functions in big file finder

This commit is contained in:
Rafał Mikrut 2023-05-01 17:48:12 +02:00
parent 7b1600bdaa
commit 31d8d937b1
4 changed files with 139 additions and 93 deletions

View file

@ -1,7 +1,7 @@
use std::collections::BTreeMap; use std::collections::BTreeMap;
use std::fs::{File, Metadata}; use std::fs::{DirEntry, File, Metadata};
use std::io::{BufWriter, Write}; use std::io::{BufWriter, Write};
use std::path::PathBuf; use std::path::{Path, PathBuf};
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::sync::atomic::{AtomicBool, AtomicU64}; use std::sync::atomic::{AtomicBool, AtomicU64};
use std::sync::Arc; use std::sync::Arc;
@ -232,82 +232,9 @@ impl BigFile {
} }
}; };
if metadata.is_dir() { if metadata.is_dir() {
if !self.recursive_search { self.check_folder_children(&mut dir_result, &mut warnings, current_folder, &entry_data);
continue 'dir;
}
let next_folder = current_folder.join(entry_data.file_name());
if self.directories.is_excluded(&next_folder) {
continue 'dir;
}
if self.excluded_items.is_excluded(&next_folder) {
continue 'dir;
}
#[cfg(target_family = "unix")]
if self.directories.exclude_other_filesystems() {
match self.directories.is_on_other_filesystems(&next_folder) {
Ok(true) => continue 'dir,
Err(e) => warnings.push(e.to_string()),
_ => (),
}
}
dir_result.push(next_folder);
} else if metadata.is_file() { } else if metadata.is_file() {
atomic_file_counter.fetch_add(1, Ordering::Relaxed); self.collect_file_entry(&atomic_file_counter, &metadata, &entry_data, &mut fe_result, &mut warnings, current_folder);
if metadata.len() == 0 {
continue 'dir;
}
let file_name_lowercase: String = match entry_data.file_name().into_string() {
Ok(t) => t,
Err(_inspected) => {
warnings.push(flc!(
"core_file_not_utf8_name",
generate_translation_hashmap(vec![("name", entry_data.path().display().to_string())])
));
continue 'dir;
}
}
.to_lowercase();
if !self.allowed_extensions.matches_filename(&file_name_lowercase) {
continue 'dir;
}
let current_file_name = current_folder.join(entry_data.file_name());
if self.excluded_items.is_excluded(&current_file_name) {
continue 'dir;
}
let fe: FileEntry = FileEntry {
path: current_file_name.clone(),
size: metadata.len(),
modified_date: match metadata.modified() {
Ok(t) => match t.duration_since(UNIX_EPOCH) {
Ok(d) => d.as_secs(),
Err(_inspected) => {
warnings.push(flc!(
"core_file_modified_before_epoch",
generate_translation_hashmap(vec![("name", current_file_name.display().to_string())])
));
0
}
},
Err(e) => {
warnings.push(flc!(
"core_file_no_modification_date",
generate_translation_hashmap(vec![("name", current_file_name.display().to_string()), ("reason", e.to_string())])
));
0
}
},
};
fe_result.push((fe.size, fe));
} }
} }
(dir_result, warnings, fe_result) (dir_result, warnings, fe_result)
@ -331,8 +258,102 @@ impl BigFile {
progress_thread_run.store(false, Ordering::Relaxed); progress_thread_run.store(false, Ordering::Relaxed);
progress_thread_handle.join().unwrap(); progress_thread_handle.join().unwrap();
// Extract n biggest files to new TreeMap self.extract_n_biggest_files(old_map);
Common::print_time(start_time, SystemTime::now(), "look_for_big_files");
true
}
pub fn check_folder_children(&self, dir_result: &mut Vec<PathBuf>, warnings: &mut Vec<String>, current_folder: &Path, entry_data: &DirEntry) {
if !self.recursive_search {
return;
}
let next_folder = current_folder.join(entry_data.file_name());
if self.directories.is_excluded(&next_folder) {
return;
}
if self.excluded_items.is_excluded(&next_folder) {
return;
}
#[cfg(target_family = "unix")]
if self.directories.exclude_other_filesystems() {
match self.directories.is_on_other_filesystems(&next_folder) {
Ok(true) => return,
Err(e) => warnings.push(e),
_ => (),
}
}
dir_result.push(next_folder);
}
pub fn collect_file_entry(
&self,
atomic_file_counter: &Arc<AtomicU64>,
metadata: &Metadata,
entry_data: &DirEntry,
fe_result: &mut Vec<(u64, FileEntry)>,
warnings: &mut Vec<String>,
current_folder: &Path,
) {
atomic_file_counter.fetch_add(1, Ordering::Relaxed);
if metadata.len() == 0 {
return;
}
let file_name_lowercase: String = match entry_data.file_name().into_string() {
Ok(t) => t,
Err(_inspected) => {
warnings.push(flc!(
"core_file_not_utf8_name",
generate_translation_hashmap(vec![("name", entry_data.path().display().to_string())])
));
return;
}
}
.to_lowercase();
if !self.allowed_extensions.matches_filename(&file_name_lowercase) {
return;
}
let current_file_name = current_folder.join(entry_data.file_name());
if self.excluded_items.is_excluded(&current_file_name) {
return;
}
let fe: FileEntry = FileEntry {
path: current_file_name.clone(),
size: metadata.len(),
modified_date: match metadata.modified() {
Ok(t) => match t.duration_since(UNIX_EPOCH) {
Ok(d) => d.as_secs(),
Err(_inspected) => {
warnings.push(flc!(
"core_file_modified_before_epoch",
generate_translation_hashmap(vec![("name", current_file_name.display().to_string())])
));
0
}
},
Err(e) => {
warnings.push(flc!(
"core_file_no_modification_date",
generate_translation_hashmap(vec![("name", current_file_name.display().to_string()), ("reason", e.to_string())])
));
0
}
},
};
fe_result.push((fe.size, fe));
}
pub fn extract_n_biggest_files(&mut self, old_map: BTreeMap<u64, Vec<FileEntry>>) {
let iter: Box<dyn Iterator<Item = _>>; let iter: Box<dyn Iterator<Item = _>>;
if self.search_mode == SearchMode::SmallestFiles { if self.search_mode == SearchMode::SmallestFiles {
iter = Box::new(old_map.into_iter()); iter = Box::new(old_map.into_iter());
@ -360,9 +381,6 @@ impl BigFile {
break; break;
} }
} }
Common::print_time(start_time, SystemTime::now(), "look_for_big_files");
true
} }
pub fn set_number_of_files_to_check(&mut self, number_of_files_to_check: usize) { pub fn set_number_of_files_to_check(&mut self, number_of_files_to_check: usize) {

View file

@ -30,6 +30,12 @@ pub enum DeleteMethod {
Delete, Delete,
} }
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
pub enum AudioCheckMethod {
Tags,
Content,
}
bitflags! { bitflags! {
#[derive(PartialEq, Copy, Clone, Debug)] #[derive(PartialEq, Copy, Clone, Debug)]
pub struct MusicSimilarity : u32 { pub struct MusicSimilarity : u32 {
@ -112,6 +118,7 @@ pub struct SameMusic {
delete_outdated_cache: bool, // TODO add this to GUI delete_outdated_cache: bool, // TODO add this to GUI
use_reference_folders: bool, use_reference_folders: bool,
save_also_as_json: bool, save_also_as_json: bool,
check_type: AudioCheckMethod,
} }
impl SameMusic { impl SameMusic {
@ -138,6 +145,7 @@ impl SameMusic {
use_reference_folders: false, use_reference_folders: false,
duplicated_music_entries_referenced: vec![], duplicated_music_entries_referenced: vec![],
save_also_as_json: false, save_also_as_json: false,
check_type: AudioCheckMethod::Content,
} }
} }
@ -148,13 +156,20 @@ impl SameMusic {
self.stopped_search = true; self.stopped_search = true;
return; return;
} }
if !self.check_records_multithreaded(stop_receiver, progress_sender) { match self.check_type {
self.stopped_search = true; AudioCheckMethod::Tags => {
return; if !self.read_tags(stop_receiver, progress_sender) {
} self.stopped_search = true;
if !self.check_for_duplicates(stop_receiver, progress_sender) { return;
self.stopped_search = true; }
return; if !self.check_for_duplicate_tags(stop_receiver, progress_sender) {
self.stopped_search = true;
return;
}
}
AudioCheckMethod::Content => {
unimplemented!();
}
} }
self.delete_files(); self.delete_files();
self.debug_print(); self.debug_print();
@ -308,7 +323,7 @@ impl SameMusic {
} }
} }
fn check_records_multithreaded(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&futures::channel::mpsc::UnboundedSender<ProgressData>>) -> bool { fn read_tags(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&futures::channel::mpsc::UnboundedSender<ProgressData>>) -> bool {
let start_time: SystemTime = SystemTime::now(); let start_time: SystemTime = SystemTime::now();
let loaded_hash_map; let loaded_hash_map;
@ -504,11 +519,11 @@ impl SameMusic {
return false; return false;
} }
Common::print_time(start_time, SystemTime::now(), "check_records_multithreaded"); Common::print_time(start_time, SystemTime::now(), "read_tags");
true true
} }
fn check_for_duplicates(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&futures::channel::mpsc::UnboundedSender<ProgressData>>) -> bool { fn check_for_duplicate_tags(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&futures::channel::mpsc::UnboundedSender<ProgressData>>) -> bool {
assert!(MusicSimilarity::NONE != self.music_similarity, "This can't be none"); assert!(MusicSimilarity::NONE != self.music_similarity, "This can't be none");
let start_time: SystemTime = SystemTime::now(); let start_time: SystemTime = SystemTime::now();
@ -748,7 +763,7 @@ impl SameMusic {
} }
} }
Common::print_time(start_time, SystemTime::now(), "check_for_duplicates"); Common::print_time(start_time, SystemTime::now(), "check_for_duplicate_tags");
// Clear unused data // Clear unused data
self.music_entries.clear(); self.music_entries.clear();

View file

@ -160,7 +160,7 @@
(5,122,"GtkCheckButton","check_button_music_genre",117,None,None,None,4), (5,122,"GtkCheckButton","check_button_music_genre",117,None,None,None,4),
(5,123,"GtkCheckButton","check_button_music_length",117,None,None,None,5), (5,123,"GtkCheckButton","check_button_music_length",117,None,None,None,5),
(5,124,"GtkBox",None,116,None,None,None,1), (5,124,"GtkBox",None,116,None,None,None,1),
(5,125,"GtkCheckButton","check_button_music_approximate_comparison",124,None,None,None,None), (5,125,"GtkCheckButton","check_button_music_approximate_comparison",124,None,None,None,2),
(5,126,"GtkScrolledWindow","scrolled_window_same_music_finder",116,None,None,None,2), (5,126,"GtkScrolledWindow","scrolled_window_same_music_finder",116,None,None,None,2),
(5,127,"GtkLabel",None,115,None,None,None,None), (5,127,"GtkLabel",None,115,None,None,None,None),
(5,128,"GtkNotebookPage",None,56,None,None,None,8), (5,128,"GtkNotebookPage",None,56,None,None,None,8),
@ -235,6 +235,8 @@
(5,230,"GtkBox",None,229,None,None,None,None), (5,230,"GtkBox",None,229,None,None,None,None),
(5,231,"GtkImage",None,230,None,None,None,None), (5,231,"GtkImage",None,230,None,None,None,None),
(5,232,"GtkLabel","label_buttons_sort",230,None,None,None,1), (5,232,"GtkLabel","label_buttons_sort",230,None,None,None,1),
(5,234,"GtkLabel","label_audio_check_type",124,None,None,None,None),
(5,235,"GtkComboBoxText","combo_box_audio_check_type",124,None,None,None,1),
(6,1,"GtkPopover","popover_right_click",None,None,None,None,None), (6,1,"GtkPopover","popover_right_click",None,None,None,None,None),
(6,2,"GtkBox",None,1,None,None,None,None), (6,2,"GtkBox",None,1,None,None,None,None),
(6,3,"GtkButton","buttons_popover_right_click_open_file",2,None,None,None,None), (6,3,"GtkButton","buttons_popover_right_click_open_file",2,None,None,None,None),
@ -765,6 +767,8 @@
(5,230,"GtkWidget","halign","center",None,None,None,None,None), (5,230,"GtkWidget","halign","center",None,None,None,None,None),
(5,231,"GtkImage","icon-name","image-missing",None,None,None,None,None), (5,231,"GtkImage","icon-name","image-missing",None,None,None,None,None),
(5,232,"GtkLabel","label","SortMenu",None,None,None,None,None), (5,232,"GtkLabel","label","SortMenu",None,None,None,None,None),
(5,234,"GtkLabel","label","Audio check type",None,None,None,None,None),
(5,234,"GtkWidget","margin-end","2",None,None,None,None,None),
(6,1,"GtkPopover","child",None,None,None,None,None,2), (6,1,"GtkPopover","child",None,None,None,None,None,2),
(6,1,"GtkPopover","position","left",None,None,None,None,None), (6,1,"GtkPopover","position","left",None,None,None,None,None),
(6,2,"GtkOrientable","orientation","vertical",None,None,None,None,None), (6,2,"GtkOrientable","orientation","vertical",None,None,None,None,None),

View file

@ -728,6 +728,15 @@
<property name="margin-bottom">2</property> <property name="margin-bottom">2</property>
<property name="margin-end">5</property> <property name="margin-end">5</property>
<property name="margin-start">5</property> <property name="margin-start">5</property>
<child>
<object class="GtkLabel" id="label_audio_check_type">
<property name="label">Audio check type</property>
<property name="margin-end">2</property>
</object>
</child>
<child>
<object class="GtkComboBoxText" id="combo_box_audio_check_type"/>
</child>
<child> <child>
<object class="GtkCheckButton" id="check_button_music_approximate_comparison"> <object class="GtkCheckButton" id="check_button_music_approximate_comparison">
<property name="focusable">1</property> <property name="focusable">1</property>