diff --git a/include/util.h b/include/util.h index 5ef5b5c..769b591 100644 --- a/include/util.h +++ b/include/util.h @@ -102,6 +102,7 @@ namespace Util return std::string(buf.get(), buf.get() + sz - 1); // -1 because we don't want the null terminator } Json::Value readJsonFile(const std::string& path); + std::string transformGamename(const std::string& gamename); } #endif // UTIL_H diff --git a/man/lgogdownloader.supplemental.groff b/man/lgogdownloader.supplemental.groff index a81a506..34921da 100644 --- a/man/lgogdownloader.supplemental.groff +++ b/man/lgogdownloader.supplemental.groff @@ -120,6 +120,10 @@ Must be in the following format: { "regex" : , "replacement" : , + "exceptions" : [ + , + , + ], }, : { @@ -129,18 +133,27 @@ Must be in the following format: .br } .br -Member names are used to match the gamename. +Member names are used to match the gamename (regex). +Member names must be unique. +.br +For example if the file contains 2 rules with "^x" then only the last one is applied. However if user really wants multiple different rules for everything starting with "x" then adding wild wildcard matches makes them unique ("^x", "^x.*", "^x.*.*") +.br If it matches then \fBregex\fP is used for the actual replacement using the value in \fBreplacement\fP. .br +"\fBexceptions\fP" is an optional array of gamenames excluded from the rule. These are matched exactly, no regex. +.br \fBExample:\fP .br -match all games beginning with "\fBb\fP" and if they end with "\fB_the\fP" then remove "\fB_the\fP" at the end and prefix it with "\fBthe_\fP" +match all games beginning with "\fBb\fP" and if they end with "\fB_the\fP" then remove "\fB_the\fP" at the end and prefix it with "\fBthe_\fP" with exception of "\fBblackwell_epiphany_the\fP" .br { "^b" : { "regex" : "(.*)_the$", "replacement" : "the_\\\\1", + "exceptions" : [ + "blackwell_epiphany_the", + ], }, .br } diff --git a/src/downloader.cpp b/src/downloader.cpp index 8696058..5aed242 100644 --- a/src/downloader.cpp +++ b/src/downloader.cpp @@ -526,9 +526,7 @@ int Downloader::listGames() std::string gamename = gameItems[i].name; if (Globals::globalConfig.iListFormat == GlobalConstants::LIST_FORMAT_TRANSFORMATIONS) { - std::string str = "%gamename% -> %gamename_transformed%"; - Util::filepathReplaceReservedStrings(str, gamename); - std::cout << str << std::endl; + std::cout << gamename << " -> " << Util::transformGamename(gamename) << std::endl; } else { diff --git a/src/util.cpp b/src/util.cpp index 80fe4ae..316f5cf 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -438,21 +438,9 @@ void Util::filepathReplaceReservedStrings(std::string& str, const std::string& g gamename_firstletter = gamename.front(); } - std::string gamename_transformed = gamename; if (str.find("%gamename_transformed%") != std::string::npos || str.find("%gamename_transformed_firstletter%") != std::string::npos) { - for (auto transformMatch : Globals::globalConfig.transformationsJSON.getMemberNames()) - { - boost::regex expression(transformMatch); - boost::match_results what; - if (boost::regex_search(gamename_transformed, what, expression)) - { - boost::regex transformRegex(Globals::globalConfig.transformationsJSON[transformMatch]["regex"].asString()); - std::string transformReplacement = Globals::globalConfig.transformationsJSON[transformMatch]["replacement"].asString(); - gamename_transformed = boost::regex_replace(gamename_transformed, transformRegex, transformReplacement); - } - } - + std::string gamename_transformed = transformGamename(gamename); std::string gamename_transformed_firstletter; if (!gamename_transformed.empty()) { @@ -963,3 +951,40 @@ Json::Value Util::readJsonFile(const std::string& path) return json; } + +std::string Util::transformGamename(const std::string& gamename) +{ + std::string gamename_transformed = gamename; + for (auto transformMatch : Globals::globalConfig.transformationsJSON.getMemberNames()) + { + boost::regex expression(transformMatch); + boost::match_results what; + if (boost::regex_search(gamename_transformed, what, expression)) + { + // Get list of exceptions + std::vector vExceptions; + if (Globals::globalConfig.transformationsJSON[transformMatch].isMember("exceptions")) + { + if (Globals::globalConfig.transformationsJSON[transformMatch]["exceptions"].isArray()) + { + for (auto exception : Globals::globalConfig.transformationsJSON[transformMatch]["exceptions"]) + vExceptions.push_back(exception.asString()); + } + else + { + vExceptions.push_back(Globals::globalConfig.transformationsJSON[transformMatch]["exceptions"].asString()); + } + } + + // Skip if gamename matches exception + if (std::any_of(vExceptions.begin(), vExceptions.end(), [gamename](std::string exception){return exception == gamename;})) + continue; + + boost::regex transformRegex(Globals::globalConfig.transformationsJSON[transformMatch]["regex"].asString()); + std::string transformReplacement = Globals::globalConfig.transformationsJSON[transformMatch]["replacement"].asString(); + gamename_transformed = boost::regex_replace(gamename_transformed, transformRegex, transformReplacement); + } + } + + return gamename_transformed; +}