Eliya/src/Reader/FileReader.cpp

142 lines
4.2 KiB
C++

//
// Created by versustune on 22.02.20.
//
#include <iostream>
#include <algorithm>
#include <fstream>
#include <utility>
#include <zconf.h>
#include <queue>
#include "FileReader.h"
#include "../Utils/Logging.h"
#include "../Utils/Utils.h"
#include "../Utils/ProgressBar.h"
#include "ThreadPool.h"
#define FS_MODULE_NAME "FileReader"
FileReader::FileReader(std::string path, std::string outputPath) {
FileReader::path = std::move(path);
FileReader::outputPath = std::move(outputPath);
validateDirectories();
}
FileReader::~FileReader() {
}
const std::vector<AudioFile *> &FileReader::getValidFiles() const {
return validFiles;
}
// here i want to iterate over all files recursive and save all valid files ;)
void FileReader::pureRead() {
auto *progressBar = getProgressBar("Read Files", -1);
progressBar->startThread();
for (const auto &entry : fs::recursive_directory_iterator(path, fs::directory_options::skip_permission_denied)) {
if (fs::is_directory(entry.path()))
continue;
try {
//check if file is less then 2GB
if (entry.file_size() < 2147483648) {
files.push_back(entry.path());
}
} catch (fs::filesystem_error &error) {
//skip
}
progressBar->tick();
}
progressBar->setFinished(true);
while (!progressBar->isDone()) {
usleep(1);
}
}
void FileReader::validateDirectories() {
if (!fs::is_directory(path)) {
Logging::error("Input Path not Found", FS_MODULE_NAME);
exit(1);
}
if (!fs::is_directory(outputPath)) {
Logging::error("Output Path not Found. Creating? [Y/n]", FS_MODULE_NAME);
auto value = std::cin.get();
if (value == 110) {
exit(1);
}
fs::create_directory(outputPath);
if (!fs::is_directory(outputPath)) {
Logging::error("Cannot create Output Path", FS_MODULE_NAME);
exit(1);
}
}
auto cacheDir = outputPath + "/cache";
if (!fs::is_directory(cacheDir)) {
fs::create_directory(cacheDir);
if (!fs::is_directory(cacheDir)) {
Logging::error("Cannot create Cache Directory", FS_MODULE_NAME);
exit(1);
}
}
auto finalDir = outputPath + "/final";
if (!fs::is_directory(finalDir)) {
fs::create_directory(outputPath + "/final");
if (!fs::is_directory(finalDir)) {
Logging::error("Cannot create final Directory", FS_MODULE_NAME);
exit(1);
}
}
}
/*
* this function write a json from all valid music files into the cache directory.
* here we go. we get all AudioFile and call the toJson function.
*/
void FileReader::writeToCache() {
auto cacheFile = outputPath + "/cache/" + cacheName;
std::ofstream outputFile;
outputFile.open(cacheFile);
if (!outputFile.is_open()) {
Logging::error("Cannot open cache File: \"" + cacheFile + "\"", FS_MODULE_NAME);
Logging::error("Writing Cache FAILED", FS_MODULE_NAME);
return;
}
}
/*
* filename: stringToHex(inputPath) + ".json"
*/
std::string FileReader::getCacheName() {
if (cacheName.empty()) {
std::string _cacheName = path;
_cacheName.erase(std::remove_if(_cacheName.begin(), _cacheName.end(), ::isspace), cacheName.end());
cacheName = Utils::stringToHex(_cacheName) + ".json";
}
return cacheName;
}
void FileReader::readAudioFiles() {
auto *progressBar = getProgressBar("Validate Files", files.size());
auto threadPool = ThreadPool();
auto queue = new Tsqueue<std::shared_ptr<ThreadQueueItem>>();
for (int i = 0; i < files.size(); ++i) {
auto item = std::make_shared<ThreadQueueItem>();
item->fileIndex = i;
item->reader = this;
item->progressBar = progressBar;
queue->push(item);
}
progressBar->setMaxTicks(queue->getSize());
threadPool.setQueue(queue);
threadPool.start(progressBar);
progressBar->setFinished(true);
}
ProgressBar *FileReader::getProgressBar(std::string name, int maxTicks) {
auto progressBar = new ProgressBar(std::move(name), maxTicks, 1);
std::thread progressBarThread(&ProgressBar::runInThread, progressBar);
progressBarThread.detach();
return progressBar;
}