vxorg/vxorg.cpp

134 lines
3.6 KiB
C++
Raw Permalink Normal View History

#include <cstring>
#include <filesystem>
#include <fstream>
2024-10-21 21:21:37 -04:00
#include <indicators/progress_bar.hpp>
#include <indicators/terminal_size.hpp>
#include <string>
2024-10-21 21:21:37 -04:00
#include "indicators/terminal_size.hpp"
2024-10-22 00:49:49 -04:00
#include "threadpool.hpp"
#include "tree.hpp"
#include "vxheaven_parse.hpp"
2024-10-21 21:21:37 -04:00
namespace ind = indicators;
int main(int argc, char** argv) {
if(argc != 4) {
std::fprintf(stderr, "usage: %s [path to list] [source path] [destination path]\n", argv[0]);
return 1;
}
vxorg::VxHeavenTree sample_tree;
2024-10-22 00:49:49 -04:00
// used for os filesystem ops
ThreadPool filesystem_threadpool(4);
// Parse into the sample tree
std::ifstream ifs(argv[1]);
if(!ifs) {
char err[256]{};
strerror_r(errno, &err[0], sizeof(err)-1);
std::fprintf(stderr, "Could not open sample list \"%s\": %s", argv[1], err);
return 1;
}
vxorg::parse_into_tree(sample_tree, ifs);
2024-10-22 00:49:49 -04:00
std::filesystem::path unorganized_source_path = argv[2];
std::filesystem::path organized_destination_path = argv[3];
2024-10-21 21:21:37 -04:00
if(!std::filesystem::exists(unorganized_source_path)) {
std::fprintf(stderr, "Source path \"%s\" does not exist", argv[2]);
return 1;
}
if(!std::filesystem::exists(organized_destination_path))
std::filesystem::create_directories(organized_destination_path);
2024-10-21 21:21:37 -04:00
std::size_t sampleCount = 0;
2024-10-21 21:21:37 -04:00
// Walk the tree to get the amount of sample nodes
sample_tree.walk([&](auto* node) {
2024-10-21 21:21:37 -04:00
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::red },
2024-10-21 21:21:37 -04:00
ind::option::FontStyles { std::vector<ind::FontStyle> { ind::FontStyle::bold } },
ind::option::MaxProgress { sampleCount } };
// Walk the tree to perform the operation
sample_tree.walk([&](auto* node) {
auto& data = node->data();
#if 0
auto tabulation_level = node->parent_count();
if(tabulation_level != 0) {
for(auto i = 0; i < tabulation_level; ++i) {
std::printf("\t");
}
}
2024-10-21 19:56:43 -04:00
if(node->is_root()) {
std::printf("(root)\n");
} else {
if(data.is_sample) {
2024-10-21 12:27:40 -04:00
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
2024-10-21 21:21:37 -04:00
if(!node->is_root()) {
if(data.is_sample) {
std::string sample_name = vxorg::get_sample_name(node);
2024-10-21 21:21:37 -04:00
// paths
auto path = organized_destination_path / vxorg::get_sample_path(node);
auto source_path = unorganized_source_path / vxorg::get_sample_name(node);
2024-10-21 21:21:37 -04:00
if(!std::filesystem::exists(source_path)) {
std::printf("WARNING: sample %s in tree (source disk file %s) does not exist\n", sample_name.c_str(),
2024-10-21 21:21:37 -04:00
source_path.string().c_str());
} else {
filesystem_threadpool.add_task([path, source_path, sample_name, &bar]() {
2024-10-22 00:49:49 -04:00
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);
}
2024-10-21 21:21:37 -04:00
if(std::filesystem::exists(dest_path)) {
std::filesystem::remove(dest_path);
}
2024-10-21 21:21:37 -04:00
2024-10-22 00:49:49 -04:00
std::filesystem::rename(source_path, dest_path);
bar.tick();
});
}
2024-10-21 21:21:37 -04:00
}
}
#endif
});
2024-10-22 00:49:49 -04:00
filesystem_threadpool.shutdown();
bar.mark_as_completed();
std::printf("Done.\n");
return 0;
}