#include #include #include #include #include #include "indicators/terminal_size.hpp" #include "threadpool.hpp" #include "tree.hpp" #include "vxheaven_parse.hpp" namespace ind = indicators; int main() { std::ifstream ifs("./testdata/samples.sort"); vxorg::VxHeavenTree tree; // used for os filesystem ops ThreadPool fsPool(4); vxorg::parse_into_tree(tree, ifs); std::filesystem::path root = std::filesystem::current_path() / "testdata"; std::filesystem::path unorg = root / "unorg"; std::filesystem::path org = root / "org"; if(!std::filesystem::exists(org)) std::filesystem::create_directories(org); std::size_t sampleCount = 0; // Walk the tree to get the amount of sample nodes tree.walk([&](auto* node) { if(node->data().is_sample) sampleCount++; }); ind::ProgressBar bar { ind::option::BarWidth { indicators::terminal_width() - 64 }, ind::option::Start { "[" }, ind::option::Fill { "■" }, ind::option::Lead { "■" }, ind::option::Remainder { "-" }, ind::option::End { " ]" }, ind::option::ForegroundColor { ind::Color::cyan }, ind::option::FontStyles { std::vector { ind::FontStyle::bold } }, ind::option::MaxProgress { sampleCount } }; // Walk the tree to perform the operation tree.walk([&](auto* node) { auto tabulation_level = node->parent_count(); auto& data = node->data(); #if 0 if(tabulation_level != 0) { for(auto i = 0; i < tabulation_level; ++i) { std::printf("\t"); } } if(node->is_root()) { std::printf("(root)\n"); } else { if(data.is_sample) { std::string sample_name = vxorg::get_sample_name(node); std::printf("%s (sample %s)\n", data.name.c_str(), sample_name.c_str()); } else { std::printf("%s\n", data.name.c_str()); } } #endif #if 1 if(!node->is_root()) { if(data.is_sample) { std::string sample_name = vxorg::get_sample_name(node); // paths auto path = org / vxorg::get_sample_path(node); auto source_path = unorg / vxorg::get_sample_name(node); if(!std::filesystem::exists(source_path)) { std::printf("WARNING: sample %s/%s in tree (source disk file %s) does not exist\n", path.string().c_str(), sample_name.c_str(), source_path.string().c_str()); } else { fsPool.add_task([path, source_path, sample_name, &bar]() { bar.set_option(ind::option::PostfixText { std::format("Moving {}", sample_name) }); auto dest_path = path / sample_name; // possibly TOCTOUable but it should:tm: be fine? if(!std::filesystem::exists(path)) { std::filesystem::create_directories(path); } if(std::filesystem::exists(dest_path)) { std::filesystem::remove(dest_path); } std::filesystem::rename(source_path, dest_path); bar.tick(); }); } } } #endif }); return 0; }