some experiments about sending form
This commit is contained in:
parent
be3d8b0e77
commit
c966d95058
7 changed files with 305 additions and 21 deletions
110
API/api.cpp
110
API/api.cpp
|
@ -2,8 +2,10 @@
|
|||
#include <QDebug>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QUrlQuery>
|
||||
|
||||
constexpr const char* json = "application/json";
|
||||
constexpr const char* urlEncoded = "application/x-www-form-urlencoded";
|
||||
|
||||
struct NetworkReplyDeleter {
|
||||
void operator () (QNetworkReply* reply) {
|
||||
|
@ -14,23 +16,53 @@ struct NetworkReplyDeleter {
|
|||
API::API(const QUrl& address, QObject* parent):
|
||||
QObject(parent),
|
||||
address(address),
|
||||
network()
|
||||
{
|
||||
network(),
|
||||
state(NoServer)
|
||||
{}
|
||||
|
||||
QUrl API::getAddress() const {
|
||||
return address;
|
||||
}
|
||||
|
||||
API::State API::getState() const {
|
||||
return state;
|
||||
}
|
||||
|
||||
void API::setAddress(const QUrl& path) {
|
||||
if (address == path)
|
||||
return;
|
||||
|
||||
if (state == Authenticated) {
|
||||
//do something
|
||||
}
|
||||
|
||||
address = path;
|
||||
state = address.isEmpty() ? NoServer : NotAuthenticated;
|
||||
|
||||
emit addressChanged(address);
|
||||
emit stateChanged(state);
|
||||
}
|
||||
|
||||
void API::test(const QString& path, const QJSValue& finished) {
|
||||
qDebug() << "Testing" << path;
|
||||
|
||||
if (state == Offline) {
|
||||
QString err = "Need to be online to test";
|
||||
qDebug() << "Test for" << path << "failed:" << err;
|
||||
callCallback(finished, err);
|
||||
return;
|
||||
}
|
||||
|
||||
QNetworkRequest request(path + "/info");
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, json);
|
||||
|
||||
QNetworkReply* reply = network.get(request);
|
||||
connect(reply, &QNetworkReply::finished,
|
||||
std::bind(&API::onTestSuccess, this, reply, finished)
|
||||
std::bind(&API::onTestFinished, this, reply, finished)
|
||||
);
|
||||
}
|
||||
|
||||
void API::onTestSuccess(QNetworkReply* reply, const QJSValue& finished) const {
|
||||
void API::onTestFinished(QNetworkReply* reply, const QJSValue& finished) const {
|
||||
std::unique_ptr<QNetworkReply, NetworkReplyDeleter> rpl(reply);
|
||||
QNetworkReply::NetworkError error = reply->error();
|
||||
if (error != QNetworkReply::NoError) {
|
||||
|
@ -65,7 +97,7 @@ void API::onTestSuccess(QNetworkReply* reply, const QJSValue& finished) const {
|
|||
return;
|
||||
}
|
||||
|
||||
if (type.toString() != "Pica") {
|
||||
if (type.toString() != "pica") {
|
||||
QString err("server of this type (" + type.toString() + ") is not supported");
|
||||
qDebug() << "Test for" << reply->url() << "failed:" << err;
|
||||
callCallback(finished, err);
|
||||
|
@ -82,6 +114,74 @@ void API::onTestSuccess(QNetworkReply* reply, const QJSValue& finished) const {
|
|||
callCallback(finished, QString(), {QJSValue(true)});
|
||||
}
|
||||
|
||||
void API::sendRegister(const QString& login, const QString& password, const QJSValue &finished) {
|
||||
qDebug() << "Registering...";
|
||||
|
||||
if (state != NotAuthenticated) {
|
||||
QString err = "Can not register in current state";
|
||||
qDebug() << "Register failed:" << err;
|
||||
callCallback(finished, err);
|
||||
return;
|
||||
}
|
||||
|
||||
QUrlQuery params({
|
||||
{"login", login},
|
||||
{"password", password}
|
||||
});
|
||||
|
||||
QNetworkRequest request(address.path() + "/register");
|
||||
request.setHeader(QNetworkRequest::ContentTypeHeader, urlEncoded);
|
||||
|
||||
QNetworkReply* reply = network.post(request, params.toString(QUrl::FullyEncoded).toUtf8());
|
||||
connect(reply, &QNetworkReply::finished,
|
||||
std::bind(&API::onRegisterFinished, this, reply, finished)
|
||||
);
|
||||
}
|
||||
|
||||
void API::onRegisterFinished(QNetworkReply *reply, const QJSValue &finished) const {
|
||||
std::unique_ptr<QNetworkReply, NetworkReplyDeleter> rpl(reply);
|
||||
QNetworkReply::NetworkError error = reply->error();
|
||||
if (error != QNetworkReply::NoError) {
|
||||
QString err = reply->errorString();
|
||||
qDebug() << "Register failed:" << err;
|
||||
callCallback(finished, err);
|
||||
return;
|
||||
}
|
||||
|
||||
QVariant contentType = reply->header(QNetworkRequest::ContentTypeHeader);
|
||||
if (!
|
||||
contentType.isValid() ||
|
||||
!contentType.canConvert<QString>() ||
|
||||
contentType.toString() != json
|
||||
) {
|
||||
QString err("wrong response content type");
|
||||
qDebug() << "Register failed:" << err;
|
||||
callCallback(finished, err);
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
QJsonDocument document = QJsonDocument::fromJson(data);
|
||||
QJsonObject rootObj = document.object();
|
||||
|
||||
QJsonValue result = rootObj.value("result");
|
||||
if (!result.isString()) {
|
||||
QString err("malformed json");
|
||||
qDebug() << "Register failed:" << err;
|
||||
callCallback(finished, err);
|
||||
return;
|
||||
}
|
||||
|
||||
if (result.toString() != "ok") {
|
||||
QString err("Registration result was not okay");
|
||||
qDebug() << "Register failed:" << err;
|
||||
callCallback(finished, err);
|
||||
return;
|
||||
}
|
||||
|
||||
callCallback(finished, QString(), {QJSValue(true)});
|
||||
}
|
||||
|
||||
void API::callCallback(const QJSValue& callback, const QString& error, const QJSValueList& arguments) const {
|
||||
if (callback.isCallable()) {
|
||||
if (error.isEmpty())
|
||||
|
|
25
API/api.h
25
API/api.h
|
@ -11,13 +11,33 @@
|
|||
|
||||
class API : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
enum State {Offline, NoServer, NotAuthenticated, Authenticated};
|
||||
Q_ENUM(State)
|
||||
|
||||
private:
|
||||
Q_PROPERTY(QUrl address READ getAddress WRITE setAddress NOTIFY addressChanged)
|
||||
Q_PROPERTY(State state READ getState NOTIFY stateChanged)
|
||||
|
||||
public:
|
||||
explicit API(const QUrl& path = QString(), QObject* parent = nullptr);
|
||||
|
||||
Q_INVOKABLE void test(const QString& path, const QJSValue& finished = QJSValue());
|
||||
QUrl getAddress() const;
|
||||
State getState() const;
|
||||
|
||||
void setAddress(const QUrl& path);
|
||||
|
||||
signals:
|
||||
void addressChanged(const QUrl& path);
|
||||
void stateChanged(State state);
|
||||
|
||||
public slots:
|
||||
void test(const QString& path, const QJSValue& finished = QJSValue());
|
||||
void sendRegister(const QString& login, const QString& password, const QJSValue& finished = QJSValue());
|
||||
|
||||
private slots:
|
||||
void onTestSuccess(QNetworkReply* reply, const QJSValue& finished) const;
|
||||
void onTestFinished(QNetworkReply* reply, const QJSValue& finished) const;
|
||||
void onRegisterFinished(QNetworkReply* reply, const QJSValue& finished) const;
|
||||
|
||||
private:
|
||||
void callCallback(const QJSValue& callback, const QString& error = QString(), const QJSValueList& arguments = QJSValueList()) const;
|
||||
|
@ -25,4 +45,5 @@ private:
|
|||
private:
|
||||
QUrl address;
|
||||
QNetworkAccessManager network;
|
||||
State state;
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue