Add support for exceptions in transformation rules

This commit is contained in:
Sude 2023-04-26 13:57:47 +03:00
parent b4fdc2929c
commit 06c033eda1
4 changed files with 55 additions and 18 deletions

View File

@ -102,6 +102,7 @@ namespace Util
return std::string(buf.get(), buf.get() + sz - 1); // -1 because we don't want the null terminator 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); Json::Value readJsonFile(const std::string& path);
std::string transformGamename(const std::string& gamename);
} }
#endif // UTIL_H #endif // UTIL_H

View File

@ -120,6 +120,10 @@ Must be in the following format:
{ {
"regex" : <string>, "regex" : <string>,
"replacement" : <string>, "replacement" : <string>,
"exceptions" : [
<string>,
<string>,
],
}, },
<string> : <string> :
{ {
@ -129,18 +133,27 @@ Must be in the following format:
.br .br
} }
.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. If it matches then \fBregex\fP is used for the actual replacement using the value in \fBreplacement\fP.
.br .br
"\fBexceptions\fP" is an optional array of gamenames excluded from the rule. These are matched exactly, no regex.
.br
\fBExample:\fP \fBExample:\fP
.br .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 .br
{ {
"^b" : "^b" :
{ {
"regex" : "(.*)_the$", "regex" : "(.*)_the$",
"replacement" : "the_\\\\1", "replacement" : "the_\\\\1",
"exceptions" : [
"blackwell_epiphany_the",
],
}, },
.br .br
} }

View File

@ -526,9 +526,7 @@ int Downloader::listGames()
std::string gamename = gameItems[i].name; std::string gamename = gameItems[i].name;
if (Globals::globalConfig.iListFormat == GlobalConstants::LIST_FORMAT_TRANSFORMATIONS) if (Globals::globalConfig.iListFormat == GlobalConstants::LIST_FORMAT_TRANSFORMATIONS)
{ {
std::string str = "%gamename% -> %gamename_transformed%"; std::cout << gamename << " -> " << Util::transformGamename(gamename) << std::endl;
Util::filepathReplaceReservedStrings(str, gamename);
std::cout << str << std::endl;
} }
else else
{ {

View File

@ -438,21 +438,9 @@ void Util::filepathReplaceReservedStrings(std::string& str, const std::string& g
gamename_firstletter = gamename.front(); 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) if (str.find("%gamename_transformed%") != std::string::npos || str.find("%gamename_transformed_firstletter%") != std::string::npos)
{ {
for (auto transformMatch : Globals::globalConfig.transformationsJSON.getMemberNames()) std::string gamename_transformed = transformGamename(gamename);
{
boost::regex expression(transformMatch);
boost::match_results<std::string::const_iterator> 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_firstletter; std::string gamename_transformed_firstletter;
if (!gamename_transformed.empty()) if (!gamename_transformed.empty())
{ {
@ -963,3 +951,40 @@ Json::Value Util::readJsonFile(const std::string& path)
return json; 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<std::string::const_iterator> what;
if (boost::regex_search(gamename_transformed, what, expression))
{
// Get list of exceptions
std::vector<std::string> 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;
}