1 #include "deckstats_interface.h"
2
3 #include "decklist.h"
4
5 #include <QDesktopServices>
6 #include <QMessageBox>
7 #include <QNetworkAccessManager>
8 #include <QNetworkReply>
9 #include <QNetworkRequest>
10 #include <QRegExp>
11 #include <QUrlQuery>
12
DeckStatsInterface(CardDatabase & _cardDatabase,QObject * parent)13 DeckStatsInterface::DeckStatsInterface(CardDatabase &_cardDatabase, QObject *parent)
14 : QObject(parent), cardDatabase(_cardDatabase)
15 {
16 manager = new QNetworkAccessManager(this);
17 connect(manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(queryFinished(QNetworkReply *)));
18 }
19
queryFinished(QNetworkReply * reply)20 void DeckStatsInterface::queryFinished(QNetworkReply *reply)
21 {
22 if (reply->error() != QNetworkReply::NoError) {
23 QMessageBox::critical(0, tr("Error"), reply->errorString());
24 reply->deleteLater();
25 deleteLater();
26 return;
27 }
28
29 QString data(reply->readAll());
30 reply->deleteLater();
31
32 QRegExp rx("<meta property=\"og:url\" content=\"([^\"]+)\"");
33 if (-1 == rx.indexIn(data)) {
34 QMessageBox::critical(0, tr("Error"), tr("The reply from the server could not be parsed."));
35 deleteLater();
36 return;
37 }
38
39 QString deckUrl = rx.cap(1);
40 QDesktopServices::openUrl(deckUrl);
41
42 deleteLater();
43 }
44
getAnalyzeRequestData(DeckList * deck,QByteArray * data)45 void DeckStatsInterface::getAnalyzeRequestData(DeckList *deck, QByteArray *data)
46 {
47 DeckList deckWithoutTokens;
48 copyDeckWithoutTokens(*deck, deckWithoutTokens);
49
50 QUrl params;
51 QUrlQuery urlQuery;
52 urlQuery.addQueryItem("deck", deckWithoutTokens.writeToString_Plain());
53 urlQuery.addQueryItem("decktitle", deck->getName());
54 params.setQuery(urlQuery);
55 data->append(params.query(QUrl::EncodeReserved).toUtf8());
56 }
57
analyzeDeck(DeckList * deck)58 void DeckStatsInterface::analyzeDeck(DeckList *deck)
59 {
60 QByteArray data;
61 getAnalyzeRequestData(deck, &data);
62
63 QNetworkRequest request(QUrl("https://deckstats.net/index.php"));
64 request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
65
66 manager->post(request, data);
67 }
68
69 struct CopyIfNotAToken
70 {
71 CardDatabase &cardDatabase;
72 DeckList &destination;
73
CopyIfNotATokenCopyIfNotAToken74 CopyIfNotAToken(CardDatabase &_cardDatabase, DeckList &_destination)
75 : cardDatabase(_cardDatabase), destination(_destination){};
76
operator ()CopyIfNotAToken77 void operator()(const InnerDecklistNode *node, const DecklistCardNode *card) const
78 {
79 CardInfoPtr dbCard = cardDatabase.getCard(card->getName());
80 if (dbCard && !dbCard->getIsToken()) {
81 DecklistCardNode *addedCard = destination.addCard(card->getName(), node->getName());
82 addedCard->setNumber(card->getNumber());
83 }
84 }
85 };
86
copyDeckWithoutTokens(const DeckList & source,DeckList & destination)87 void DeckStatsInterface::copyDeckWithoutTokens(const DeckList &source, DeckList &destination)
88 {
89 CopyIfNotAToken copyIfNotAToken(cardDatabase, destination);
90 source.forEachCard(copyIfNotAToken);
91 }
92