diff --git a/df_finder3.py b/df_finder3.py index 706bfb1..e052fc0 100644 --- a/df_finder3.py +++ b/df_finder3.py @@ -20,13 +20,13 @@ def main(args): (files_moved, files_created, unique_source_duplicate_files_found, duplicate_source_files_moved) = ( find_and_process_duplicates(args)) else: - duplicates, _, _ = find_duplicates_files_v3(args, args.src, args.target) + duplicates, source_stats, target_stats = find_duplicates_files_v3(args, args.src, args.target) files_moved, files_created = process_duplicates(duplicates, args) duplicate_source_files_moved = clean_source_duplications(args, duplicates) deleted_source_folders = fm.delete_empty_folders_in_tree(args.src, True) if args.delete_empty_folders else 0 hash_manager.save_data() - output_results(args, files_moved, files_created, deleted_source_folders, duplicate_source_files_moved) + output_results(args, files_moved, files_created, deleted_source_folders, duplicate_source_files_moved, source_stats, target_stats) if __name__ == "__main__": diff --git a/duplicate_files_in_folders/duplicates_finder.py b/duplicate_files_in_folders/duplicates_finder.py index ba88285..7ce4865 100644 --- a/duplicate_files_in_folders/duplicates_finder.py +++ b/duplicate_files_in_folders/duplicates_finder.py @@ -129,16 +129,16 @@ def process_duplicates(combined: Dict, args) -> (int, int): # Copy or move files to target locations if not args.copy_to_all: - copy_or_move_file(target_files[0]['path'], args.move_to, src_filepath, args.target, not args.run, move=True) + copy_or_move_file(target_files[0]['path'], args.move_to, src_filepath, args.target, move=True) files_moved += 1 else: num_to_copy = max(0, len(target_files) - len(srcs_to_move)) for i in range(num_to_copy): - copy_or_move_file(target_files[i]['path'], args.move_to, src_filepath, args.target, not args.run, False) + copy_or_move_file(target_files[i]['path'], args.move_to, src_filepath, args.target, False) files_created += 1 for (src, _), tgt in zip(srcs_to_move, target_files[num_to_copy:]): - copy_or_move_file(tgt['path'], args.move_to, src, args.target, not args.run, move=True) + copy_or_move_file(tgt['path'], args.move_to, src, args.target, move=True) files_moved += 1 return files_moved, files_created @@ -153,5 +153,5 @@ def clean_source_duplications(args, combined): locations['source'] if os.path.exists(file_info['path'])] source_dups_move_to: str = str(os.path.join(args.move_to, os.path.basename(args.src) + "_dups")) for src_path in source_paths: - copy_or_move_file(src_path, source_dups_move_to, src_path, args.src, not args.run, move=True) + copy_or_move_file(src_path, source_dups_move_to, src_path, args.src, move=True) return len(source_paths) diff --git a/duplicate_files_in_folders/old_duplicates_finder.py b/duplicate_files_in_folders/old_duplicates_finder.py index bd29ac7..3ebd82f 100644 --- a/duplicate_files_in_folders/old_duplicates_finder.py +++ b/duplicate_files_in_folders/old_duplicates_finder.py @@ -123,18 +123,18 @@ def move_to_target_paths(args, src_filepath, target_paths_to_copy, source_duplic source_duplicates.sort(key=lambda x: x[0], reverse=True) # sort by path name reverse for easier testing if not args.copy_to_all: - copy_or_move_file(target_paths_to_copy[0], args.move_to, src_filepath, args.target, not args.run) + copy_or_move_file(target_paths_to_copy[0], args.move_to, src_filepath, args.target) return files_created, files_moved + 1 num_to_copy = max(0, len(target_paths_to_copy) - len(source_duplicates)) if num_to_copy: # Copy first source to make up for fewer source duplicates for i in range(num_to_copy): - copy_or_move_file(target_paths_to_copy[i], args.move_to, src_filepath, args.target, not args.run, False) + copy_or_move_file(target_paths_to_copy[i], args.move_to, src_filepath, args.target, False) files_created += 1 # Move each source duplicate to the corresponding target path for (src, _), tgt in zip(source_duplicates, target_paths_to_copy[num_to_copy:]): - copy_or_move_file(tgt, args.move_to, src, args.target, not args.run, move=True) + copy_or_move_file(tgt, args.move_to, src, args.target, move=True) files_moved += 1 return files_created, files_moved diff --git a/duplicate_files_in_folders/utils.py b/duplicate_files_in_folders/utils.py index a1317ab..41b321c 100644 --- a/duplicate_files_in_folders/utils.py +++ b/duplicate_files_in_folders/utils.py @@ -11,15 +11,6 @@ logger = logging.getLogger(__name__) -def validate_folder(folder, name): - """ Validate if a folder exists and is not empty. """ - if not os.path.isdir(folder) or not os.path.exists(folder): - print_error(f"{name} folder does not exist.") - if not os.listdir(folder): - print_error(f"{name} folder is empty.") - return True - - def log_and_print(message): print(message) logger.info(message) @@ -114,8 +105,8 @@ def any_is_subfolder_of(folders: List[str]) -> bool: for i in range(len(folders)): for j in range(len(folders)): if i != j and folders[i].startswith(folders[j]): - print_error(f"{folders[i]} is a subfolder of {folders[j]}") - return True + logger.error(f"{folders[i]} is a subfolder of {folders[j]}") + sys.exit(1) return False @@ -221,12 +212,8 @@ def parse_arguments(cust_args=None, check_folders=True): return args -def print_error(message): - print(f"Error: {message}") - logger.critical(f"{message}") - sys.exit(1) - -def output_results(args, files_moved, files_created, deleted_source_folders, duplicate_source_files_moved): +def output_results(args, files_moved, files_created, deleted_source_folders, duplicate_source_files_moved, + source_stats, target_stats): summary_header = "Summary (Test Mode):" if not args.run else "Summary:" separator = "-" * max(len(summary_header), 40) blank_line = "" @@ -244,8 +231,10 @@ def output_results(args, files_moved, files_created, deleted_source_folders, dup # Detailed summary summary_lines = { - 'Files Moved': f"{files_moved}", - 'Files Created': f"{files_created} copies", + 'Source Files': f"{format_number_with_commas(len(source_stats))} files", + 'Target Files': f"{format_number_with_commas(len(target_stats))} files", + 'Files Moved': f"{format_number_with_commas(files_moved)}", + 'Files Created': f"{format_number_with_commas(files_created)} copies", } if duplicate_source_files_moved: @@ -269,7 +258,8 @@ def setup_hash_manager(args): return hash_manager -def copy_or_move_file(target_file_path: str, destination_base_path: str, source_file_path: str, base_target_path: str, is_test_mode: bool, move: bool = True) -> str: +def copy_or_move_file(target_file_path: str, destination_base_path: str, source_file_path: str, base_target_path: str, + move: bool = True) -> str: destination_path = os.path.join(destination_base_path, os.path.relpath(target_file_path, base_target_path)) destination_dir = os.path.dirname(destination_path) file_manager = FileManager.get_instance() @@ -283,7 +273,6 @@ def copy_or_move_file(target_file_path: str, destination_base_path: str, source_ return final_destination_path - def check_and_update_filename(original_filename): new_filename = original_filename if os.path.exists(original_filename): diff --git a/tests/test_functions.py b/tests/test_functions.py index 09e003e..cb5eb30 100644 --- a/tests/test_functions.py +++ b/tests/test_functions.py @@ -1,9 +1,7 @@ -import logging - from duplicate_files_in_folders.duplicates_finder import clean_source_duplications, find_duplicates_files_v3, \ process_duplicates from duplicate_files_in_folders.file_manager import FileManager -from duplicate_files_in_folders.utils import parse_arguments, any_is_subfolder_of, validate_folder, parse_size, \ +from duplicate_files_in_folders.utils import parse_arguments, any_is_subfolder_of, parse_size, \ check_and_update_filename from tests.helpers_testing import * @@ -87,27 +85,6 @@ def test_check_and_update_filename(): assert check_and_update_filename(exist_file) != exist_file -def test_validate_folder(setup_teardown): - source_dir, _, _, _ = setup_teardown - - # test case 1: folder not existing - with pytest.raises(SystemExit) as excinfo: - validate_folder(os.path.join(source_dir, "sub1"), "sub1") - assert excinfo.type == SystemExit - assert excinfo.value.code == 1 - - # test case 2: folder existing but empty - os.makedirs(os.path.join(source_dir, "sub1")) - with pytest.raises(SystemExit) as excinfo: - validate_folder(os.path.join(source_dir, "sub1"), "sub1") - assert excinfo.type == SystemExit - assert excinfo.value.code == 1 - - # test case 3: folder existing and not empty - copy_files(range(1, 6), os.path.join(source_dir, "sub1")) - assert validate_folder(os.path.join(source_dir, "sub1"), "sub1") is True - - def test_any_is_subfolder_of(): # Test case 1: one folder is subfolder of another with pytest.raises(SystemExit) as excinfo: diff --git a/tests/test_old_functions.py b/tests/test_old_functions.py index e6913f6..046821f 100644 --- a/tests/test_old_functions.py +++ b/tests/test_old_functions.py @@ -321,3 +321,40 @@ def test_delete_empty_folders_in_tree(setup_teardown): # check that source folder was not deleted assert os.path.exists(source_dir), "source folder does not exist" + + +# def test_validate_folder(setup_teardown): +# source_dir, _, _, _ = setup_teardown +# +# # test case 1: folder not existing +# with pytest.raises(SystemExit) as excinfo: +# validate_folder(os.path.join(source_dir, "sub1"), "sub1") +# assert excinfo.type == SystemExit +# assert excinfo.value.code == 1 +# +# # test case 2: folder existing but empty +# os.makedirs(os.path.join(source_dir, "sub1")) +# with pytest.raises(SystemExit) as excinfo: +# validate_folder(os.path.join(source_dir, "sub1"), "sub1") +# assert excinfo.type == SystemExit +# assert excinfo.value.code == 1 +# +# # test case 3: folder existing and not empty +# copy_files(range(1, 6), os.path.join(source_dir, "sub1")) +# assert validate_folder(os.path.join(source_dir, "sub1"), "sub1") is True +# +# +# +# def print_error(message): +# print(f"Error: {message}") +# logger.critical(f"{message}") +# sys.exit(1) +# +# +# def validate_folder(folder, name): +# """ Validate if a folder exists and is not empty. """ +# if not os.path.isdir(folder) or not os.path.exists(folder): +# print_error(f"{name} folder does not exist.") +# if not os.listdir(folder): +# print_error(f"{name} folder is empty.") +# return True