some more thoughts about config
This commit is contained in:
parent
870842f63d
commit
6c7356598a
@ -1,3 +1,10 @@
|
|||||||
|
function(make_includable input_file output_file)
|
||||||
|
file(READ ${input_file} content)
|
||||||
|
set(delim "for_c++_include")
|
||||||
|
set(content "R\"${delim}(\n${content})${delim}\"")
|
||||||
|
file(WRITE ${output_file} "${content}")
|
||||||
|
endfunction(make_includable)
|
||||||
|
|
||||||
set(SOURCES
|
set(SOURCES
|
||||||
main.cpp
|
main.cpp
|
||||||
help.cpp
|
help.cpp
|
||||||
@ -20,3 +27,6 @@ set(HEADERS
|
|||||||
)
|
)
|
||||||
|
|
||||||
target_sources(${PROJECT_NAME} PRIVATE ${SOURCES})
|
target_sources(${PROJECT_NAME} PRIVATE ${SOURCES})
|
||||||
|
|
||||||
|
make_includable(default.conf ${CMAKE_BINARY_DIR}/generated/default.conf)
|
||||||
|
target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_BINARY_DIR})
|
||||||
|
@ -71,13 +71,12 @@ void Collection::convert(const std::string& outPath) {
|
|||||||
switch (entry.status().type()) {
|
switch (entry.status().type()) {
|
||||||
case fs::file_type::regular: {
|
case fs::file_type::regular: {
|
||||||
fs::path sourcePath = entry.path();
|
fs::path sourcePath = entry.path();
|
||||||
fs::path dstPath = out / sourcePath.filename();
|
fs::path dstPath = out / sourcePath.stem();
|
||||||
if (isMusic(sourcePath)) {
|
if (isMusic(sourcePath))
|
||||||
dstPath.replace_extension(".mp3");
|
|
||||||
taskManager->queueJob(sourcePath, dstPath);
|
taskManager->queueJob(sourcePath, dstPath);
|
||||||
} else {
|
else
|
||||||
fs::copy_file(sourcePath, dstPath, fs::copy_options::overwrite_existing);
|
fs::copy_file(sourcePath, dstPath, fs::copy_options::overwrite_existing);
|
||||||
}
|
|
||||||
//std::cout << sourcePath << " => " << dstPath << std::endl;
|
//std::cout << sourcePath << " => " << dstPath << std::endl;
|
||||||
} break;
|
} break;
|
||||||
case fs::file_type::directory: {
|
case fs::file_type::directory: {
|
||||||
|
23
src/default.conf
Normal file
23
src/default.conf
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# This is a default autogenerated MLC config
|
||||||
|
# The syntax goes like this:
|
||||||
|
# key value
|
||||||
|
#
|
||||||
|
# Use # sign for comments
|
||||||
|
#
|
||||||
|
# All printed comented out values are default values
|
||||||
|
#
|
||||||
|
# You should have one of this files as ~/.config/mlc.conf,
|
||||||
|
# if you have started mlc at least once.
|
||||||
|
# This is going to be used every time you launch mlc,
|
||||||
|
# so, edit it if you wish to change default behaviour.
|
||||||
|
#
|
||||||
|
# Alternatively, you can launch `mlc -c customConfig.conf`
|
||||||
|
# if you wish to override ~/.config/mlc.conf file
|
||||||
|
|
||||||
|
# Log level, regulates minimal message severity to be printed
|
||||||
|
# Allowed values are: debug, info, minor, major, warning, error, fatal
|
||||||
|
#level info
|
||||||
|
|
||||||
|
# Output type
|
||||||
|
# Allowed values are: mp3 (more comming soon)
|
||||||
|
#type mp3
|
@ -1,5 +1,15 @@
|
|||||||
#include "loggable.h"
|
#include "loggable.h"
|
||||||
|
|
||||||
|
constexpr std::array<std::string_view, Loggable::_sevetirySize> levels({
|
||||||
|
"debug",
|
||||||
|
"info",
|
||||||
|
"minor",
|
||||||
|
"major",
|
||||||
|
"warning",
|
||||||
|
"error",
|
||||||
|
"fatal"
|
||||||
|
});
|
||||||
|
|
||||||
Loggable::Loggable(Loggable::Severity severity):
|
Loggable::Loggable(Loggable::Severity severity):
|
||||||
currentSeverity(severity),
|
currentSeverity(severity),
|
||||||
history()
|
history()
|
||||||
@ -16,3 +26,11 @@ void Loggable::log(Loggable::Severity severity, const std::string& comment) cons
|
|||||||
std::list<std::pair<Loggable::Severity, std::string>> Loggable::getHistory() const {
|
std::list<std::pair<Loggable::Severity, std::string>> Loggable::getHistory() const {
|
||||||
return history;
|
return history;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loggable::Severity Loggable::stringToSeverity(const std::string& line) {
|
||||||
|
unsigned char dist = std::distance(levels.begin(), std::find(levels.begin(), levels.end(), line));
|
||||||
|
if (dist < _sevetirySize)
|
||||||
|
return static_cast<Severity>(dist);
|
||||||
|
|
||||||
|
return _sevetirySize;
|
||||||
|
}
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <array>
|
||||||
|
#include <string_view>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
class Loggable {
|
class Loggable {
|
||||||
public:
|
public:
|
||||||
@ -12,7 +15,8 @@ public:
|
|||||||
major,
|
major,
|
||||||
warning,
|
warning,
|
||||||
error,
|
error,
|
||||||
fatal
|
fatal,
|
||||||
|
_sevetirySize
|
||||||
};
|
};
|
||||||
typedef std::pair<Severity, std::string> Message;
|
typedef std::pair<Severity, std::string> Message;
|
||||||
|
|
||||||
@ -22,6 +26,8 @@ public:
|
|||||||
void log (Severity severity, const std::string& comment) const;
|
void log (Severity severity, const std::string& comment) const;
|
||||||
std::list<Message> getHistory() const;
|
std::list<Message> getHistory() const;
|
||||||
|
|
||||||
|
static Severity stringToSeverity(const std::string& line);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
const Severity currentSeverity;
|
const Severity currentSeverity;
|
||||||
mutable std::list<Message> history;
|
mutable std::list<Message> history;
|
||||||
|
27
src/main.cpp
27
src/main.cpp
@ -1,6 +1,8 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
|
#include <memory>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
#include "FLAC/stream_decoder.h"
|
#include "FLAC/stream_decoder.h"
|
||||||
@ -12,14 +14,14 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
Settings settings(argc, argv);
|
std::shared_ptr<Settings> settings = std::make_shared<Settings>(argc, argv);
|
||||||
|
|
||||||
switch (settings.getAction()) {
|
switch (settings->getAction()) {
|
||||||
case Settings::help:
|
case Settings::help:
|
||||||
printHelp();
|
printHelp();
|
||||||
return 0;
|
return 0;
|
||||||
case Settings::printConfig:
|
case Settings::config:
|
||||||
//printHelp();
|
std::cout << settings->defaultConfig() << std::endl;
|
||||||
return 0;
|
return 0;
|
||||||
case Settings::convert:
|
case Settings::convert:
|
||||||
std::cout << "Converting..." << std::endl;
|
std::cout << "Converting..." << std::endl;
|
||||||
@ -29,12 +31,23 @@ int main(int argc, char **argv) {
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskManager taskManager;
|
if (!settings->readConfigFile() && settings->isConfigDefault()) {
|
||||||
|
std::string defaultConfigPath = settings->getConfigPath();
|
||||||
|
std::ofstream file(defaultConfigPath, std::ios::out | std::ios::trunc);
|
||||||
|
if (file.is_open()) {
|
||||||
|
std::cout << "Writing default config to " << defaultConfigPath << std::endl;
|
||||||
|
file << settings->defaultConfig();
|
||||||
|
} else {
|
||||||
|
std::cout << "Couldn't open " << defaultConfigPath << " to write default config" << std::endl;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TaskManager taskManager(settings);
|
||||||
taskManager.start();
|
taskManager.start();
|
||||||
|
|
||||||
std::chrono::time_point start = std::chrono::system_clock::now();
|
std::chrono::time_point start = std::chrono::system_clock::now();
|
||||||
Collection collection(settings.getInput(), &taskManager);
|
Collection collection(settings->getInput(), &taskManager);
|
||||||
collection.convert(settings.getOutput());
|
collection.convert(settings->getOutput());
|
||||||
|
|
||||||
taskManager.printProgress();
|
taskManager.printProgress();
|
||||||
taskManager.wait();
|
taskManager.wait();
|
||||||
|
143
src/settings.cpp
143
src/settings.cpp
@ -1,14 +1,32 @@
|
|||||||
#include "settings.h"
|
#include "settings.h"
|
||||||
|
|
||||||
|
static const char* defaultConfig =
|
||||||
|
#include "generated/default.conf"
|
||||||
|
;
|
||||||
|
|
||||||
constexpr std::array<std::string_view, Settings::_actionsSize> actions({
|
constexpr std::array<std::string_view, Settings::_actionsSize> actions({
|
||||||
"convert",
|
"convert",
|
||||||
"help",
|
"help",
|
||||||
"printConfig"
|
"config"
|
||||||
});
|
});
|
||||||
|
|
||||||
|
constexpr std::array<std::string_view, Settings::_optionsSize> options({
|
||||||
|
"level",
|
||||||
|
"type"
|
||||||
|
});
|
||||||
|
|
||||||
|
constexpr std::array<std::string_view, Settings::_typesSize> types({
|
||||||
|
"mp3"
|
||||||
|
});
|
||||||
|
|
||||||
|
bool is_space(char ch){
|
||||||
|
return std::isspace(static_cast<unsigned char>(ch));
|
||||||
|
}
|
||||||
|
|
||||||
Settings::Settings(int argc, char ** argv):
|
Settings::Settings(int argc, char ** argv):
|
||||||
arguments(),
|
arguments(),
|
||||||
action(std::nullopt),
|
action(std::nullopt),
|
||||||
|
outputType(std::nullopt),
|
||||||
input(std::nullopt),
|
input(std::nullopt),
|
||||||
output(std::nullopt),
|
output(std::nullopt),
|
||||||
logLevel(std::nullopt)
|
logLevel(std::nullopt)
|
||||||
@ -23,10 +41,9 @@ void Settings::parseArguments() {
|
|||||||
for (int i = 0; i < arguments.size(); ++i) {
|
for (int i = 0; i < arguments.size(); ++i) {
|
||||||
const std::string_view& arg = arguments[i];
|
const std::string_view& arg = arguments[i];
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
std::string_view act = stripFlags(arg);
|
Action act = stringToAction(stripFlags(arg));
|
||||||
int dist = std::distance(actions.begin(), std::find(actions.begin(), actions.end(), act));
|
if (act < _actionsSize) {
|
||||||
if (dist < _actionsSize) {
|
action = act;
|
||||||
action = static_cast<Settings::Action>(dist);
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -52,6 +69,13 @@ Settings::Action Settings::getAction() const {
|
|||||||
return convert;
|
return convert;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Settings::Type Settings::getType() const {
|
||||||
|
if (outputType.has_value())
|
||||||
|
return outputType.value();
|
||||||
|
else
|
||||||
|
return mp3;
|
||||||
|
}
|
||||||
|
|
||||||
std::string Settings::getInput() const {
|
std::string Settings::getInput() const {
|
||||||
if (input.has_value())
|
if (input.has_value())
|
||||||
return input.value();
|
return input.value();
|
||||||
@ -66,6 +90,17 @@ std::string Settings::getOutput() const {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string Settings::getConfigPath() const {
|
||||||
|
if (configPath.has_value())
|
||||||
|
return configPath.value();
|
||||||
|
else
|
||||||
|
return std::string(getenv("HOME")) + "/.config/mlc.conf";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::isConfigDefault() const {
|
||||||
|
return !configPath.has_value();
|
||||||
|
}
|
||||||
|
|
||||||
Loggable::Severity Settings::getLogLevel() const {
|
Loggable::Severity Settings::getLogLevel() const {
|
||||||
if (logLevel.has_value())
|
if (logLevel.has_value())
|
||||||
return logLevel.value();
|
return logLevel.value();
|
||||||
@ -82,3 +117,101 @@ std::string_view Settings::stripFlags(const std::string_view& option) {
|
|||||||
}
|
}
|
||||||
return option;
|
return option;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Settings::strip(std::string& line) {
|
||||||
|
line.erase(line.begin(), std::find_if(line.begin(), line.end(), std::not_fn(is_space)));
|
||||||
|
line.erase(std::find_if(line.rbegin(), line.rend(), std::not_fn(is_space)).base(), line.end());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::stripComment(std::string& line) {
|
||||||
|
std::string::size_type index = line.find('#');
|
||||||
|
if (index != std::string::npos)
|
||||||
|
line.erase(index);
|
||||||
|
|
||||||
|
strip(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string Settings::defaultConfig() const {
|
||||||
|
return ::defaultConfig + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Settings::readConfigFile() {
|
||||||
|
std::ifstream file;
|
||||||
|
file.open(getConfigPath(), std::ios::in);
|
||||||
|
if (file.is_open()){
|
||||||
|
std::string tp;
|
||||||
|
while(getline(file, tp)) {
|
||||||
|
stripComment(tp);
|
||||||
|
if (!tp.empty())
|
||||||
|
readConfigLine(tp);
|
||||||
|
}
|
||||||
|
file.close();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Settings::readConfigLine(const std::string& line) {
|
||||||
|
std::istringstream stream(line);
|
||||||
|
std::string key;
|
||||||
|
if (!(stream >> key))
|
||||||
|
return;
|
||||||
|
|
||||||
|
Option option = stringToOption(key);
|
||||||
|
if (option == _optionsSize)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (option) {
|
||||||
|
case level: {
|
||||||
|
std::string lv;
|
||||||
|
if (stream >> lv) {
|
||||||
|
Loggable::Severity level = Loggable::stringToSeverity(lv);
|
||||||
|
if (level < Loggable::_sevetirySize)
|
||||||
|
logLevel = level;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
case type: {
|
||||||
|
std::string lv;
|
||||||
|
if (stream >> lv) {
|
||||||
|
Type type = stringToType(lv);
|
||||||
|
if (type < _typesSize)
|
||||||
|
outputType = type;
|
||||||
|
}
|
||||||
|
} break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings::Action Settings::stringToAction(const std::string& source) {
|
||||||
|
unsigned char dist = std::distance(actions.begin(), std::find(actions.begin(), actions.end(), source));
|
||||||
|
if (dist < _actionsSize)
|
||||||
|
return static_cast<Action>(dist);
|
||||||
|
|
||||||
|
return _actionsSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings::Action Settings::stringToAction(const std::string_view& source) {
|
||||||
|
unsigned char dist = std::distance(actions.begin(), std::find(actions.begin(), actions.end(), source));
|
||||||
|
if (dist < _actionsSize)
|
||||||
|
return static_cast<Action>(dist);
|
||||||
|
|
||||||
|
return _actionsSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings::Option Settings::stringToOption(const std::string& source) {
|
||||||
|
unsigned char dist = std::distance(options.begin(), std::find(options.begin(), options.end(), source));
|
||||||
|
if (dist < _optionsSize)
|
||||||
|
return static_cast<Option>(dist);
|
||||||
|
|
||||||
|
return _optionsSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
Settings::Type Settings::stringToType(const std::string& source) {
|
||||||
|
unsigned char dist = std::distance(types.begin(), std::find(types.begin(), types.end(), source));
|
||||||
|
if (dist < _typesSize)
|
||||||
|
return static_cast<Type>(dist);
|
||||||
|
|
||||||
|
return _typesSize;
|
||||||
|
}
|
||||||
|
@ -6,6 +6,11 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <functional>
|
||||||
|
#include <cctype>
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
#include "loggable.h"
|
#include "loggable.h"
|
||||||
|
|
||||||
@ -14,26 +19,53 @@ public:
|
|||||||
enum Action {
|
enum Action {
|
||||||
convert,
|
convert,
|
||||||
help,
|
help,
|
||||||
printConfig,
|
config,
|
||||||
_actionsSize
|
_actionsSize
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum Type {
|
||||||
|
mp3,
|
||||||
|
_typesSize
|
||||||
|
};
|
||||||
|
|
||||||
|
enum Option {
|
||||||
|
level,
|
||||||
|
type,
|
||||||
|
_optionsSize
|
||||||
|
};
|
||||||
|
|
||||||
Settings(int argc, char **argv);
|
Settings(int argc, char **argv);
|
||||||
|
|
||||||
std::string getInput() const;
|
std::string getInput() const;
|
||||||
std::string getOutput() const;
|
std::string getOutput() const;
|
||||||
|
std::string getConfigPath() const;
|
||||||
|
bool isConfigDefault() const;
|
||||||
Loggable::Severity getLogLevel() const;
|
Loggable::Severity getLogLevel() const;
|
||||||
|
Type getType() const;
|
||||||
Action getAction() const;
|
Action getAction() const;
|
||||||
|
|
||||||
|
bool readConfigFile();
|
||||||
|
void readConfigLine(const std::string& line);
|
||||||
|
std::string defaultConfig() const;
|
||||||
|
|
||||||
|
static Action stringToAction(const std::string& source);
|
||||||
|
static Action stringToAction(const std::string_view& source);
|
||||||
|
static Type stringToType(const std::string& source);
|
||||||
|
static Option stringToOption(const std::string& source);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parseArguments();
|
void parseArguments();
|
||||||
|
|
||||||
static std::string_view stripFlags(const std::string_view& option);
|
static std::string_view stripFlags(const std::string_view& option);
|
||||||
|
static void strip(std::string& line);
|
||||||
|
static void stripComment(std::string& line);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
std::vector<std::string_view> arguments;
|
std::vector<std::string_view> arguments;
|
||||||
std::optional<Action> action;
|
std::optional<Action> action;
|
||||||
|
std::optional<Type> outputType;
|
||||||
std::optional<std::string> input;
|
std::optional<std::string> input;
|
||||||
std::optional<std::string> output;
|
std::optional<std::string> output;
|
||||||
std::optional<Loggable::Severity> logLevel;
|
std::optional<Loggable::Severity> logLevel;
|
||||||
|
std::optional<std::string> configPath;
|
||||||
};
|
};
|
||||||
|
@ -22,7 +22,8 @@ constexpr const std::array<std::string_view, Loggable::fatal + 1> logHeaders({
|
|||||||
/*fatal*/ "FATAL: "
|
/*fatal*/ "FATAL: "
|
||||||
});
|
});
|
||||||
|
|
||||||
TaskManager::TaskManager():
|
TaskManager::TaskManager(const std::shared_ptr<Settings>& settings):
|
||||||
|
settings(settings),
|
||||||
busyThreads(0),
|
busyThreads(0),
|
||||||
maxTasks(0),
|
maxTasks(0),
|
||||||
completeTasks(0),
|
completeTasks(0),
|
||||||
@ -42,7 +43,7 @@ TaskManager::TaskManager():
|
|||||||
TaskManager::~TaskManager() {
|
TaskManager::~TaskManager() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskManager::queueJob(const std::string& source, const std::string& destination) {
|
void TaskManager::queueJob(const std::filesystem::path& source, const std::filesystem::path& destination) {
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(queueMutex);
|
std::unique_lock<std::mutex> lock(queueMutex);
|
||||||
jobs.emplace(source, destination);
|
jobs.emplace(source, destination);
|
||||||
@ -83,7 +84,13 @@ void TaskManager::loop() {
|
|||||||
jobs.pop();
|
jobs.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
JobResult result = job(pair.first, pair.second);
|
JobResult result;
|
||||||
|
switch (settings->getType()) {
|
||||||
|
case Settings::mp3:
|
||||||
|
result = mp3Job(pair.first, pair.second + ".mp3");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
++completeTasks;
|
++completeTasks;
|
||||||
printProgress(result, pair.first, pair.second);
|
printProgress(result, pair.first, pair.second);
|
||||||
--busyThreads;
|
--busyThreads;
|
||||||
@ -117,7 +124,7 @@ void TaskManager::wait() {
|
|||||||
waitConditional.wait(lock, boundWaitCondition);
|
waitConditional.wait(lock, boundWaitCondition);
|
||||||
}
|
}
|
||||||
|
|
||||||
TaskManager::JobResult TaskManager::job(const std::string& source, const std::string& destination) {
|
TaskManager::JobResult TaskManager::mp3Job(const std::filesystem::path& source, const std::filesystem::path& destination) {
|
||||||
FLACtoMP3 convertor(Loggable::debug);
|
FLACtoMP3 convertor(Loggable::debug);
|
||||||
convertor.setInputFile(source);
|
convertor.setInputFile(source);
|
||||||
convertor.setOutputFile(destination);
|
convertor.setOutputFile(destination);
|
||||||
@ -130,7 +137,11 @@ void TaskManager::printProgress() const {
|
|||||||
std::cout << "\r" << completeTasks << "/" << maxTasks << std::flush;
|
std::cout << "\r" << completeTasks << "/" << maxTasks << std::flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskManager::printProgress(const TaskManager::JobResult& result, const std::string& source, const std::string& destination) const {
|
void TaskManager::printProgress(
|
||||||
|
const TaskManager::JobResult& result,
|
||||||
|
const std::filesystem::path& source,
|
||||||
|
const std::filesystem::path& destination) const
|
||||||
|
{
|
||||||
std::unique_lock<std::mutex> lock(printMutex);
|
std::unique_lock<std::mutex> lock(printMutex);
|
||||||
if (result.first) {
|
if (result.first) {
|
||||||
if (result.second.size() > 0) {
|
if (result.second.size() > 0) {
|
||||||
@ -144,7 +155,11 @@ void TaskManager::printProgress(const TaskManager::JobResult& result, const std:
|
|||||||
std::cout << "\r" << completeTasks << "/" << maxTasks << std::flush;
|
std::cout << "\r" << completeTasks << "/" << maxTasks << std::flush;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TaskManager::printLog(const TaskManager::JobResult& result, const std::string& source, const std::string& destination) {
|
void TaskManager::printLog(
|
||||||
|
const TaskManager::JobResult& result,
|
||||||
|
const std::filesystem::path& source,
|
||||||
|
const std::filesystem::path& destination)
|
||||||
|
{
|
||||||
std::cout << "Source: \t" << source << std::endl;
|
std::cout << "Source: \t" << source << std::endl;
|
||||||
std::cout << "Destination: \t" << destination << std::endl;
|
std::cout << "Destination: \t" << destination << std::endl;
|
||||||
for (const Loggable::Message& msg : result.second) {
|
for (const Loggable::Message& msg : result.second) {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
#include <filesystem>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
@ -11,30 +12,33 @@
|
|||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <array>
|
#include <array>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
#include "loggable.h"
|
#include "loggable.h"
|
||||||
|
#include "settings.h"
|
||||||
|
|
||||||
class TaskManager {
|
class TaskManager {
|
||||||
typedef std::pair<bool, std::list<Loggable::Message>> JobResult;
|
typedef std::pair<bool, std::list<Loggable::Message>> JobResult;
|
||||||
public:
|
public:
|
||||||
TaskManager();
|
TaskManager(const std::shared_ptr<Settings>& settings);
|
||||||
~TaskManager();
|
~TaskManager();
|
||||||
|
|
||||||
void start();
|
void start();
|
||||||
void queueJob(const std::string& source, const std::string& destination);
|
void queueJob(const std::filesystem::path& source, const std::filesystem::path& destination);
|
||||||
void stop();
|
void stop();
|
||||||
bool busy() const;
|
bool busy() const;
|
||||||
void wait();
|
void wait();
|
||||||
void printProgress() const;
|
void printProgress() const;
|
||||||
void printProgress(const JobResult& result, const std::string& source, const std::string& destination) const;
|
void printProgress(const JobResult& result, const std::filesystem::path& source, const std::filesystem::path& destination) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void loop();
|
void loop();
|
||||||
bool loopCondition() const;
|
bool loopCondition() const;
|
||||||
bool waitCondition() const;
|
bool waitCondition() const;
|
||||||
static JobResult job(const std::string& source, const std::string& destination);
|
static JobResult mp3Job(const std::filesystem::path& source, const std::filesystem::path& destination);
|
||||||
static void printLog(const JobResult& result, const std::string& source, const std::string& destination);
|
static void printLog(const JobResult& result, const std::filesystem::path& source, const std::filesystem::path& destination);
|
||||||
private:
|
private:
|
||||||
|
std::shared_ptr<Settings> settings;
|
||||||
std::atomic<uint32_t> busyThreads;
|
std::atomic<uint32_t> busyThreads;
|
||||||
std::atomic<uint32_t> maxTasks;
|
std::atomic<uint32_t> maxTasks;
|
||||||
std::atomic<uint32_t> completeTasks;
|
std::atomic<uint32_t> completeTasks;
|
||||||
@ -45,7 +49,7 @@ private:
|
|||||||
std::condition_variable loopConditional;
|
std::condition_variable loopConditional;
|
||||||
std::condition_variable waitConditional;
|
std::condition_variable waitConditional;
|
||||||
std::vector<std::thread> threads;
|
std::vector<std::thread> threads;
|
||||||
std::queue<std::pair<std::string, std::string>> jobs;
|
std::queue<std::pair<std::filesystem::path, std::filesystem::path>> jobs;
|
||||||
std::function<bool()> boundLoopCondition;
|
std::function<bool()> boundLoopCondition;
|
||||||
std::function<bool()> boundWaitCondition;
|
std::function<bool()> boundWaitCondition;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user