Oracle / card xml improvements (#3934)

* fix #1610

* fix #2679; partially fix #3647

* Fix tests

* Remove debug code
This commit is contained in:
ctrlaltca 2020-03-30 21:56:03 +02:00 committed by GitHub
parent a135ad064a
commit 27b7ebe208
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 131 additions and 10 deletions

View file

@ -6,6 +6,8 @@
#include <QIODevice>
#include <QString>
#define COCKATRICE_XML_XSI_NAMESPACE "http://www.w3.org/2001/XMLSchema-instance"
class ICardDatabaseParser : public QObject
{
public:
@ -13,7 +15,11 @@ public:
virtual bool getCanParseFile(const QString &name, QIODevice &device) = 0;
virtual void parseFile(QIODevice &device) = 0;
virtual bool saveToFile(SetNameMap sets, CardNameMap cards, const QString &fileName) = 0;
virtual bool saveToFile(SetNameMap sets,
CardNameMap cards,
const QString &fileName,
const QString &sourceUrl = "unknown",
const QString &sourceVersion = "unknown") = 0;
static void clearSetlist();
protected:

View file

@ -1,11 +1,15 @@
#include "cockatricexml3.h"
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QXmlStreamReader>
#include <version_string.h>
#define COCKATRICE_XML3_TAGNAME "cockatrice_carddatabase"
#define COCKATRICE_XML3_TAGVER 3
#define COCKATRICE_XML3_SCHEMALOCATION \
"https://raw.githubusercontent.com/Cockatrice/Cockatrice/master/doc/carddatabase_v3/cards.xsd"
bool CockatriceXml3Parser::getCanParseFile(const QString &fileName, QIODevice &device)
{
@ -403,7 +407,11 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
return xml;
}
bool CockatriceXml3Parser::saveToFile(SetNameMap sets, CardNameMap cards, const QString &fileName)
bool CockatriceXml3Parser::saveToFile(SetNameMap sets,
CardNameMap cards,
const QString &fileName,
const QString &sourceUrl,
const QString &sourceVersion)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly)) {
@ -416,6 +424,15 @@ bool CockatriceXml3Parser::saveToFile(SetNameMap sets, CardNameMap cards, const
xml.writeStartDocument();
xml.writeStartElement(COCKATRICE_XML3_TAGNAME);
xml.writeAttribute("version", QString::number(COCKATRICE_XML3_TAGVER));
xml.writeAttribute("xmlns:xsi", COCKATRICE_XML_XSI_NAMESPACE);
xml.writeAttribute("xsi:schemaLocation", COCKATRICE_XML3_SCHEMALOCATION);
xml.writeStartElement("info");
xml.writeTextElement("author", QCoreApplication::applicationName() + QString(" %1").arg(VERSION_STRING));
xml.writeTextElement("createdAt", QDateTime::currentDateTimeUtc().toString(Qt::ISODate));
xml.writeTextElement("sourceUrl", sourceUrl);
xml.writeTextElement("sourceVersion", sourceVersion);
xml.writeEndElement();
if (sets.count() > 0) {
xml.writeStartElement("sets");

View file

@ -14,7 +14,11 @@ public:
~CockatriceXml3Parser() override = default;
bool getCanParseFile(const QString &name, QIODevice &device) override;
void parseFile(QIODevice &device) override;
bool saveToFile(SetNameMap sets, CardNameMap cards, const QString &fileName) override;
bool saveToFile(SetNameMap sets,
CardNameMap cards,
const QString &fileName,
const QString &sourceUrl = "unknown",
const QString &sourceVersion = "unknown") override;
private:
void loadCardsFromXml(QXmlStreamReader &xml);

View file

@ -1,11 +1,15 @@
#include "cockatricexml4.h"
#include <QCoreApplication>
#include <QDebug>
#include <QFile>
#include <QXmlStreamReader>
#include <version_string.h>
#define COCKATRICE_XML4_TAGNAME "cockatrice_carddatabase"
#define COCKATRICE_XML4_TAGVER 4
#define COCKATRICE_XML4_SCHEMALOCATION \
"https://raw.githubusercontent.com/Cockatrice/Cockatrice/master/doc/carddatabase_v4/cards.xsd"
bool CockatriceXml4Parser::getCanParseFile(const QString &fileName, QIODevice &device)
{
@ -329,7 +333,11 @@ static QXmlStreamWriter &operator<<(QXmlStreamWriter &xml, const CardInfoPtr &in
return xml;
}
bool CockatriceXml4Parser::saveToFile(SetNameMap sets, CardNameMap cards, const QString &fileName)
bool CockatriceXml4Parser::saveToFile(SetNameMap sets,
CardNameMap cards,
const QString &fileName,
const QString &sourceUrl,
const QString &sourceVersion)
{
QFile file(fileName);
if (!file.open(QIODevice::WriteOnly)) {
@ -342,6 +350,15 @@ bool CockatriceXml4Parser::saveToFile(SetNameMap sets, CardNameMap cards, const
xml.writeStartDocument();
xml.writeStartElement(COCKATRICE_XML4_TAGNAME);
xml.writeAttribute("version", QString::number(COCKATRICE_XML4_TAGVER));
xml.writeAttribute("xmlns:xsi", COCKATRICE_XML_XSI_NAMESPACE);
xml.writeAttribute("xsi:schemaLocation", COCKATRICE_XML4_SCHEMALOCATION);
xml.writeStartElement("info");
xml.writeTextElement("author", QCoreApplication::applicationName() + QString(" %1").arg(VERSION_STRING));
xml.writeTextElement("createdAt", QDateTime::currentDateTimeUtc().toString(Qt::ISODate));
xml.writeTextElement("sourceUrl", sourceUrl);
xml.writeTextElement("sourceVersion", sourceVersion);
xml.writeEndElement();
if (sets.count() > 0) {
xml.writeStartElement("sets");

View file

@ -14,7 +14,11 @@ public:
~CockatriceXml4Parser() override = default;
bool getCanParseFile(const QString &name, QIODevice &device) override;
void parseFile(QIODevice &device) override;
bool saveToFile(SetNameMap sets, CardNameMap cards, const QString &fileName) override;
bool saveToFile(SetNameMap sets,
CardNameMap cards,
const QString &fileName,
const QString &sourceUrl = "unknown",
const QString &sourceVersion = "unknown") override;
private:
QVariantHash loadCardPropertiesFromXml(QXmlStreamReader &xml);

View file

@ -11,6 +11,16 @@
<xs:element name="cockatrice_carddatabase">
<xs:complexType>
<xs:all>
<xs:element name="info" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:all>
<xs:element type="xs:string" name="author" minOccurs="0" maxOccurs="1" />
<xs:element type="xs:string" name="createdAt" minOccurs="0" maxOccurs="1" />
<xs:element type="xs:string" name="sourceUrl" minOccurs="0" maxOccurs="1" />
<xs:element type="xs:string" name="sourceVersion" minOccurs="0" maxOccurs="1" />
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="sets" minOccurs="0">
<xs:complexType>
<xs:sequence>

View file

@ -57,6 +57,16 @@
<xs:element name="cockatrice_carddatabase">
<xs:complexType>
<xs:sequence>
<xs:element name="info" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:all>
<xs:element type="xs:string" name="author" minOccurs="0" maxOccurs="1" />
<xs:element type="xs:string" name="createdAt" minOccurs="0" maxOccurs="1" />
<xs:element type="xs:string" name="sourceUrl" minOccurs="0" maxOccurs="1" />
<xs:element type="xs:string" name="sourceVersion" minOccurs="0" maxOccurs="1" />
</xs:all>
</xs:complexType>
</xs:element>
<xs:element name="sets" minOccurs="0">
<xs:complexType>
<xs:sequence>

View file

@ -459,10 +459,10 @@ int OracleImporter::startImport()
return setIndex;
}
bool OracleImporter::saveToFile(const QString &fileName)
bool OracleImporter::saveToFile(const QString &fileName, const QString &sourceUrl, const QString &sourceVersion)
{
CockatriceXml4Parser parser;
return parser.saveToFile(sets, cards, fileName);
return parser.saveToFile(sets, cards, fileName, sourceUrl, sourceVersion);
}
void OracleImporter::clear()

View file

@ -110,7 +110,7 @@ public:
explicit OracleImporter(const QString &_dataDir, QObject *parent = nullptr);
bool readSetsFromByteArray(const QByteArray &data);
int startImport();
bool saveToFile(const QString &fileName);
bool saveToFile(const QString &fileName, const QString &sourceUrl, const QString &sourceVersion);
int importCardsFromSet(CardSetPtr currentSet, const QList<QVariant> &cards, bool skipSpecialNums = true);
QList<SetToDownload> &getSets()
{

View file

@ -39,6 +39,7 @@
// Xz stream header: 0xFD + "7zXZ"
#define XZ_SIGNATURE "\xFD\x37\x7A\x58\x5A"
#define ALLSETS_URL_FALLBACK "https://www.mtgjson.com/files/AllPrintings.json"
#define MTGJSON_VERSION_URL "https://www.mtgjson.com/files/version.json"
#ifdef HAS_LZMA
#define ALLSETS_URL "https://www.mtgjson.com/files/AllPrintings.json.xz"
@ -331,14 +332,46 @@ bool LoadSetsPage::validatePage()
wizard()->disableButtons();
setEnabled(false);
wizard()->setCardSourceUrl(setsFile.fileName());
wizard()->setCardSourceVersion("unknown");
readSetsFromByteArray(setsFile.readAll());
}
return false;
}
#include <iostream>
void LoadSetsPage::downloadSetsFile(QUrl url)
{
wizard()->setCardSourceVersion("unknown");
QString urlString = url.toString();
if (urlString == ALLSETS_URL || urlString == ALLSETS_URL_FALLBACK) {
QUrl versionUrl = QUrl::fromUserInput(MTGJSON_VERSION_URL);
QNetworkReply *versionReply = wizard()->nam->get(QNetworkRequest(versionUrl));
connect(versionReply, &QNetworkReply::finished, [this, versionReply]() {
if (versionReply->error() == QNetworkReply::NoError) {
QByteArray jsonData = versionReply->readAll();
QJsonParseError jsonError;
QJsonDocument jsonResponse = QJsonDocument::fromJson(jsonData, &jsonError);
if (jsonError.error == QJsonParseError::NoError) {
QVariantMap jsonMap = jsonResponse.toVariant().toMap();
QString versionString = jsonMap["version"].toString();
if (versionString.isEmpty()) {
versionString = "unknown";
}
wizard()->setCardSourceVersion(versionString);
}
}
versionReply->deleteLater();
});
}
wizard()->setCardSourceUrl(url.toString());
QNetworkReply *reply = wizard()->nam->get(QNetworkRequest(url));
connect(reply, SIGNAL(finished()), this, SLOT(actDownloadFinishedSetsFile()));
@ -597,7 +630,7 @@ bool SaveSetsPage::validatePage()
return false;
}
if (wizard()->importer->saveToFile(fileName)) {
if (wizard()->importer->saveToFile(fileName, wizard()->getCardSourceUrl(), wizard()->getCardSourceVersion())) {
ok = true;
} else {
QMessageBox::critical(this, tr("Error"), tr("The file could not be saved to %1").arg(fileName));

View file

@ -38,6 +38,22 @@ public:
{
return !tokensData.isEmpty();
}
void setCardSourceUrl(const QString &sourceUrl)
{
cardSourceUrl = sourceUrl;
}
void setCardSourceVersion(const QString &sourceVersion)
{
cardSourceVersion = sourceVersion;
}
const QString &getCardSourceUrl() const
{
return cardSourceUrl;
}
const QString &getCardSourceVersion() const
{
return cardSourceVersion;
}
bool saveTokensToFile(const QString &fileName);
public:
@ -50,6 +66,8 @@ private slots:
private:
QByteArray tokensData;
QString cardSourceUrl;
QString cardSourceVersion;
protected:
void changeEvent(QEvent *event) override;

View file

@ -6,6 +6,7 @@ add_executable(carddatabase_test
../../cockatrice/src/carddbparser/carddatabaseparser.cpp
../../cockatrice/src/carddbparser/cockatricexml3.cpp
../../cockatrice/src/carddbparser/cockatricexml4.cpp
${VERSION_STRING_CPP}
)
add_executable(filter_string_test
filter_string_test.cpp
@ -17,6 +18,7 @@ add_executable(filter_string_test
../../cockatrice/src/carddbparser/carddatabaseparser.cpp
../../cockatrice/src/carddbparser/cockatricexml3.cpp
../../cockatrice/src/carddbparser/cockatricexml4.cpp
${VERSION_STRING_CPP}
)
if(NOT GTEST_FOUND)
add_dependencies(carddatabase_test gtest)

View file

@ -1,5 +1,5 @@
#include "gtest/gtest.h"
#include "../cockatrice/src/filter_string.h"
#include "../../cockatrice/src/filter_string.h"
#include "mocks.h"
#include <cmath>