prepare for further work with polling, license
This commit is contained in:
parent
b38ed2107b
commit
4694f3838f
25 changed files with 816 additions and 18 deletions
|
@ -1,3 +1,6 @@
|
|||
# SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
set(HEADERS
|
||||
api.h
|
||||
codes.h
|
||||
|
|
82
API/api.cpp
82
API/api.cpp
|
@ -1,9 +1,11 @@
|
|||
// SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "api.h"
|
||||
#include <QDebug>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QUrlQuery>
|
||||
#include <QTimer>
|
||||
|
||||
#include "codes.h"
|
||||
#include "finalaction.h"
|
||||
|
@ -35,8 +37,15 @@ API::API(const QUrl& address, QObject* parent):
|
|||
QObject(parent),
|
||||
address(address),
|
||||
network(),
|
||||
state(NoServer)
|
||||
{}
|
||||
state(NoServer),
|
||||
accessToken(),
|
||||
renewToken(),
|
||||
firstPoll()
|
||||
{
|
||||
firstPoll.setSingleShot(true);
|
||||
firstPoll.setInterval(2000);
|
||||
connect(&firstPoll, &QTimer::timeout, this, &API::onFirstPollSuccess);
|
||||
}
|
||||
|
||||
QUrl API::getAddress() const {
|
||||
return address;
|
||||
|
@ -50,11 +59,29 @@ void API::setTokens(const QString access, const QString &renew) {
|
|||
accessToken = access;
|
||||
renewToken = renew;
|
||||
setState(Authenticating);
|
||||
startPolling();
|
||||
}
|
||||
|
||||
//dont forget to remove
|
||||
QTimer::singleShot(1000, this, [this] () {
|
||||
setState(Authenticated);
|
||||
});
|
||||
void API::startPolling() {
|
||||
qDebug() << "Starting polling...";
|
||||
if (state != Authenticating)
|
||||
throw std::runtime_error("Can not start polling in this state: " + std::to_string(state));
|
||||
|
||||
if (accessToken.isEmpty())
|
||||
throw std::runtime_error("Can not start polling: access token is empty");
|
||||
|
||||
QByteArray authorizationHeader = "Bearer " + accessToken.toUtf8();
|
||||
QNetworkRequest request(createUrl("/poll"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, json);
|
||||
request.setRawHeader(QByteArray("Authorization"), authorizationHeader);
|
||||
request.setTransferTimeout(30000);
|
||||
|
||||
firstPoll.start();
|
||||
|
||||
QNetworkReply* reply = network.get(request);
|
||||
connect(reply, &QNetworkReply::finished,
|
||||
std::bind(&API::onPollFinished, this, reply)
|
||||
);
|
||||
}
|
||||
|
||||
void API::setAddress(const QUrl& path) {
|
||||
|
@ -112,6 +139,13 @@ void API::setState(State newState) {
|
|||
emit stateChanged(state);
|
||||
}
|
||||
|
||||
QUrl API::createUrl(const QString &path) const {
|
||||
QString startingPath = address.path();
|
||||
QUrl url = address;
|
||||
url.setPath(startingPath + path);
|
||||
return url;
|
||||
}
|
||||
|
||||
void API::test(const QString& path, const QJSValue& finished) {
|
||||
qDebug() << "Testing" << path;
|
||||
if (state == Offline)
|
||||
|
@ -160,11 +194,7 @@ void API::sendRegister(const QString& login, const QString& password, const QJSV
|
|||
{"password", password}
|
||||
});
|
||||
|
||||
QString path = address.path();
|
||||
QUrl regUrl = address;
|
||||
regUrl.setPath(path + "/register");
|
||||
|
||||
QNetworkRequest request(regUrl);
|
||||
QNetworkRequest request(createUrl("/register"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, urlEncoded);
|
||||
|
||||
QNetworkReply* reply = network.post(request, params.toString(QUrl::FullyEncoded).toUtf8());
|
||||
|
@ -183,11 +213,7 @@ void API::sendLogin(const QString& login, const QString& password, const QJSValu
|
|||
{"password", password}
|
||||
});
|
||||
|
||||
QString path = address.path();
|
||||
QUrl url = address;
|
||||
url.setPath(path + "/login");
|
||||
|
||||
QNetworkRequest request(url);
|
||||
QNetworkRequest request(createUrl("/login"));
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, urlEncoded);
|
||||
setState(Authenticating);
|
||||
QNetworkReply* reply = network.post(request, params.toString(QUrl::FullyEncoded).toUtf8());
|
||||
|
@ -250,10 +276,30 @@ void API::onLoginFinished(QNetworkReply* reply, const QJSValue& finished) {
|
|||
|
||||
callCallback(finished, detail, {QJSValue(success)});
|
||||
|
||||
state = Authenticated;
|
||||
state = Authenticating;
|
||||
accessToken = data->value("accessToken").toString();
|
||||
renewToken = data->value("renewToken").toString();
|
||||
emit storeTokens(accessToken, renewToken);
|
||||
startPolling();
|
||||
}
|
||||
|
||||
void API::onPollFinished(QNetworkReply *reply) {
|
||||
firstPoll.stop();
|
||||
std::unique_ptr<QNetworkReply, NetworkReplyDeleter> rpl(reply);
|
||||
QNetworkReply::NetworkError error = reply->error();
|
||||
std::optional<QVariantMap> data = readResult(reply);
|
||||
|
||||
if (error != QNetworkReply::NoError)
|
||||
qDebug() << reply->errorString();
|
||||
|
||||
if (data)
|
||||
qDebug() << data.value();
|
||||
|
||||
setState(NotAuthenticated);
|
||||
}
|
||||
|
||||
void API::onFirstPollSuccess() {
|
||||
setState(Authenticated);
|
||||
}
|
||||
|
||||
void API::callCallback(const QJSValue& callback, const QString& error, const QJSValueList& arguments) const {
|
||||
|
|
10
API/api.h
10
API/api.h
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
@ -10,6 +13,7 @@
|
|||
#include <QJSValue>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
#include <QTimer>
|
||||
|
||||
class Root;
|
||||
class API : public QObject {
|
||||
|
@ -35,6 +39,7 @@ public:
|
|||
QUrl getAddress() const;
|
||||
State getState() const;
|
||||
void setTokens(const QString access, const QString& renew);
|
||||
void startPolling();
|
||||
|
||||
signals:
|
||||
void addressChanged(const QUrl& path);
|
||||
|
@ -51,6 +56,9 @@ private slots:
|
|||
void onTestFinished(QNetworkReply* reply, const QUrl& addr, const QJSValue& finished);
|
||||
void onRegisterFinished(QNetworkReply* reply, const QJSValue& finished) const;
|
||||
void onLoginFinished(QNetworkReply* reply, const QJSValue& finished);
|
||||
void onPollFinished(QNetworkReply* reply);
|
||||
|
||||
void onFirstPollSuccess();
|
||||
|
||||
private:
|
||||
void callCallback(const QJSValue& callback, const QString& error = QString(), const QJSValueList& arguments = QJSValueList()) const;
|
||||
|
@ -58,6 +66,7 @@ private:
|
|||
static std::optional<QVariantMap> readResult(QNetworkReply* reply);
|
||||
static bool validateResponse(const std::optional<QVariantMap>& data, const std::map<QString, QMetaType::Type>& structure);
|
||||
void setState(State newState);
|
||||
QUrl createUrl(const QString& path) const;
|
||||
|
||||
private:
|
||||
QUrl address;
|
||||
|
@ -65,4 +74,5 @@ private:
|
|||
State state;
|
||||
QString accessToken;
|
||||
QString renewToken;
|
||||
QTimer firstPoll;
|
||||
};
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "codes.h"
|
||||
|
||||
#include <iostream>
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QString>
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#include "finalaction.h"
|
||||
|
||||
FinalAction::FinalAction(const std::function<void()>& action):
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
// SPDX-FileCopyrightText: 2023 Yury Gubich <blue@macaw.me>
|
||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <functional>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue