#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(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::fetchItems() { /// Set up a GET request m_restManager->get(m_serviceApi->createRequest(ROUTE_ITEMS), this, [this](QRestReply& reply) { if (reply.isSuccess()) { qInfo() << "Fetching items successful."; const QJsonDocument doc = reply.readJson().value(); emit itemsFetched(doc.toJson()); } else { if (reply.hasError()) { const QString errorString = reply.errorString(); qCritical() << "ERROR:" << errorString; emit itemsFetchFailure(errorString); } else { int statusCode = reply.httpStatus(); qCritical() << "ERROR:" << statusCode; emit itemsFetchFailure(QString::number(statusCode)); emit itemsFetchFailure(QString("HTTP status code: %1").arg(statusCode)); } } }); } void ServerCommunicator::postItems(const QByteArray& jsonData) { QNetworkReply* reply = m_restManager->post(m_serviceApi->createRequest(ROUTE_ITEMS), jsonData); QObject::connect(reply, &QNetworkReply::finished, [=]() { if (reply->error() == QNetworkReply::NoError) { QByteArray responseData = reply->readAll(); const QString message = QString("POST successful! Response: %1").arg(responseData); qInfo() << message; emit postRequestSuccessful(responseData); } else { const QString message = QString("Error: %1").arg(reply->errorString()); qDebug() << message; emit postRequestFailure(message); } reply->deleteLater(); }); } void ServerCommunicator::deleteItem(const QString& id) { const QString deleteRoute = QString("%1/%2").arg(ROUTE_ITEMS, id); QNetworkReply* reply = m_restManager->deleteResource(m_serviceApi->createRequest(deleteRoute)); QObject::connect(reply, &QNetworkReply::finished, [=]() { if (reply->error() == QNetworkReply::NoError) { QByteArray responseData = reply->readAll(); const QString message = QString("DELETE successful! Response: %1").arg(responseData); qInfo() << message; emit deleteRequestSuccessful(responseData); } else { const QString message = QString("Error: %1").arg(reply->errorString()); qDebug() << message; emit deleteRequestFailure(message); } reply->deleteLater(); }); } 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) { 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: 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 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::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); }