1
0
Fork 0
mirror of synced 2024-05-18 03:13:36 +12:00
This commit is contained in:
Rafał Mikrut 2023-10-02 19:26:44 +02:00
parent df6ec5cee1
commit 8cf3b00e53
15 changed files with 428 additions and 408 deletions

26
Cargo.lock generated
View file

@ -735,9 +735,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.3"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "136526188508e25c6fef639d7927dfb3e0e3084488bf202267829cf7fc23dbdd"
checksum = "add4f07d43996f76ef320709726a556a9d4f965d9410d8d0271132d2f8293480"
dependencies = [
"errno-dragonfly",
"libc",
@ -1742,9 +1742,9 @@ checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "linux-raw-sys"
version = "0.4.7"
version = "0.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a9bad9f94746442c783ca431b22403b519cd7fbeed0533fdd6328b2f2212128"
checksum = "3852614a3bd9ca9804678ba6be5e3b8ce76dfc902cae004e3e0c44051b6e88db"
[[package]]
name = "locale_config"
@ -1771,9 +1771,9 @@ dependencies = [
[[package]]
name = "lofty"
version = "0.15.0"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8143c1ac799df98778738e48e403990dcae27c9843f89ae0bd79967ddd512448"
checksum = "cfa7a62ede7d634892901a2be8bb32f3e13d0418f276d2a391a509afe050f01b"
dependencies = [
"base64",
"byteorder",
@ -1843,9 +1843,9 @@ checksum = "490cc448043f947bae3cbee9c203358d62dbee0db12107a74be5c30ccfd09771"
[[package]]
name = "memchr"
version = "2.6.3"
version = "2.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f232d6ef707e1956a43342693d2a31e72989554d58299d7a88738cc95b0d35c"
checksum = "f665ee40bc4a3c5590afb1e9677db74a508659dfd71e126420da8274909a0167"
[[package]]
name = "memoffset"
@ -2368,13 +2368,13 @@ dependencies = [
[[package]]
name = "regex"
version = "1.9.5"
version = "1.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "697061221ea1b4a94a624f67d0ae2bfe4e22b8a17b6a192afb11046542cc8c47"
checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff"
dependencies = [
"aho-corasick",
"memchr",
"regex-automata 0.3.8",
"regex-automata 0.3.9",
"regex-syntax 0.7.5",
]
@ -2389,9 +2389,9 @@ dependencies = [
[[package]]
name = "regex-automata"
version = "0.3.8"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2f401f4955220693b56f8ec66ee9c78abffd8d1c4f23dc41a23839eb88f0795"
checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9"
dependencies = [
"aho-corasick",
"memchr",

View file

@ -26,7 +26,7 @@ hamming = "0.1"
# Needed by same music
bitflags = "2.4"
lofty = "0.15"
lofty = "0.16"
# Futures - needed by async progress sender
futures = "0.3.28"

View file

@ -174,12 +174,6 @@ pub struct Info {
pub number_of_files_with_bad_extension: usize,
}
impl Info {
pub fn new() -> Self {
Default::default()
}
}
pub struct BadExtensions {
common_data: CommonToolData,
information: Info,
@ -187,21 +181,11 @@ pub struct BadExtensions {
bad_extensions_files: Vec<BadFileEntry>,
include_files_without_extension: bool,
}
impl CommonData for BadExtensions {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}
impl BadExtensions {
pub fn new() -> Self {
Self {
common_data: CommonToolData::new(ToolType::BadExtensions),
information: Info::new(),
information: Info::default(),
files_to_check: Default::default(),
bad_extensions_files: Default::default(),
include_files_without_extension: true,
@ -209,7 +193,13 @@ impl BadExtensions {
}
pub fn find_bad_extensions_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
info!("Starting finding extensions files");
info!("Starting finding files with bad extensions");
let start_time = std::time::Instant::now();
self.find_bad_extensions_files_internal(stop_receiver, progress_sender);
info!("Ended finding files with bad extensions which took {:?}", start_time.elapsed());
}
fn find_bad_extensions_files_internal(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
self.optimize_dirs_before_start();
if !self.check_files(stop_receiver, progress_sender) {
self.common_data.stopped_search = true;
@ -221,13 +211,6 @@ impl BadExtensions {
}
self.debug_print();
}
pub const fn get_bad_extensions_files(&self) -> &Vec<BadFileEntry> {
&self.bad_extensions_files
}
pub const fn get_information(&self) -> &Info {
&self.information
}
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
debug!("check_files - start");
@ -498,3 +481,22 @@ impl PrintResults for BadExtensions {
}
}
}
impl BadExtensions {
pub const fn get_bad_extensions_files(&self) -> &Vec<BadFileEntry> {
&self.bad_extensions_files
}
pub const fn get_information(&self) -> &Info {
&self.information
}
}
impl CommonData for BadExtensions {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}

View file

@ -42,12 +42,6 @@ pub struct Info {
pub number_of_real_files: usize,
}
impl Info {
pub fn new() -> Self {
Default::default()
}
}
/// Struct with required information's to work
pub struct BigFile {
common_data: CommonToolData,
@ -58,20 +52,11 @@ pub struct BigFile {
search_mode: SearchMode,
}
impl CommonData for BigFile {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}
impl BigFile {
pub fn new() -> Self {
Self {
common_data: CommonToolData::new(ToolType::BigFile),
information: Info::new(),
information: Info::default(),
big_files: Default::default(),
number_of_files_to_check: 50,
delete_method: DeleteMethod::None,
@ -81,6 +66,12 @@ impl BigFile {
pub fn find_big_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
info!("Starting finding big files");
let start_time = std::time::Instant::now();
self.find_big_files_internal(stop_receiver, progress_sender);
info!("Ended finding big files which took {:?}", start_time.elapsed());
}
fn find_big_files_internal(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
self.optimize_dirs_before_start();
if !self.look_for_big_files(stop_receiver, progress_sender) {
self.common_data.stopped_search = true;
@ -90,22 +81,6 @@ impl BigFile {
self.debug_print();
}
pub fn set_search_mode(&mut self, search_mode: SearchMode) {
self.search_mode = search_mode;
}
pub const fn get_big_files(&self) -> &Vec<(u64, FileEntry)> {
&self.big_files
}
pub const fn get_information(&self) -> &Info {
&self.information
}
pub fn set_delete_method(&mut self, delete_method: DeleteMethod) {
self.delete_method = delete_method;
}
fn look_for_big_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
debug!("look_for_big_files - start");
let mut folders_to_check: Vec<PathBuf> = Vec::with_capacity(1024 * 2); // This should be small enough too not see to big difference and big enough to store most of paths without needing to resize vector
@ -250,10 +225,6 @@ impl BigFile {
debug!("extract_n_biggest_files - end");
}
pub fn set_number_of_files_to_check(&mut self, number_of_files_to_check: usize) {
self.number_of_files_to_check = number_of_files_to_check;
}
/// Function to delete files, from filed Vector
fn delete_files(&mut self) {
match self.delete_method {
@ -353,3 +324,34 @@ impl PrintResults for BigFile {
}
}
}
impl CommonData for BigFile {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}
impl BigFile {
pub fn set_search_mode(&mut self, search_mode: SearchMode) {
self.search_mode = search_mode;
}
pub const fn get_big_files(&self) -> &Vec<(u64, FileEntry)> {
&self.big_files
}
pub const fn get_information(&self) -> &Info {
&self.information
}
pub fn set_delete_method(&mut self, delete_method: DeleteMethod) {
self.delete_method = delete_method;
}
pub fn set_number_of_files_to_check(&mut self, number_of_files_to_check: usize) {
self.number_of_files_to_check = number_of_files_to_check;
}
}

View file

@ -68,12 +68,6 @@ pub struct Info {
pub number_of_broken_files: usize,
}
impl Info {
pub fn new() -> Self {
Default::default()
}
}
pub struct BrokenFiles {
common_data: CommonToolData,
information: Info,
@ -83,20 +77,11 @@ pub struct BrokenFiles {
checked_types: CheckedTypes,
}
impl CommonData for BrokenFiles {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}
impl BrokenFiles {
pub fn new() -> Self {
Self {
common_data: CommonToolData::new(ToolType::BrokenFiles),
information: Info::new(),
information: Info::default(),
files_to_check: Default::default(),
delete_method: DeleteMethod::None,
broken_files: Default::default(),
@ -106,6 +91,12 @@ impl BrokenFiles {
pub fn find_broken_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
info!("Starting finding broken files");
let start_time = std::time::Instant::now();
self.find_broken_files_internal(stop_receiver, progress_sender);
info!("Ended finding broken files which took {:?}", start_time.elapsed());
}
pub fn find_broken_files_internal(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
self.optimize_dirs_before_start();
if !self.check_files(stop_receiver, progress_sender) {
self.common_data.stopped_search = true;
@ -671,3 +662,12 @@ fn validate_pdf_error(file_entry: &mut FileEntry, e: PdfError) -> PdfError {
file_entry.error_string = error_string;
unpack_pdf_error(e)
}
impl CommonData for BrokenFiles {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}

View file

@ -82,7 +82,7 @@ pub const IMAGE_RS_BROKEN_FILES_EXTENSIONS: &[&str] = &[
];
pub const HEIC_EXTENSIONS: &[&str] = &[".heif", ".heifs", ".heic", ".heics", ".avci", ".avcs", ".avif", ".avifs"];
pub const ZIP_FILES_EXTENSIONS: &[&str] = &[".zip"];
pub const ZIP_FILES_EXTENSIONS: &[&str] = &[".zip", ".jar"];
pub const PDF_FILES_EXTENSIONS: &[&str] = &[".pdf"];
@ -94,7 +94,8 @@ pub const VIDEO_FILES_EXTENSIONS: &[&str] = &[
".mp4", ".mpv", ".flv", ".mp4a", ".webm", ".mpg", ".mp2", ".mpeg", ".m4p", ".m4v", ".avi", ".wmv", ".qt", ".mov", ".swf", ".mkv",
];
pub const LOOP_DURATION: u32 = 200; //ms
pub const LOOP_DURATION: u32 = 20; //ms
pub const SEND_PROGRESS_DATA_TIME_BETWEEN: u32 = 200; //ms
pub struct Common();
@ -411,21 +412,28 @@ pub fn prepare_thread_handler_common(
let progress_send = progress_sender.clone();
let progress_thread_run = progress_thread_run.clone();
let atomic_counter = atomic_counter.clone();
thread::spawn(move || loop {
progress_send
.unbounded_send(ProgressData {
checking_method,
current_stage,
max_stage,
entries_checked: atomic_counter.load(Ordering::Relaxed),
entries_to_check: max_value,
tool_type,
})
.unwrap();
if !progress_thread_run.load(Ordering::Relaxed) {
break;
thread::spawn(move || {
let mut time_since_last_send = SystemTime::now();
loop {
if time_since_last_send.elapsed().unwrap().as_millis() > SEND_PROGRESS_DATA_TIME_BETWEEN as u128 {
progress_send
.unbounded_send(ProgressData {
checking_method,
current_stage,
max_stage,
entries_checked: atomic_counter.load(Ordering::Relaxed),
entries_to_check: max_value,
tool_type,
})
.unwrap();
time_since_last_send = SystemTime::now();
}
if !progress_thread_run.load(Ordering::Relaxed) {
break;
}
sleep(Duration::from_millis(LOOP_DURATION as u64));
}
sleep(Duration::from_millis(LOOP_DURATION as u64));
})
} else {
thread::spawn(|| {})

View file

@ -44,8 +44,9 @@ pub enum ToolType {
None,
}
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
#[derive(PartialEq, Eq, Clone, Debug, Copy, Default)]
pub enum CheckingMethod {
#[default]
None,
Name,
SizeName,

View file

@ -28,8 +28,9 @@ use crate::localizer_core::generate_translation_hashmap;
const TEMP_HARDLINK_FILE: &str = "rzeczek.rxrxrxl";
#[derive(PartialEq, Eq, Clone, Debug, Copy)]
#[derive(PartialEq, Eq, Clone, Debug, Copy, Default)]
pub enum HashType {
#[default]
Blake3,
Crc32,
Xxh3,
@ -45,8 +46,9 @@ impl HashType {
}
}
#[derive(Eq, PartialEq, Clone, Debug, Copy)]
#[derive(Eq, PartialEq, Clone, Debug, Copy, Default)]
pub enum DeleteMethod {
#[default]
None,
AllExceptNewest,
AllExceptOldest,
@ -69,31 +71,25 @@ pub struct Info {
pub lost_space_by_hash: u64,
}
impl Info {
pub fn new() -> Self {
Default::default()
}
}
pub struct DuplicateFinder {
common_data: CommonToolData,
information: Info,
// File Size, File Entry
files_with_identical_names: BTreeMap<String, Vec<FileEntry>>,
// File Size, File Entry
// File (Size, Name), File Entry
files_with_identical_size_names: BTreeMap<(u64, String), Vec<FileEntry>>,
// File (Size, Name), File Entry
// File Size, File Entry
files_with_identical_size: BTreeMap<u64, Vec<FileEntry>>,
// File Size, File Entry
// File Size, next grouped by file size, next grouped by hash
files_with_identical_hashes: BTreeMap<u64, Vec<Vec<FileEntry>>>,
// File Size, next grouped by file size, next grouped by hash
// File Size, File Entry
files_with_identical_names_referenced: BTreeMap<String, (FileEntry, Vec<FileEntry>)>,
// File Size, File Entry
files_with_identical_size_names_referenced: BTreeMap<(u64, String), (FileEntry, Vec<FileEntry>)>,
// File (Size, Name), File Entry
files_with_identical_size_referenced: BTreeMap<u64, (FileEntry, Vec<FileEntry>)>,
files_with_identical_size_names_referenced: BTreeMap<(u64, String), (FileEntry, Vec<FileEntry>)>,
// File Size, File Entry
files_with_identical_hashes_referenced: BTreeMap<u64, Vec<(FileEntry, Vec<FileEntry>)>>,
files_with_identical_size_referenced: BTreeMap<u64, (FileEntry, Vec<FileEntry>)>,
// File Size, next grouped by file size, next grouped by hash
files_with_identical_hashes_referenced: BTreeMap<u64, Vec<(FileEntry, Vec<FileEntry>)>>,
check_method: CheckingMethod,
delete_method: DeleteMethod,
hash_type: HashType,
@ -105,20 +101,11 @@ pub struct DuplicateFinder {
case_sensitive_name_comparison: bool,
}
impl CommonData for DuplicateFinder {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}
impl DuplicateFinder {
pub fn new() -> Self {
Self {
common_data: CommonToolData::new(ToolType::Duplicate),
information: Info::new(),
information: Info::default(),
files_with_identical_names: Default::default(),
files_with_identical_size: Default::default(),
files_with_identical_size_names: Default::default(),
@ -141,6 +128,12 @@ impl DuplicateFinder {
pub fn find_duplicates(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
info!("Starting finding duplicates");
let start_time = std::time::Instant::now();
self.find_duplicates_internal(stop_receiver, progress_sender);
info!("Ended finding duplicates which took {:?}", start_time.elapsed());
}
fn find_duplicates_internal(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
self.optimize_dirs_before_start();
self.common_data.use_reference_folders = !self.common_data.directories.reference_directories.is_empty();
@ -1492,6 +1485,15 @@ impl MyHasher for Xxh3 {
}
}
impl CommonData for DuplicateFinder {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}
#[cfg(test)]
mod tests {
use std::fs::{read_dir, File, Metadata};

View file

@ -23,12 +23,6 @@ pub struct Info {
pub number_of_empty_files: usize,
}
impl Info {
pub fn new() -> Self {
Default::default()
}
}
/// Struct with required information's to work
pub struct EmptyFiles {
common_data: CommonToolData,
@ -50,15 +44,20 @@ impl EmptyFiles {
pub fn new() -> Self {
Self {
common_data: CommonToolData::new(ToolType::EmptyFiles),
information: Info::new(),
information: Info::default(),
empty_files: vec![],
delete_method: DeleteMethod::None,
}
}
/// Finding empty files, save results to internal struct variables
pub fn find_empty_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
info!("Starting finding empty files");
let start_time = std::time::Instant::now();
self.find_empty_files_internal(stop_receiver, progress_sender);
info!("Ended finding empty files which took {:?}", start_time.elapsed());
}
fn find_empty_files_internal(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
self.optimize_dirs_before_start();
if !self.check_files(stop_receiver, progress_sender) {
self.common_data.stopped_search = true;
@ -68,18 +67,6 @@ impl EmptyFiles {
self.debug_print();
}
pub const fn get_empty_files(&self) -> &Vec<FileEntry> {
&self.empty_files
}
pub const fn get_information(&self) -> &Info {
&self.information
}
pub fn set_delete_method(&mut self, delete_method: DeleteMethod) {
self.delete_method = delete_method;
}
/// Check files for any with size == 0
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
debug!("check_files - start");
@ -207,3 +194,17 @@ impl PrintResults for EmptyFiles {
}
}
}
impl EmptyFiles {
pub const fn get_empty_files(&self) -> &Vec<FileEntry> {
&self.empty_files
}
pub const fn get_information(&self) -> &Info {
&self.information
}
pub fn set_delete_method(&mut self, delete_method: DeleteMethod) {
self.delete_method = delete_method;
}
}

View file

@ -20,27 +20,12 @@ pub struct EmptyFolder {
empty_folder_list: BTreeMap<PathBuf, FolderEntry>, // Path, FolderEntry
}
impl CommonData for EmptyFolder {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}
/// Info struck with helpful information's about results
#[derive(Default)]
pub struct Info {
pub number_of_empty_folders: usize,
}
impl Info {
pub fn new() -> Self {
Default::default()
}
}
/// Method implementation for `EmptyFolder`
impl EmptyFolder {
/// New function providing basics values
@ -62,9 +47,14 @@ impl EmptyFolder {
&self.information
}
/// Public function used by CLI to search for empty folders
pub fn find_empty_folders(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
info!("Starting finding empty folders");
let start_time = std::time::Instant::now();
self.find_empty_folders_internal(stop_receiver, progress_sender);
info!("Ended finding empty folders which took {:?}", start_time.elapsed());
}
fn find_empty_folders_internal(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
self.optimize_dirs_before_start();
if !self.check_for_empty_folders(stop_receiver, progress_sender) {
self.common_data.stopped_search = true;
@ -235,3 +225,12 @@ impl PrintResults for EmptyFolder {
}
}
}
impl CommonData for EmptyFolder {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}

View file

@ -23,12 +23,6 @@ pub struct Info {
pub number_of_invalid_symlinks: usize,
}
impl Info {
pub fn new() -> Self {
Default::default()
}
}
/// Struct with required information's to work
pub struct InvalidSymlinks {
common_data: CommonToolData,
@ -37,27 +31,24 @@ pub struct InvalidSymlinks {
delete_method: DeleteMethod,
}
impl CommonData for InvalidSymlinks {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}
impl InvalidSymlinks {
pub fn new() -> Self {
Self {
common_data: CommonToolData::new(ToolType::InvalidSymlinks),
information: Info::new(),
information: Info::default(),
invalid_symlinks: vec![],
delete_method: DeleteMethod::None,
}
}
pub fn find_invalid_links(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
info!("Starting finding invalid links");
info!("Starting finding invalid symlinks");
let start_time = std::time::Instant::now();
self.find_invalid_links_internal(stop_receiver, progress_sender);
info!("Ended finding invalid symlinks which took {:?}", start_time.elapsed());
}
fn find_invalid_links_internal(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
self.optimize_dirs_before_start();
if !self.check_files(stop_receiver, progress_sender) {
self.common_data.stopped_search = true;
@ -219,3 +210,12 @@ impl PrintResults for InvalidSymlinks {
}
}
}
impl CommonData for InvalidSymlinks {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}

View file

@ -98,12 +98,6 @@ pub struct Info {
pub number_of_groups: u64,
}
impl Info {
pub fn new() -> Self {
Default::default()
}
}
/// Struct with required information's to work
pub struct SameMusic {
common_data: CommonToolData,
@ -121,20 +115,11 @@ pub struct SameMusic {
maximum_difference: f64,
}
impl CommonData for SameMusic {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}
impl SameMusic {
pub fn new() -> Self {
Self {
common_data: CommonToolData::new(ToolType::SameMusic),
information: Info::new(),
information: Info::default(),
music_entries: Vec::with_capacity(2048),
delete_method: DeleteMethod::None,
music_similarity: MusicSimilarity::NONE,
@ -150,7 +135,13 @@ impl SameMusic {
}
pub fn find_same_music(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
info!("Starting finding same music");
info!("Starting finding same music files");
let start_time = std::time::Instant::now();
self.find_same_music_internal(stop_receiver, progress_sender);
info!("Ended finding same music which took {:?}", start_time.elapsed());
}
fn find_same_music_internal(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
self.optimize_dirs_before_start();
self.common_data.use_reference_folders = !self.common_data.directories.reference_directories.is_empty();
if !self.check_files(stop_receiver, progress_sender) {
@ -188,62 +179,6 @@ impl SameMusic {
self.debug_print();
}
pub const fn get_duplicated_music_entries(&self) -> &Vec<Vec<MusicEntry>> {
&self.duplicated_music_entries
}
pub const fn get_music_similarity(&self) -> &MusicSimilarity {
&self.music_similarity
}
pub const fn get_information(&self) -> &Info {
&self.information
}
pub fn set_delete_method(&mut self, delete_method: DeleteMethod) {
self.delete_method = delete_method;
}
pub fn set_approximate_comparison(&mut self, approximate_comparison: bool) {
self.approximate_comparison = approximate_comparison;
}
pub fn set_maximum_difference(&mut self, maximum_difference: f64) {
self.maximum_difference = maximum_difference;
}
pub fn set_minimum_segment_duration(&mut self, minimum_segment_duration: f32) {
self.minimum_segment_duration = minimum_segment_duration;
}
pub fn set_check_type(&mut self, check_type: CheckingMethod) {
assert!([CheckingMethod::AudioTags, CheckingMethod::AudioContent].contains(&check_type));
self.check_type = check_type;
}
pub fn get_check_type(&self) -> CheckingMethod {
self.check_type
}
pub fn set_music_similarity(&mut self, music_similarity: MusicSimilarity) {
self.music_similarity = music_similarity;
}
pub fn get_similar_music_referenced(&self) -> &Vec<(MusicEntry, Vec<MusicEntry>)> {
&self.duplicated_music_entries_referenced
}
pub fn get_number_of_base_duplicated_files(&self) -> usize {
if self.common_data.use_reference_folders {
self.duplicated_music_entries_referenced.len()
} else {
self.duplicated_music_entries.len()
}
}
pub fn get_use_reference(&self) -> bool {
self.common_data.use_reference_folders
}
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
if !self.common_data.allowed_extensions.using_custom_extensions() {
self.common_data.allowed_extensions.extend_allowed_extensions(AUDIO_FILES_EXTENSIONS);
@ -752,6 +687,64 @@ impl SameMusic {
}
}
impl SameMusic {
pub const fn get_duplicated_music_entries(&self) -> &Vec<Vec<MusicEntry>> {
&self.duplicated_music_entries
}
pub const fn get_music_similarity(&self) -> &MusicSimilarity {
&self.music_similarity
}
pub const fn get_information(&self) -> &Info {
&self.information
}
pub fn set_delete_method(&mut self, delete_method: DeleteMethod) {
self.delete_method = delete_method;
}
pub fn set_approximate_comparison(&mut self, approximate_comparison: bool) {
self.approximate_comparison = approximate_comparison;
}
pub fn set_maximum_difference(&mut self, maximum_difference: f64) {
self.maximum_difference = maximum_difference;
}
pub fn set_minimum_segment_duration(&mut self, minimum_segment_duration: f32) {
self.minimum_segment_duration = minimum_segment_duration;
}
pub fn set_check_type(&mut self, check_type: CheckingMethod) {
assert!([CheckingMethod::AudioTags, CheckingMethod::AudioContent].contains(&check_type));
self.check_type = check_type;
}
pub fn get_check_type(&self) -> CheckingMethod {
self.check_type
}
pub fn set_music_similarity(&mut self, music_similarity: MusicSimilarity) {
self.music_similarity = music_similarity;
}
pub fn get_similar_music_referenced(&self) -> &Vec<(MusicEntry, Vec<MusicEntry>)> {
&self.duplicated_music_entries_referenced
}
pub fn get_number_of_base_duplicated_files(&self) -> usize {
if self.common_data.use_reference_folders {
self.duplicated_music_entries_referenced.len()
} else {
self.duplicated_music_entries.len()
}
}
pub fn get_use_reference(&self) -> bool {
self.common_data.use_reference_folders
}
}
fn save_cache_to_file(hashmap: &HashMap<String, MusicEntry>, text_messages: &mut Messages, save_also_as_json: bool, checking_tags: bool) {
if let Some(((file_handler, cache_file), (file_handler_json, cache_file_json))) =
open_cache_folder(get_cache_file(checking_tags), true, save_also_as_json, &mut text_messages.warnings)
@ -1162,3 +1155,12 @@ mod tests {
assert_eq!(what, "Kekistan");
}
}
impl CommonData for SameMusic {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}

View file

@ -96,15 +96,6 @@ pub struct SimilarImages {
exclude_images_with_same_size: bool,
}
impl CommonData for SimilarImages {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}
/// Info struck with helpful information's about results
#[derive(Default)]
pub struct Info {
@ -112,12 +103,6 @@ pub struct Info {
pub number_of_groups: u64,
}
impl Info {
pub fn new() -> Self {
Default::default()
}
}
/// Method implementation for `EmptyFolder`
impl SimilarImages {
/// New function providing basics values
@ -139,50 +124,14 @@ impl SimilarImages {
}
}
pub fn set_hash_size(&mut self, hash_size: u8) {
self.hash_size = match hash_size {
8 | 16 | 32 | 64 => hash_size,
e => {
panic!("Invalid value of hash size {e}");
}
}
}
pub fn set_exclude_images_with_same_size(&mut self, exclude_images_with_same_size: bool) {
self.exclude_images_with_same_size = exclude_images_with_same_size;
}
pub fn set_hash_alg(&mut self, hash_alg: HashAlg) {
self.hash_alg = hash_alg;
}
pub fn set_image_filter(&mut self, image_filter: FilterType) {
self.image_filter = image_filter;
}
pub const fn get_similar_images(&self) -> &Vec<Vec<FileEntry>> {
&self.similar_vectors
}
pub fn get_similar_images_referenced(&self) -> &Vec<(FileEntry, Vec<FileEntry>)> {
&self.similar_referenced_vectors
}
pub fn get_use_reference(&self) -> bool {
self.common_data.use_reference_folders
}
pub const fn get_information(&self) -> &Info {
&self.information
}
pub fn set_similarity(&mut self, similarity: u32) {
self.similarity = similarity;
}
/// Public function used by CLI to search for empty folders
pub fn find_similar_images(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
info!("Starting finding similar images");
info!("Starting finding similar images files");
let start_time = std::time::Instant::now();
self.find_similar_images_internal(stop_receiver, progress_sender);
info!("Ended finding similar images which took {:?}", start_time.elapsed());
}
pub fn find_similar_images_internal(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
self.optimize_dirs_before_start();
self.common_data.use_reference_folders = !self.common_data.directories.reference_directories.is_empty();
if !self.check_for_similar_images(stop_receiver, progress_sender) {
@ -1260,6 +1209,58 @@ fn debug_check_for_duplicated_things(
assert!(!found_broken_thing);
}
impl CommonData for SimilarImages {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}
impl SimilarImages {
pub fn set_hash_size(&mut self, hash_size: u8) {
self.hash_size = match hash_size {
8 | 16 | 32 | 64 => hash_size,
e => {
panic!("Invalid value of hash size {e}");
}
}
}
pub fn set_exclude_images_with_same_size(&mut self, exclude_images_with_same_size: bool) {
self.exclude_images_with_same_size = exclude_images_with_same_size;
}
pub fn set_hash_alg(&mut self, hash_alg: HashAlg) {
self.hash_alg = hash_alg;
}
pub fn set_image_filter(&mut self, image_filter: FilterType) {
self.image_filter = image_filter;
}
pub const fn get_similar_images(&self) -> &Vec<Vec<FileEntry>> {
&self.similar_vectors
}
pub fn get_similar_images_referenced(&self) -> &Vec<(FileEntry, Vec<FileEntry>)> {
&self.similar_referenced_vectors
}
pub fn get_use_reference(&self) -> bool {
self.common_data.use_reference_folders
}
pub const fn get_information(&self) -> &Info {
&self.information
}
pub fn set_similarity(&mut self, similarity: u32) {
self.similarity = similarity;
}
}
#[cfg(test)]
mod tests {
use std::collections::HashMap;

View file

@ -83,12 +83,6 @@ pub struct Info {
pub number_of_groups: u64,
}
impl Info {
pub fn new() -> Self {
Default::default()
}
}
/// Method implementation for `EmptyFolder`
impl SimilarVideos {
/// New function providing basics values
@ -106,42 +100,14 @@ impl SimilarVideos {
}
}
pub fn set_exclude_videos_with_same_size(&mut self, exclude_videos_with_same_size: bool) {
self.exclude_videos_with_same_size = exclude_videos_with_same_size;
}
pub fn set_tolerance(&mut self, tolerance: i32) {
assert!((0..=MAX_TOLERANCE).contains(&tolerance));
self.tolerance = tolerance;
}
pub const fn get_similar_videos(&self) -> &Vec<Vec<FileEntry>> {
&self.similar_vectors
}
pub const fn get_information(&self) -> &Info {
&self.information
}
pub fn get_similar_videos_referenced(&self) -> &Vec<(FileEntry, Vec<FileEntry>)> {
&self.similar_referenced_vectors
}
pub fn get_number_of_base_duplicated_files(&self) -> usize {
if self.common_data.use_reference_folders {
self.similar_referenced_vectors.len()
} else {
self.similar_vectors.len()
}
}
pub fn get_use_reference(&self) -> bool {
self.common_data.use_reference_folders
}
/// Public function used by CLI to search for empty folders
pub fn find_similar_videos(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
info!("Starting finding similar videos");
let start_time = std::time::Instant::now();
self.find_similar_videos_internal(stop_receiver, progress_sender);
info!("Ended finding similar videos which took {:?}", start_time.elapsed());
}
fn find_similar_videos_internal(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
if !check_if_ffmpeg_is_installed() {
self.common_data.text_messages.errors.push(flc!("core_ffmpeg_not_found"));
#[cfg(target_os = "windows")]
@ -627,3 +593,38 @@ pub fn check_if_ffmpeg_is_installed() -> bool {
}
true
}
impl SimilarVideos {
pub fn set_exclude_videos_with_same_size(&mut self, exclude_videos_with_same_size: bool) {
self.exclude_videos_with_same_size = exclude_videos_with_same_size;
}
pub fn set_tolerance(&mut self, tolerance: i32) {
assert!((0..=MAX_TOLERANCE).contains(&tolerance));
self.tolerance = tolerance;
}
pub const fn get_similar_videos(&self) -> &Vec<Vec<FileEntry>> {
&self.similar_vectors
}
pub const fn get_information(&self) -> &Info {
&self.information
}
pub fn get_similar_videos_referenced(&self) -> &Vec<(FileEntry, Vec<FileEntry>)> {
&self.similar_referenced_vectors
}
pub fn get_number_of_base_duplicated_files(&self) -> usize {
if self.common_data.use_reference_folders {
self.similar_referenced_vectors.len()
} else {
self.similar_vectors.len()
}
}
pub fn get_use_reference(&self) -> bool {
self.common_data.use_reference_folders
}
}

View file

@ -50,12 +50,6 @@ pub struct Info {
pub number_of_temporary_files: usize,
}
impl Info {
pub fn new() -> Self {
Default::default()
}
}
/// Struct with required information's to work
pub struct Temporary {
common_data: CommonToolData,
@ -64,28 +58,17 @@ pub struct Temporary {
delete_method: DeleteMethod,
}
impl CommonData for Temporary {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}
impl Temporary {
pub fn new() -> Self {
Self {
common_data: CommonToolData::new(ToolType::TemporaryFiles),
information: Info::new(),
information: Info::default(),
delete_method: DeleteMethod::None,
temporary_files: vec![],
}
}
/// Finding temporary files, save results to internal struct variables
pub fn find_temporary_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
info!("Starting finding temporary files");
fn find_temporary_files_internal(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
self.optimize_dirs_before_start();
if !self.check_files(stop_receiver, progress_sender) {
self.common_data.stopped_search = true;
@ -95,16 +78,11 @@ impl Temporary {
self.debug_print();
}
pub const fn get_temporary_files(&self) -> &Vec<FileEntry> {
&self.temporary_files
}
pub const fn get_information(&self) -> &Info {
&self.information
}
pub fn set_delete_method(&mut self, delete_method: DeleteMethod) {
self.delete_method = delete_method;
pub fn find_temporary_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) {
info!("Starting finding temporary files");
let start_time = std::time::Instant::now();
self.find_temporary_files_internal(stop_receiver, progress_sender);
info!("Ended finding temporary files which took {:?}", start_time.elapsed());
}
fn check_files(&mut self, stop_receiver: Option<&Receiver<()>>, progress_sender: Option<&UnboundedSender<ProgressData>>) -> bool {
@ -229,27 +207,6 @@ impl Temporary {
}
}
impl Default for Temporary {
fn default() -> Self {
Self::new()
}
}
impl DebugPrint for Temporary {
#[allow(dead_code)]
#[allow(unreachable_code)]
fn debug_print(&self) {
#[cfg(not(debug_assertions))]
{
return;
}
println!("### Information's");
println!("Temporary list size - {}", self.temporary_files.len());
println!("Delete Method - {:?}", self.delete_method);
self.debug_print_common();
}
}
impl SaveResults for Temporary {
fn save_results_to_file(&mut self, file_name: &str) -> bool {
let file_name: String = match file_name {
@ -299,3 +256,47 @@ impl PrintResults for Temporary {
}
}
}
impl Default for Temporary {
fn default() -> Self {
Self::new()
}
}
impl DebugPrint for Temporary {
#[allow(dead_code)]
#[allow(unreachable_code)]
fn debug_print(&self) {
#[cfg(not(debug_assertions))]
{
return;
}
println!("### Information's");
println!("Temporary list size - {}", self.temporary_files.len());
println!("Delete Method - {:?}", self.delete_method);
self.debug_print_common();
}
}
impl CommonData for Temporary {
fn get_cd(&self) -> &CommonToolData {
&self.common_data
}
fn get_cd_mut(&mut self) -> &mut CommonToolData {
&mut self.common_data
}
}
impl Temporary {
pub const fn get_temporary_files(&self) -> &Vec<FileEntry> {
&self.temporary_files
}
pub const fn get_information(&self) -> &Info {
&self.information
}
pub fn set_delete_method(&mut self, delete_method: DeleteMethod) {
self.delete_method = delete_method;
}
}