From 94419b1e38d0d999c030ee19d35fcdadc335dfab Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 14 Jun 2014 11:29:00 +0200 Subject: [PATCH 1/6] Oracle: build with qtjson --- oracle/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/oracle/CMakeLists.txt b/oracle/CMakeLists.txt index 6f4e18c9..c23dfc4e 100644 --- a/oracle/CMakeLists.txt +++ b/oracle/CMakeLists.txt @@ -4,7 +4,7 @@ PROJECT(oracle) # paths set(DESKTOPDIR share/applications CACHE STRING "path to .desktop files") -SET(oracle_SOURCES src/main.cpp src/oracleimporter.cpp src/window_main.cpp ../cockatrice/src/carddatabase.cpp ../cockatrice/src/settingscache.cpp) +SET(oracle_SOURCES src/main.cpp src/oracleimporter.cpp src/window_main.cpp ../cockatrice/src/carddatabase.cpp ../cockatrice/src/settingscache.cpp ../cockatrice/src/qt-json/json.cpp) SET(oracle_HEADERS src/oracleimporter.h src/window_main.h ../cockatrice/src/carddatabase.h ../cockatrice/src/settingscache.h) SET(QT_USE_QTNETWORK TRUE) From dbac97ee8957a7b3144e3d6a03084143624a6000 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 14 Jun 2014 11:34:06 +0200 Subject: [PATCH 2/6] OracleImporter: use json to parse cards in sets Problem: Split card are imported as 2 different cards; need to find some way to join them --- oracle/src/oracleimporter.cpp | 94 +++++++++++------------------------ 1 file changed, 29 insertions(+), 65 deletions(-) diff --git a/oracle/src/oracleimporter.cpp b/oracle/src/oracleimporter.cpp index c244e56a..4d431e51 100644 --- a/oracle/src/oracleimporter.cpp +++ b/oracle/src/oracleimporter.cpp @@ -5,6 +5,8 @@ #include #include +#include "qt-json/json.h" + OracleImporter::OracleImporter(const QString &_dataDir, QObject *parent) : CardDatabase(parent), dataDir(_dataDir), setIndex(-1) { @@ -147,72 +149,34 @@ CardInfo *OracleImporter::addCard(const QString &setName, int OracleImporter::importTextSpoiler(CardSet *set, const QByteArray &data) { int cards = 0; - QString bufferContents(data); - - // Workaround for ampersand bug in text spoilers - int index = -1; - while ((index = bufferContents.indexOf('&', index + 1)) != -1) { - int semicolonIndex = bufferContents.indexOf(';', index); - if (semicolonIndex > 5) { - bufferContents.insert(index + 1, "amp;"); - index += 4; - } - } - - QDomDocument doc; - QString errorMsg; - int errorLine, errorColumn; - if (!doc.setContent(bufferContents, &errorMsg, &errorLine, &errorColumn)) - qDebug() << "error:" << errorMsg << "line:" << errorLine << "column:" << errorColumn; + bool ok; + QVariantMap resultMap = QtJson::Json::parse(QString(data), ok).toMap(); + if (!ok) { + qDebug() << "error: QtJson::Json::parse()"; + return 0; + } + + QListIterator it(resultMap.value("cards").toList()); + while (it.hasNext()) { + QVariantMap map = it.next().toMap(); + QString cardName = map.value("name").toString(); + QString cardCost = map.value("manaCost").toString(); + QString cardType = map.value("type").toString(); + QString cardPT = map.value("power").toString() + QString('/') + map.value("toughness").toString(); + QString cardText = map.value("text").toString(); + int cardId = map.value("multiverseid").toInt(); + int cardLoyalty = map.value("loyalty").toInt(); + QStringList cardTextSplit = cardText.split("\n"); - QDomNodeList divs = doc.elementsByTagName("div"); - for (int i = 0; i < divs.size(); ++i) { - QDomElement div = divs.at(i).toElement(); - QDomNode divClass = div.attributes().namedItem("class"); - if (divClass.nodeValue() == "textspoiler") { - QString cardName, cardCost, cardType, cardPT, cardText; - int cardId = 0; - int cardLoyalty = 0; - - QDomNodeList trs = div.elementsByTagName("tr"); - for (int j = 0; j < trs.size(); ++j) { - QDomElement tr = trs.at(j).toElement(); - QDomNodeList tds = tr.elementsByTagName("td"); - if (tds.size() != 2) { - QStringList cardTextSplit = cardText.split("\n"); - for (int i = 0; i < cardTextSplit.size(); ++i) - cardTextSplit[i] = cardTextSplit[i].trimmed(); - - CardInfo *card = addCard(set->getShortName(), cardName, false, cardId, cardCost, cardType, cardPT, cardLoyalty, cardTextSplit); - if (!set->contains(card)) { - card->addToSet(set); - cards++; - } - cardName = cardCost = cardType = cardPT = cardText = QString(); - } else { - QString v1 = tds.at(0).toElement().text().simplified(); - QString v2 = tds.at(1).toElement().text().replace(trUtf8("—"), "-"); - - if (v1 == "Name") { - QDomElement a = tds.at(1).toElement().elementsByTagName("a").at(0).toElement(); - QString href = a.attributes().namedItem("href").nodeValue(); - cardId = href.mid(href.indexOf("multiverseid=") + 13).toInt(); - cardName = v2.simplified(); - } else if (v1 == "Cost:") - cardCost = v2.simplified(); - else if (v1 == "Type:") - cardType = v2.simplified(); - else if (v1 == "Pow/Tgh:") - cardPT = v2.simplified().remove('(').remove(')'); - else if (v1 == "Rules Text:") - cardText = v2.trimmed(); - else if (v1 == "Loyalty:") - cardLoyalty = v2.trimmed().remove('(').remove(')').toInt(); - } - } - break; + CardInfo *card = addCard(set->getShortName(), cardName, false, cardId, cardCost, cardType, cardPT, cardLoyalty, cardTextSplit); + + if (!set->contains(card)) { + card->addToSet(set); + cards++; } - } + cardName = cardCost = cardType = cardPT = cardText = QString(); + } + return cards; } @@ -257,7 +221,7 @@ void OracleImporter::downloadNextFile() QString urlString = setsToDownload[setIndex].getUrl(); if (urlString.isEmpty()) urlString = setUrl; - urlString = urlString.replace("!longname!", setsToDownload[setIndex].getLongName()); + urlString = urlString.replace("!name!", setsToDownload[setIndex].getShortName()); if (urlString.startsWith("http://")) { QUrl url(urlString); From 6f8b2baad8f3b62130bc4c738df0f8a6e46aa603 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 14 Jun 2014 11:34:52 +0200 Subject: [PATCH 3/6] Corrections to sets.xml for mtgjson.com MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Used http://www.woogerworks.com/files/sets.xml as a base * update version * use mtgjson.com as source * adapted some sets name (es: 6E => 6ED) Caveats: * Not all previous sets are present (e.g.: WOTC, WMCQ, WRL); they were not present in woogerworks’s sets.xml anyway --- doc/sets.xml | 688 ++++++++++++++++++++++----------------------------- 1 file changed, 290 insertions(+), 398 deletions(-) diff --git a/doc/sets.xml b/doc/sets.xml index 1afa3958..92bf1b21 100644 --- a/doc/sets.xml +++ b/doc/sets.xml @@ -1,333 +1,253 @@ - + http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=!cardid!&type=card -http://gatherer.wizards.com/Pages/Search/Default.aspx?output=spoiler&method=text&set=["!longname!"]&special=true - - 10E - Tenth Edition - - - 15ANN - 15th Anniversary - - - 4E - Fourth Edition - - - 5DN - Fifth Dawn - - - 5E - Fifth Edition - - - 6E - Classic Sixth Edition - - - 7E - Seventh Edition - - - 8EB - Eighth Edition Box Set - - - 8E - Eighth Edition - - - 9EB - Ninth Edition Box Set - - - 9E - Ninth Edition - - - AI - Alliances - - - ALA - Shards of Alara - - - AL - Limited Edition Alpha - - - AN - Arabian Nights - - - APAC - Asia Pacific Land Program - - - AP - Apocalypse - - - AQ - Antiquities - +http://mtgjson.com/json/!name!.json ARB Alara Reborn + ALL + Alliances + + + ATQ + Antiquities + + + APC + Apocalypse + + + ARN + Arabian Nights + + ARC Archenemy - - ARENA - Arena League - - - AT - Anthologies - AVR Avacyn Restored - - BD - Beatdown Box Set + + BRB + Battle Royale Box Set - - BE - Limited Edition Beta + + BTD + Beatdown Box Set BOK Betrayers of Kamigawa - BR - Battle Royale Box Set - - - CED - Collector's Edition - - - CEDI - International Collectors' Edition - - - CFX - Conflux - - - CH - Chronicles + BNG + Born of the Gods CHK Champions of Kamigawa - CMA - Commander's Arsenal + CHR + Chronicles - CMD - Commander + 6ED + Classic Sixth Edition - CP - Champs - - - CS + CSP Coldsnap - CSTD - Coldsnap Theme Decks + CON + Conflux + + + CMA + Commander's Arsenal + + ^M + C13^M + Commander 2013 Edition^M - DCILM - Legend Membership - - - DDF - Duel Decks: Elspeth vs. Tezzeret - - - DDG - Duel Decks: Knights vs. Dragons - - - DDH - Duel Decks: Ajani vs. Nicol Bolas - - - DDI - Duel Decks: Venser vs. Koth - - - DDJ - Duel Decks: Izzet vs. Golgari - - - DDK - Duel Decks: Sorin vs. Tibalt - - - DGM - Dragon's Maze - - - DI - Dissension + DST + Darksteel DKA Dark Ascension - DK - The Dark + DIS + Dissension - DM - Deckmasters + DGM + Dragon's Maze - - DPA - Duels of the Planeswalkers + + DDH + Duel Decks: Ajani vs. Nicol Bolas - - DRC - Dragon Con - - - DS - Darksteel - - - DVD + + DDC Duel Decks: Divine vs. Demonic + + DDF + Duel Decks: Elspeth vs. Tezzeret + + + EVG + Duel Decks: Elves vs. Goblins + + + DDD + Duel Decks: Garruk vs. Liliana + + + DDL + Duel Decks: Heroes vs. Monsters + + + DDJ + Duel Decks: Izzet vs. Golgari + + + DD2 + Duel Decks: Jace vs. Chandra + + + DDM + Duel Decks: Jace vs. Vraska + + + DDG + Duel Decks: Knights vs. Dragons + + + DDE + Duel Decks: Phyrexia vs. the Coalition + + + DDK + Duel Decks: Sorin vs. Tibalt + + + DDI + Duel Decks: Venser vs. Koth + - EURO - European Land Program + 8ED + Eighth Edition EVE Eventide - EVG - Duel Decks: Elves vs. Goblins - - - EX + EXO Exodus - FE + FEM Fallen Empires - FNMP - Friday Night Magic + 5DN + Fifth Dawn + + + 5ED + Fifth Edition + + + 4ED + Fourth Edition + + + DRB + From the Vault: Dragons + + + V09 + From the Vault: Exiled + + + V11 + From the Vault: Legends + + + V12 + From the Vault: Realms + + + V10 + From the Vault: Relics + + + V13 + From the Vault: Twenty FUT Future Sight - FVD - From the Vault: Dragons - - - FVE - From the Vault: Exiled - - - FVL - From the Vault: Legends - - - FVR - From the Vault: Relics - - - GP + GPT Guildpact - - GPX - Grand Prix - - - GRC - WPN/Gateway - GTC Gatecrash - GURU - Guru - - - GVL - Duel Decks: Garruk vs. Liliana - - - HHO - Happy Holidays - - - HL + HML Homelands - IA + ICE Ice Age - - IN - Invasion - ISD Innistrad - ITP - Introductory Two-Player Set + INV + Invasion - JR - Judge Gift Program + JOU + Journey into Nyx - JU + JUD Judgment - JVC - Duel Decks: Jace vs. Chandra - - - LE - Legions - - - LG + LEG Legends - LW + LGN + Legions + + + LEA + Limited Edition Alpha + + + LEB + Limited Edition Beta + + + LRW Lorwyn @@ -347,63 +267,59 @@ Magic 2013 - MBP - Media Inserts + M14 + Magic 2014 Core Set + + + CMD + Magic: The Gathering-Commander + + + CNS + Magic: The Gathering—Conspiracy + + + MED + Masters Edition + + + ME2 + Masters Edition II + + + ME3 + Masters Edition III + + + ME4 + Masters Edition IV + + + MMQ + Mercadian Masques + + + MIR + Mirage + + + MRD + Mirrodin MBS Mirrodin Besieged + ^M + MMA^M + Modern Masters^M + ^ - ME2 - MTGO Masters Edition II - - - ME3 - MTGO Masters Edition III - - - ME4 - MTGO Masters Edition IV - - - MED - MTGO Masters Edition - - - MGBC - Multiverse Gift Box Cards - - - MGDC - Magic Game Day Cards - - - MI - Mirrodin - - - MLP - Magic: The Gathering Launch Parties - - - MM - Mercadian Masques - - - MPRP - Magic Player Rewards - - - MR - Mirage - - - MT + MOR Morningtide - NE + NMS Nemesis @@ -411,104 +327,80 @@ New Phyrexia - OD + 9ED + Ninth Edition + + + ODY Odyssey - ON + ONS Onslaught - P3K - Portal Three Kingdoms + PLC + Planar Chaos - + + HOP + Planechase + + PC2 Planechase 2012 Edition - PC - Planar Chaos + PLS + Planeshift - PCH - Planechase - - - PD2 - Premium Deck Series: Fire and Lightning - - - PD3 - Premium Deck Series: Graveborn - - - PDS - Premium Deck Series: Slivers + POR + Portal PO2 Portal Second Age - PO - Portal + PTK + Portal Three Kingdoms + + + PD2 + Premium Deck Series: Fire and Lightning + + + PD3 + Premium Deck Series: Graveborn + + + H09 + Premium Deck Series: Slivers + + + PPR + Promo set for Gatherer - POT - Portal Demogame - - - PR + PCY Prophecy - - PRO - Pro Tour - - - PS - Planeshift - - - PTC - Prerelease Events - - - PVC - Duel Decks: Phyrexia vs. The Coalition - RAV Ravnica: City of Guilds - - REP - Release Events - - - ROE - Rise of the Eldrazi - RTR Return to Ravnica - RV + 3ED Revised Edition - SC - Scourge - - - SH - Stronghold - - - SHM - Shadowmoor + ROE + Rise of the Eldrazi SOK @@ -519,97 +411,97 @@ Scars of Mirrodin - ST2K - Starter 2000 + SCG + Scourge - ST + 7ED + Seventh Edition + + + SHM + Shadowmoor + + + ALA + Shards of Alara + + + S99 Starter 1999 - SUM - Summer of Magic + S00 + Starter 2000 - SUS - Super Series + STH + Stronghold - THGT - Two-Headed Giant Tournament - - - TP + TMP Tempest - TR - Torment + 10E + Tenth Edition - TS + DRK + The Dark + + + THS + Theros + + + TSP Time Spiral - TSTS + TSB Time Spiral "Timeshifted" - UD - Urza's Destiny + TOR + Torment - - UG + + UGL Unglued - - UHAA - Unhinged Alternate Foils - - - UH + + UNH Unhinged - UL - Urza's Legacy - - - UN + 2ED Unlimited Edition - UQC - Celebration Cards + UDS + Urza's Destiny - US + ULG + Urza's Legacy + + + USG Urza's Saga - - V12 - From the Vault: Realms + + VAN + Vanguard - VI + VIS Visions - WL + WTH Weatherlight - - WMCQ - World Magic Cup Qualifiers - - - WOTC - WotC Online Store - - - WRL - Worlds - WWK Worldwake From d58615df1a2c2bd02b3599d3fa62eccbe66f50d6 Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 14 Jun 2014 11:52:55 +0200 Subject: [PATCH 4/6] Fix import of P/T; misc optimizations --- oracle/src/oracleimporter.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/oracle/src/oracleimporter.cpp b/oracle/src/oracleimporter.cpp index 4d431e51..af310a46 100644 --- a/oracle/src/oracleimporter.cpp +++ b/oracle/src/oracleimporter.cpp @@ -157,15 +157,24 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QByteArray &data) } QListIterator it(resultMap.value("cards").toList()); + QVariantMap map; + QString cardName; + QString cardCost; + QString cardType; + QString cardPT; + QString cardText; + int cardId; + int cardLoyalty; + while (it.hasNext()) { - QVariantMap map = it.next().toMap(); - QString cardName = map.value("name").toString(); - QString cardCost = map.value("manaCost").toString(); - QString cardType = map.value("type").toString(); - QString cardPT = map.value("power").toString() + QString('/') + map.value("toughness").toString(); - QString cardText = map.value("text").toString(); - int cardId = map.value("multiverseid").toInt(); - int cardLoyalty = map.value("loyalty").toInt(); + map = it.next().toMap(); + cardName = map.contains("name") ? map.value("name").toString() : QString(""); + cardCost = map.contains("manaCost") ? map.value("manaCost").toString() : QString(""); + cardType = map.contains("type") ? map.value("type").toString() : QString(""); + cardPT = map.contains("power") || map.contains("toughness") ? map.value("power").toString() + QString('/') + map.value("toughness").toString() : QString(""); + cardText = map.contains("text") ? map.value("text").toString() : QString(""); + cardId = map.contains("multiverseid") ? map.value("multiverseid").toInt() : 0; + cardLoyalty = map.contains("loyalty") ? map.value("loyalty").toInt() : 0; QStringList cardTextSplit = cardText.split("\n"); CardInfo *card = addCard(set->getShortName(), cardName, false, cardId, cardCost, cardType, cardPT, cardLoyalty, cardTextSplit); @@ -174,7 +183,6 @@ int OracleImporter::importTextSpoiler(CardSet *set, const QByteArray &data) card->addToSet(set); cards++; } - cardName = cardCost = cardType = cardPT = cardText = QString(); } return cards; From 2b1d7c4f740923a06f7880c3e25f3384d31733fc Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 14 Jun 2014 12:02:34 +0200 Subject: [PATCH 5/6] Use mtgimage.com for card images --- doc/sets.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/sets.xml b/doc/sets.xml index 92bf1b21..639cbdfc 100644 --- a/doc/sets.xml +++ b/doc/sets.xml @@ -1,6 +1,6 @@ -http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=!cardid!&type=card +http://mtgimage.com/multiverseid/!cardid!.jpg http://mtgjson.com/json/!name!.json ARB From 827f448cde5c4fb584b969bf2cb8b1ed0842a0ec Mon Sep 17 00:00:00 2001 From: Fabio Bas Date: Sat, 14 Jun 2014 12:11:03 +0200 Subject: [PATCH 6/6] Keep gatherer as image source; mtgimage as a hq alternative --- doc/sets.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/sets.xml b/doc/sets.xml index 639cbdfc..bcc7c20e 100644 --- a/doc/sets.xml +++ b/doc/sets.xml @@ -1,6 +1,7 @@ -http://mtgimage.com/multiverseid/!cardid!.jpg +http://gatherer.wizards.com/Handlers/Image.ashx?multiverseid=!cardid!&type=card + http://mtgjson.com/json/!name!.json ARB