diff --git a/src/broom.cpp b/src/broom.cpp index dae6f4d..4f414a6 100755 --- a/src/broom.cpp +++ b/src/broom.cpp @@ -215,6 +215,22 @@ uintmax_t Broom::remove_empty_files(std::vector& tracked_entries) return removed; }; +// Untracks specified group in tracked entries. Returns an amount of entries untracked +uintmax_t Broom::untrack_group(std::vector& tracked_entries, entry::Group group) { + uintmax_t untracked = 0; + + tracked_entries.erase(std::remove_if(tracked_entries.begin(), tracked_entries.end(), [&untracked, &group](entry::Entry& entry) -> bool { + if (entry.group == group) { + untracked++; + return true; + } else { + return false; + } + }), tracked_entries.end()); + + return untracked; +} + // marks every entry without any group as a duplicate void Broom::mark_as_duplicates(std::vector& tracked_entries) { for (entry::Entry& entry : tracked_entries) { diff --git a/src/broom.hpp b/src/broom.hpp index 023ed25..5252f92 100755 --- a/src/broom.hpp +++ b/src/broom.hpp @@ -46,6 +46,9 @@ public: // untracks entries with the same content-pieces. Returns amount of // files that are no longer being tracked. uintmax_t untrack_unique_contents(std::vector& tracked_entries); + + // Untracks specified group in tracked entries. Returns an amount of entries untracked + uintmax_t untrack_group(std::vector& tracked_entries, entry::Group group); // finds empty files among tracked entries and marks them with the appropriate group. // Returns amount of found empty files diff --git a/src/main.cpp b/src/main.cpp index 2a25d8a..9cfa47d 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -28,51 +28,51 @@ along with broom. If not, see . #include "broom.hpp" // Broom version number -#define VERSION "v0.3.0" +#define VERSION "v0.3.1" void print_help() { std::cout - << "broom [FLAGS..] [COMMAND] [DIRECTORY]" << std::endl << std::endl - << "[FLAGS]" << std::endl - << "-v | --version -> print version information and exit" << std::endl - << "-h | --help -> print this message and exit" << std::endl - << "-od | --output-directory -> path to the directory to save results file in" << std::endl << std::endl - - << "[COMMANDS]" << std::endl - << "sweep -> scan for duplicate files, REMOVE empty files and REPLACE other duplicates with symlinks" << std::endl - << "scan -> scan and save results in a file without removing anything [DEFAULT]" << std::endl << std::endl - - << "[DIRECTORY]" << std::endl - << "path to the directory to be scanned" << std::endl - << std::endl; + << "broom [FLAGS..] [COMMAND] [DIRECTORY]\n\n" + << "[FLAGS]\n" + << "-v | --version -> print version information and exit\n" + << "-h | --help -> print this message and exit\n" + << "-ie | --ignore-empty -> do not remove empty files when sweeping" + << "-od | --output-directory -> path to the directory to save results file in when scanning\n\n" + + << "[COMMANDS]\n" + << "sweep -> scan for duplicate files, REMOVE empty files and REPLACE other duplicates with symlinks\n" + << "scan -> scan and save results in a file without removing anything [DEFAULT]\n\n" + + << "[DIRECTORY]\n" + << "path to the directory to be scanned\n\n"; }; void print_version() { std::cout - << "broom " << VERSION << std::endl - << "incurable hoarder`s helpful friend" << std::endl << std::endl - - << " _" << std::endl - << " //" << std::endl - << " // " << std::endl - << " // " << std::endl - << " // " << std::endl - << " /####/ " << std::endl - << " ////// " << std::endl - << " /////// " << std::endl << std::endl - - << "Copyright (C) 2021 Kasyanov Nikolay Alexeyevich (Unbewohnte (me@unbewohnte.xyz))" << std::endl - << "This program comes with ABSOLUTELY NO WARRANTY." << std::endl - << "This is free software, and you are welcome to redistribute it" << std::endl - << "under certain conditions" << std::endl - << std::endl; + << "broom " << VERSION << "\n" + << "incurable hoarder`s helpful friend\n\n" + + << " _\n" + << " //\n" + << " // \n" + << " // \n" + << " // \n" + << " /####/ \n" + << " ////// \n" + << " /////// \n\n" + + << "Copyright (C) 2021 Kasyanov Nikolay Alexeyevich (Unbewohnte (me@unbewohnte.xyz))\n" + << "This program comes with ABSOLUTELY NO WARRANTY.\n" + << "This is free software, and you are welcome to redistribute it\n" + << "under certain conditions\n"; }; int main(int argc, char* argv[]) { - bool sweeping = false; std::filesystem::path results_file_dir_path = "."; std::filesystem::path tracked_path; + bool sweeping = false; + bool ignore_empty = false; if (argc < 2) { print_help(); @@ -95,6 +95,9 @@ int main(int argc, char* argv[]) { i++; results_file_dir_path = std::filesystem::path(argv[i]); } + else if (strcmp(argv[i], "-ie") == 0 || strcmp(argv[i], "--ignore-empty") == 0) { + ignore_empty = true; + } else if (strcmp(argv[i], "sweep") == 0) { sweeping = true; } @@ -117,37 +120,41 @@ int main(int argc, char* argv[]) { broom::Broom broom; try { std::cout - << " _" << std::endl - << " //" << std::endl - << " // " << std::endl - << " // " << std::endl - << " // " << std::endl - << " /####/ " << std::endl - << " ////// " << std::endl - << " /////// " << std::endl << std::endl; + << " _\n" + << " //\n" + << " // \n" + << " // \n" + << " // \n" + << " /####/ \n" + << " ////// \n" + << " /////// \n\n"; if (sweeping) { - std::cout << "[Sweeping]" << std::endl << std::endl; + std::cout << "[Sweeping]\n\n"; } else { - std::cout << "[Scanning]" << std::endl << std::endl; + std::cout << "[Scanning]\n\n"; } // track files in a given directory std::vector tracked_entries = broom.track(tracked_path); - std::cout << "[INFO] Tracking " << tracked_entries.size() << " files" << std::endl; + std::cout << "[INFO] Tracking " << tracked_entries.size() << " files\n"; // find empty files uintmax_t empty_files = broom.find_empty_files(tracked_entries); - std::cout << "[INFO] Found " << empty_files << " empty files" << std::endl; + std::cout << "[INFO] Found " << empty_files << " empty files\n"; // if sweeping - remove empty files right away - if (sweeping) { + if (sweeping && !ignore_empty) { uintmax_t removed = broom.remove_empty_files(tracked_entries); - std::cout << "[INFO] Removed " << removed << " empty files" << std::endl; + std::cout << "[INFO] Removed " << removed << " empty files\n"; + } else { + // just untrack them, do not remove + uintmax_t untracked_empty = broom.untrack_group(tracked_entries, entry::Group::EMPTY); + std::cout << "[INFO] Skipped " << untracked_empty << " empty files\n"; } // untrack unique sizes uintmax_t untracked = broom.untrack_unique_sizes(tracked_entries); - std::cout << "[INFO] Untracked " << untracked << " files with a unique size" << std::endl; + std::cout << "[INFO] Untracked " << untracked << " files with a unique size\n"; // get content pieces for each entry tracked_entries.erase(std::remove_if(tracked_entries.begin(), tracked_entries.end(), [](entry::Entry& entry) -> bool { @@ -163,16 +170,16 @@ int main(int argc, char* argv[]) { // untrack unique contents untracked = broom.untrack_unique_contents(tracked_entries); - std::cout << "[INFO] Untracked " << untracked << " files with unique contents" << std::endl; + std::cout << "[INFO] Untracked " << untracked << " files with unique contents\n"; // mark entries as duplicates broom.mark_as_duplicates(tracked_entries); - std::cout << "[INFO] " << tracked_entries.size() << " files left being tracked" << std::endl; + std::cout << "[INFO] " << tracked_entries.size() << " files left being tracked\n"; if (tracked_entries.size() == 0) { // No duplicates at all ! - std::cout << "[INFO] Nothing I can help with ! Congratulations !" << std::endl; + std::cout << "[INFO] Nothing I can help with ! Congratulations !\n"; return 0; } @@ -187,22 +194,21 @@ int main(int argc, char* argv[]) { if (!sweeping) { // output a little information about how much space could be freed if every duplicate // in the group will be deleted but one - std::cout <<"[INFO] " << could_be_freed / 1024 / 1024 << " MB could be freed" << std::endl; + std::cout <<"[INFO] " << could_be_freed / 1024 / 1024 << " MB could be freed\n"; broom.create_scan_results_list(grouped_duplicates, results_file_dir_path); - std::cout << "[INFO] Created scan results file" << std::endl; + std::cout << "[INFO] Created scan results file\n"; } else { // remove duplicates and create symlinks - std::cout << "[INFO] Removing duplicates and creating symlinks..." << std::endl; + std::cout << "[INFO] Removing duplicates and creating symlinks...\n"; broom.remove_duplicates_make_symlinks(grouped_duplicates); - - std::cout <<"[INFO] Freed approximately " << could_be_freed / 1024 / 1024 << " MB (May be incorrect)" << std::endl; + std::cout <<"[INFO] Freed approximately " << could_be_freed / 1024 / 1024 << " MB (May be incorrect)\n"; } } catch(const std::exception& e) { std::cerr - << "[ERROR] " << e.what() << std::endl; + << "[ERROR] " << e.what() <<"\n"; return 1; };