#include "servercommunicator.h" #include #include #include #include #include "../genericcore.h" #include "../structs.h" #include "apiroutes.h" using namespace Qt::StringLiterals; ServerCommunicator::ServerCommunicator(GenericCore* core) : m_core(core) , QObject{core} { m_netManager.setAutoDeleteReplies(true); m_restManager = std::make_shared(&m_netManager); m_serviceApi = std::make_shared(); connect(m_core, &GenericCore::sendGetRequest, this, &ServerCommunicator::onSendGetRequestTriggered); connect(m_core, &GenericCore::sendPostRequest, this, &ServerCommunicator::onSendPostRequestTriggered); connect(this, &ServerCommunicator::biddingsChanged, m_core, &GenericCore::onBiddingsChanged); } bool ServerCommunicator::sslSupported() const { #if QT_CONFIG(ssl) return QSslSocket::supportsSsl(); #else return false; #endif } QUrl ServerCommunicator::url() const { return m_serviceApi->baseUrl(); } void ServerCommunicator::setUrl(const QUrl& url) { if (m_serviceApi->baseUrl() == url) { return; } m_serviceApi->setBaseUrl(url); QHttpHeaders authenticationHeaders; authenticationHeaders.append(QHttpHeaders::WellKnownHeader::ContentType, "application/json"); m_serviceApi->setCommonHeaders(authenticationHeaders); emit urlChanged(); } void ServerCommunicator::setServerConfiguration(const QString url, const QString email, const QString password) { setUrl(url); m_email = email; m_password = password; } void ServerCommunicator::onSendGetRequestTriggered(const GetRequestTypes type, QVariant data = QVariant()) { QString path; switch (type) { case GetCurrentBiddingRound: path = ROUTE_CURRENT_BIDDINGROUND; break; case StartNewBiddingRound: path = ROUTE_START_BIDDINGROUND; break; case RestartLastBiddingRound: path = ROUTE_RESTART_BIDDINGROUND; break; case StopCurrentBiddingRound: path = ROUTE_STOP_BIDDINGROUND; break; case GetBiddingsOfSpecificRound: path = ROUTE_GET_BIDDINGS_OF_SPECIFIC_ROUND + "/" + data.toString(); break; case GetBiddingsOfHighestRound: path = ROUTE_GET_BIDDINGS_OF_HIGHEST_ROUND; break; default: qWarning() << "No route found for GetRequestType:" << type; break; } // TODO move into default case of switch statement? if (path.isEmpty()) { qDebug() << "Empty path -> Not sending a request."; return; } const QNetworkRequest request = m_serviceApi->createRequest(path); m_restManager->get(request, this, [this, type](QRestReply& reply) { if (reply.isSuccess()) { qInfo() << "Request successful."; const QJsonDocument doc = reply.readJson().value(); onGetReplySuccessful(type, doc); } else { if (reply.hasError()) { const QString errorString = reply.errorString(); qWarning() << "Network error:" << errorString; onGetReplyFailure(type, errorString); } else { int statusCode = reply.httpStatus(); qWarning() << "Request not successful:" << statusCode; onGetReplyFailure(type, QString("HTTP status code: %1").arg(statusCode)); } } }); } void ServerCommunicator::onGetReplySuccessful(const GetRequestTypes type, const QJsonDocument doc) { switch (type) { case GetCurrentBiddingRound: case StartNewBiddingRound: case RestartLastBiddingRound: case StopCurrentBiddingRound: currentBiddingRoundChangedReply(doc); break; case GetBiddingsOfSpecificRound: case GetBiddingsOfHighestRound: currentBiddingsReply(doc); break; default: qWarning() << "Can't match request type:" << type; break; } } void ServerCommunicator::onGetReplyFailure(const GetRequestTypes type, const QString errorString) { const QString message = QString("Request of type %1 returned: %2").arg(QString::number(type), errorString); m_core->displayStatusMessage(message); } void ServerCommunicator::onSendPostRequestTriggered(const PostRequestTypes type, QVariant data) { QString path; switch (type) { case RegisterUser: path = ROUTE_REGISTER_USER; break; default: qWarning() << "No route found for PostRequestType:" << type; break; } // TODO move into default case of switch statement? if (path.isEmpty()) { qDebug() << "Empty path -> Not sending a request."; return; } const QNetworkRequest request = m_serviceApi->createRequest(path); QJsonDocument doc = QJsonDocument(); QJsonObject rootObject; QJsonObject itemObject; itemObject.insert("email", data.toString()); rootObject.insert("user", itemObject); doc.setObject(rootObject); m_restManager->post(request, doc, this, [this, type](QRestReply& reply) { if (reply.isSuccess()) { int statusCode = reply.httpStatus(); qInfo() << "Request successful. Status code:" << statusCode; const QJsonDocument doc = reply.readJson().value(); onPostReplySuccessful(type, doc); } else { if (reply.hasError()) { const QString errorString = reply.errorString(); qWarning() << "Network error:" << errorString; onPostReplyFailure(type, errorString); } else { int statusCode = reply.httpStatus(); qWarning() << "Request not successful:" << statusCode; qCritical() << "Content:" << reply.readJson(); onPostReplyFailure(type, QString("HTTP status code: %1").arg(statusCode)); } } }); } void ServerCommunicator::onPostReplySuccessful(const PostRequestTypes type, const QJsonDocument doc) { switch (type) { case RegisterUser: qInfo() << "Register user successful:" << type; m_core->displayStatusMessage(doc.toJson()); break; default: qWarning() << "Can't match request type:" << type; break; } } void ServerCommunicator::onPostReplyFailure(const PostRequestTypes type, const QString errorString) { const QString message = QString("Request of type %1 returned: %2").arg(QString::number(type), errorString); m_core->displayStatusMessage(message); } void ServerCommunicator::currentBiddingRoundChangedReply(const QJsonDocument jsonDoc) { qInfo() << "Current bidding round received."; const QJsonObject rootObject = jsonDoc["data"].toObject(); const int roundNumber = rootObject["round_number"].toInt(); const bool stopped = rootObject["stopped"].toBool(); const bool isActive = !stopped; // NOTE ?use ServerCommunicator::currentBiddingRoundChanged signal instead of emiting a signal of // the core directly? emit m_core->currentBiddingRoundChanged(roundNumber, isActive); } void ServerCommunicator::currentBiddingsReply(const QJsonDocument jsonDoc) { qCritical() << "currentBiddingsReply:" << jsonDoc; // NEXT extract biddings from jsonDoc const int roundNumber = 0; const bidding dummyBidding{.userId = QUuid(), .biddingRound = 0, .amount = 123, .depotWishOne = "one", .depotWishTwo = "two"}; const QList biddings{dummyBidding}; emit biddingsChanged(roundNumber, biddings); }