diff --git a/CHANGELOG.md b/CHANGELOG.md index 8fa2da4..2f4c444 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # Changelog -## MLC 1.3.0 (UNRELEASED) +## MLC 1.3.0 (October 09, 2023) - Config file to control the process +- First help page - Program modes concept to implement config print and help ## MLC 1.2.0 (August 11, 2023) diff --git a/CMakeLists.txt b/CMakeLists.txt index ea5a1f7..3114df2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.5) project( mlc - VERSION 1.2.0 + VERSION 1.3.0 DESCRIPTION "Media Library Compiler: rips your media library to a lossy compilation" LANGUAGES CXX ) diff --git a/README.md b/README.md index d356f93..8d3f250 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ This is a program for compilation of your loseless music library to lossy format - flac - lame - jpeg +- taglib ### Building diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 26c19d8..07770c0 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -29,4 +29,5 @@ target_sources(${PROJECT_NAME} PRIVATE ${SOURCES}) add_subdirectory(logger) make_includable(default.conf ${CMAKE_BINARY_DIR}/generated/default.conf) +make_includable(help ${CMAKE_BINARY_DIR}/generated/help) target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_BINARY_DIR}) diff --git a/src/default.conf b/src/default.conf index 8f23d3c..67fd2ef 100644 --- a/src/default.conf +++ b/src/default.conf @@ -1,6 +1,7 @@ # This is a default autogenerated MLC config # The syntax goes like this: # key value +# Only the first occasion of the valid key value pair is taken to consideration # # Use # sign for comments # @@ -15,9 +16,31 @@ # 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 +# Allowed values are: [debug, info, minor, major, warning, error, fatal] #level info # Output type -# Allowed values are: mp3 (more comming soon) +# Allowed values are: [mp3] (more comming soon) #type mp3 + +# Source collection path +# This is a default path to your music collection source. +# It's usefull to set it when you always encode the same collection +# Leaving this empty (as it is by default) will make you always +# specify source in the command line +#source + +# Destingation path +# This is a default path for your encoding destination +# It's usefull to set it when you often encode your collection +# to the same output +# Leaving this empty (as it is by default) will make you always +# specify destination in the command line +#destination + +# Parallel tasks +# Defines how many threads are going to be started in parralel +# Allowed values are [0, 1, 2, 3 ...] etc +# If it's set to 0 - amount of threads is going to be +# as high as your processor can effectively handle +#parallel 0 diff --git a/src/help b/src/help new file mode 100644 index 0000000..34356f5 --- /dev/null +++ b/src/help @@ -0,0 +1,42 @@ +Usage: + mlc [action] [arguments] [flags] + +Actions: + convert - converts music + config - prints default config + help - prints this page + +Default action is `convert`, so it can be omitted + +Arguments work only for `convert` action + first - collection source + second - collection destination + +Flags: + -c (--config) + - sets custom config instead of default one + + -h (--help) + - sets action to help, and prints this page + +Examples: + `mlc ~/Music comile/latest` + - reads config file from `~/.config/mlc.conf` + - if there was not - creates default that changes nothing + - creates directory `conpile` in the CURRENT directory if it was not created before + - create `latest` directory in `compile` dirrectory if it was not created before + - searches for music in `~/Music` directory + - converts all music to `comile/latest` directory + - copies all other files found in `~/Music` to `comile/latest` + - any file name overlap will be overriden + + `mlc config > myConfig.conf` + - prints default config to standard output + - unix operator `>` redirects output to a file `myConfig.conf` + + `mlc rip -c myConfig.conf` + - reads file `myConfig.conf` from current directory + - if `myConfig.conf` has a valid `source` entry - uses it and uses `rip` as destination + - if `myConfig.conf` has a valid `destination` entry - uses it and uses `rip` as source + - if both present (don't do this way) - it depends on the order, who comes first - defines behaviour + - the rest is the same from the first example apart from default config diff --git a/src/help.cpp b/src/help.cpp index 98be0d9..2d8a1a4 100644 --- a/src/help.cpp +++ b/src/help.cpp @@ -2,6 +2,10 @@ #include "iostream" +static const char* help = +#include "generated/help" +; + void printHelp() { - std::cout << "Sorry, there is no help yet. It will arrive one day... I hope" << std::endl; + std::cout << help << std::endl; } diff --git a/src/settings.cpp b/src/settings.cpp index 01dc1a3..019eff5 100644 --- a/src/settings.cpp +++ b/src/settings.cpp @@ -4,15 +4,39 @@ static const char* defaultConfig = #include "generated/default.conf" ; +enum class Flag { + config, + help, + none +}; + +enum class Option { + level, + type, + source, + destination, + parallel, + _optionsSize +}; + +using Literals = std::array; +constexpr std::array(Flag::none)> flags({{ + {"-c", "--config"}, + {"-h", "--help"} +}}); + constexpr std::array actions({ "convert", "help", "config" }); -constexpr std::array options({ +constexpr std::array(Option::_optionsSize)> options({ "level", - "type" + "type", + "source", + "destination", + "parallel" }); constexpr std::array types({ @@ -23,6 +47,25 @@ bool is_space(char ch){ return std::isspace(static_cast(ch)); } +Flag getFlag(const std::string_view arg) { + for (int i = 0; i < flags.size(); ++i) { + const Literals& lit = flags[i]; + unsigned char dist = std::distance(lit.begin(), std::find(lit.begin(), lit.end(), arg)); + if (dist < lit.size()) + return static_cast(i); + } + + return Flag::none; +} + +Option stringToOption(const std::string& source) { + unsigned char dist = std::distance(options.begin(), std::find(options.begin(), options.end(), source)); + if (dist < static_cast(Option::_optionsSize)) + return static_cast