add _substr_[pos]_[len] to picture download templates (#4762)

This commit is contained in:
ebbit1q 2023-04-02 04:29:57 +02:00 committed by GitHub
parent f5f8acf1fd
commit 9ce450d0b0
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -239,6 +239,79 @@ bool PictureLoaderWorker::cardImageExistsOnDisk(QString &setName, QString &corre
return false; return false;
} }
static int parse(const QString &urlTemplate,
const QString &propType,
const QString &cardName,
const QString &setName,
std::function<QString(const QString &)> getProperty,
QMap<QString, QString> &transformMap)
{
static const QRegularExpression rxFillWith("^(.+)_fill_with_(.+)$");
static const QRegularExpression rxSubStr("^(.+)_substr_(\\d+)_(\\d+)$");
const QRegularExpression rxCardProp("!" + propType + ":([^!]+)!");
auto matches = rxCardProp.globalMatch(urlTemplate);
while (matches.hasNext()) {
auto match = matches.next();
QString templatePropertyName = match.captured(1);
auto fillMatch = rxFillWith.match(templatePropertyName);
QString cardPropertyName;
QString fillWith;
int subStrPos = 0;
int subStrLen = -1;
if (fillMatch.hasMatch()) {
cardPropertyName = fillMatch.captured(1);
fillWith = fillMatch.captured(2);
} else {
fillWith = QString();
auto subStrMatch = rxSubStr.match(templatePropertyName);
if (subStrMatch.hasMatch()) {
cardPropertyName = subStrMatch.captured(1);
subStrPos = subStrMatch.captured(2).toInt();
subStrLen = subStrMatch.captured(3).toInt();
} else {
cardPropertyName = templatePropertyName;
}
}
QString propertyValue = getProperty(cardPropertyName);
if (propertyValue.isEmpty()) {
qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested "
<< propType << "property (" << cardPropertyName << ") for Url template (" << urlTemplate
<< ") is not available";
return 1;
} else {
int propLength = propertyValue.length();
if (subStrLen > 0 && subStrPos + subStrLen > propLength) {
qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested "
<< propType << " property (" << cardPropertyName << ") for Url template ("
<< urlTemplate << ") is smaller than substr specification (" << subStrPos << " + "
<< subStrLen << " > " << propLength << ")";
return 1;
} else {
propertyValue = propertyValue.mid(subStrPos, subStrLen);
propLength = subStrLen;
}
if (!fillWith.isEmpty()) {
int fillLength = fillWith.length();
if (fillLength < propLength) {
qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName << "]: Requested "
<< propType << " property (" << cardPropertyName << ") for Url template ("
<< urlTemplate << ") is longer than fill specification (" << fillWith << ")";
return 1;
} else {
propertyValue = fillWith.left(fillLength - propLength) + propertyValue;
}
}
transformMap["!" + propType + ":" + templatePropertyName + "!"] = propertyValue;
}
}
return 0;
}
QString PictureToLoad::transformUrl(const QString &urlTemplate) const QString PictureToLoad::transformUrl(const QString &urlTemplate) const
{ {
/* This function takes Url templates and substitutes actual card details /* This function takes Url templates and substitutes actual card details
@ -246,56 +319,23 @@ QString PictureToLoad::transformUrl(const QString &urlTemplate) const
for downloading images. If information is requested by the template that is for downloading images. If information is requested by the template that is
not populated for this specific card/set combination, an empty string is returned.*/ not populated for this specific card/set combination, an empty string is returned.*/
static const QRegularExpression rxCardProp("!prop:([^!]+)!");
static const QRegularExpression rxFillWith("^(.+)_fill_with_(.+)$");
static const QRegularExpression rxSetProp("!set:([^!]+)!");
QString transformedUrl = urlTemplate;
CardSetPtr set = getCurrentSet(); CardSetPtr set = getCurrentSet();
QMap<QString, QString> transformMap = QMap<QString, QString>(); QMap<QString, QString> transformMap = QMap<QString, QString>();
QString setName = getSetName();
// name // name
transformMap["!name!"] = card->getName(); QString cardName = card->getName();
transformMap["!name!"] = cardName;
transformMap["!name_lower!"] = card->getName().toLower(); transformMap["!name_lower!"] = card->getName().toLower();
transformMap["!corrected_name!"] = card->getCorrectedName(); transformMap["!corrected_name!"] = card->getCorrectedName();
transformMap["!corrected_name_lower!"] = card->getCorrectedName().toLower(); transformMap["!corrected_name_lower!"] = card->getCorrectedName().toLower();
// card properties // card properties
auto matches = rxCardProp.globalMatch(transformedUrl); if (parse(
while (matches.hasNext()) { urlTemplate, "prop", cardName, setName, [&](const QString &name) { return card->getProperty(name); },
auto match = matches.next(); transformMap)) {
QString propertyName = match.captured(1); return QString();
auto fillMatch = rxFillWith.match(propertyName);
QString fillPropertyName;
QString fillWith;
if (fillMatch.hasMatch()) {
fillPropertyName = fillMatch.captured(1);
fillWith = fillMatch.captured(2);
} else {
fillPropertyName = propertyName;
fillWith = QString();
}
QString propertyValue = card->getProperty(fillPropertyName);
if (propertyValue.isEmpty()) {
qDebug() << "PictureLoader: [card: " << card->getName() << " set: " << getSetName()
<< "]: Requested property (" << fillPropertyName << ") for Url template (" << urlTemplate
<< ") is not available";
return QString();
} else {
if (!fillWith.isEmpty()) {
int fillLength = fillWith.length();
int propLength = propertyValue.length();
if (fillLength < propLength) {
qDebug() << "PictureLoader: [card: " << card->getName() << " set: " << getSetName()
<< "]: Requested property (" << fillPropertyName << ") for Url template (" << urlTemplate
<< ") is longer than fill specification (" << fillWith << ")";
return QString();
} else {
propertyValue = fillWith.left(fillLength - propLength) + propertyValue;
}
}
transformMap["!prop:" + propertyName + "!"] = propertyValue;
}
} }
if (set) { if (set) {
@ -304,41 +344,10 @@ QString PictureToLoad::transformUrl(const QString &urlTemplate) const
transformMap["!setname!"] = set->getLongName(); transformMap["!setname!"] = set->getLongName();
transformMap["!setname_lower!"] = set->getLongName().toLower(); transformMap["!setname_lower!"] = set->getLongName().toLower();
auto matches = rxSetProp.globalMatch(transformedUrl); if (parse(
while (matches.hasNext()) { urlTemplate, "set", cardName, setName,
auto match = matches.next(); [&](const QString &name) { return card->getSetProperty(set->getShortName(), name); }, transformMap)) {
QString propertyName = match.captured(1); return QString();
auto fillMatch = rxFillWith.match(propertyName);
QString fillPropertyName;
QString fillWith;
if (fillMatch.hasMatch()) {
fillPropertyName = fillMatch.captured(1);
fillWith = fillMatch.captured(2);
} else {
fillPropertyName = propertyName;
fillWith = QString();
}
QString propertyValue = card->getSetProperty(set->getShortName(), fillPropertyName);
if (propertyValue.isEmpty()) {
qDebug() << "PictureLoader: [card: " << card->getName() << " set: " << getSetName()
<< "]: Requested set property (" << fillPropertyName << ") for Url template (" << urlTemplate
<< ") is not available";
return QString();
} else {
if (!fillWith.isEmpty()) {
int fillLength = fillWith.length();
int propLength = propertyValue.length();
if (fillLength < propLength) {
qDebug() << "PictureLoader: [card: " << card->getName() << " set: " << getSetName()
<< "]: Requested set property (" << fillPropertyName << ") for Url template ("
<< urlTemplate << ") is longer than fill specification (" << fillWith << ")";
return QString();
} else {
propertyValue = fillWith.left(fillLength - propLength) + propertyValue;
}
}
transformMap["!set:" + propertyName + "!"] = propertyValue;
}
} }
} }
@ -346,6 +355,7 @@ QString PictureToLoad::transformUrl(const QString &urlTemplate) const
transformMap["!sflang!"] = QString(QCoreApplication::translate( transformMap["!sflang!"] = QString(QCoreApplication::translate(
"PictureLoader", "en", "code for scryfall's language property, not available for all languages")); "PictureLoader", "en", "code for scryfall's language property, not available for all languages"));
QString transformedUrl = urlTemplate;
for (const QString &prop : transformMap.keys()) { for (const QString &prop : transformMap.keys()) {
if (transformedUrl.contains(prop)) { if (transformedUrl.contains(prop)) {
if (!transformMap[prop].isEmpty()) { if (!transformMap[prop].isEmpty()) {
@ -355,9 +365,9 @@ QString PictureToLoad::transformUrl(const QString &urlTemplate) const
* populated in this card, so it should return an empty string, * populated in this card, so it should return an empty string,
* indicating an invalid Url. * indicating an invalid Url.
*/ */
qDebug() << "PictureLoader: [card: " << card->getName() << " set: " << getSetName() qDebug().nospace() << "PictureLoader: [card: " << cardName << " set: " << setName
<< "]: Requested information (" << prop << ") for Url template (" << urlTemplate << "]: Requested information (" << prop << ") for Url template (" << urlTemplate
<< ") is not available"; << ") is not available";
return QString(); return QString();
} }
} }