248 lines
8.2 KiB
C++
248 lines
8.2 KiB
C++
#include "servercommunicator.h"
|
|
|
|
#include <QJsonArray>
|
|
#include <QJsonObject>
|
|
#include <QRestAccessManager>
|
|
#include <QRestReply>
|
|
|
|
#include "../formats/jsonparser.h"
|
|
#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<QRestAccessManager>(&m_netManager);
|
|
m_serviceApi = std::make_shared<QNetworkRequestFactory>();
|
|
|
|
connect(m_core, &GenericCore::sendGetRequest, this,
|
|
&ServerCommunicator::onSendGetRequestTriggered);
|
|
connect(m_core, &GenericCore::sendPostRequest, this,
|
|
&ServerCommunicator::onSendPostRequestTriggered);
|
|
connect(this, &ServerCommunicator::biddingsChanged, m_core, &GenericCore::onBiddingsChanged);
|
|
connect(this, &ServerCommunicator::onlineUserAccountReceived, m_core,
|
|
&GenericCore::onOnlineUserAccountReceived);
|
|
}
|
|
|
|
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;
|
|
}
|
|
|
|
QString ServerCommunicator::getUserLoginUrl() const {
|
|
const QString logInUrl = m_serviceApi->baseUrl().toString() + ROUTE_LOG_IN;
|
|
return logInUrl;
|
|
}
|
|
|
|
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,
|
|
const QByteArray data) {
|
|
QString path;
|
|
switch (type) {
|
|
case RegisterUser:
|
|
path = ROUTE_REGISTER_USER;
|
|
break;
|
|
case MailInvite:
|
|
path = ROUTE_MAIL_INVITE;
|
|
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);
|
|
|
|
m_restManager->post(request, data, 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;
|
|
onlineUserAccountReply(doc);
|
|
break;
|
|
case MailInvite:
|
|
qInfo() << "Mail invite successful sent:" << type;
|
|
mailInviteSentReply(doc);
|
|
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);
|
|
// NEXT improve error message to the UI;
|
|
m_core->displayStatusMessage(message);
|
|
}
|
|
|
|
void ServerCommunicator::currentBiddingRoundChangedReply(const QJsonDocument jsonDoc) {
|
|
qInfo() << "Current bidding round received.";
|
|
// REFACTOR implement & use "JsonParser::parseServerResponse(const QJsonDocument& jsonDoc,
|
|
// QHash<QString, int> entries)" (generalized version of
|
|
// "serverUserCredentialsToItemValues")
|
|
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;
|
|
|
|
const QList<bidding> biddings = JsonParser::extractBiddings(jsonDoc);
|
|
|
|
emit biddingsChanged(biddings);
|
|
}
|
|
|
|
void ServerCommunicator::onlineUserAccountReply(const QJsonDocument jsonDoc) {
|
|
qInfo() << "Online user account received.";
|
|
ModelItemValues values = JsonParser::serverUserCredentialsToItemValues(jsonDoc);
|
|
|
|
emit onlineUserAccountReceived(values[MailRole].toString(), values[OnlineIdRole].toString(),
|
|
values[AccessCodeRole].toString());
|
|
}
|
|
|
|
void ServerCommunicator::mailInviteSentReply(const QJsonDocument jsonDoc) {
|
|
qInfo() << "Invitation mail successfully sent.";
|
|
emit m_core->displayStatusMessage("Invitation mail successfully sent.");
|
|
}
|