First handshake with pica
This commit is contained in:
parent
4da9a275a9
commit
f547170728
12 changed files with 391 additions and 82 deletions
9
API/CMakeLists.txt
Normal file
9
API/CMakeLists.txt
Normal file
|
@ -0,0 +1,9 @@
|
|||
set(HEADERS
|
||||
api.h
|
||||
)
|
||||
|
||||
set(SOURCES
|
||||
api.cpp
|
||||
)
|
||||
|
||||
target_sources(megpie PRIVATE ${SOURCES})
|
93
API/api.cpp
Normal file
93
API/api.cpp
Normal file
|
@ -0,0 +1,93 @@
|
|||
#include "api.h"
|
||||
#include <QDebug>
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
|
||||
constexpr const char* json = "application/json";
|
||||
|
||||
struct NetworkReplyDeleter {
|
||||
void operator () (QNetworkReply* reply) {
|
||||
reply->deleteLater();
|
||||
}
|
||||
};
|
||||
|
||||
API::API(const QUrl& address, QObject* parent):
|
||||
QObject(parent),
|
||||
address(address),
|
||||
network()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void API::test(const QString& path, const QJSValue& finished) {
|
||||
qDebug() << "Testing" << path;
|
||||
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)
|
||||
);
|
||||
}
|
||||
|
||||
void API::onTestSuccess(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() << "Test for" << reply->url() << "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() << "Test for" << reply->url() << "failed:" << err;
|
||||
callCallback(finished, err);
|
||||
return;
|
||||
}
|
||||
|
||||
QByteArray data = reply->readAll();
|
||||
QJsonDocument document = QJsonDocument::fromJson(data);
|
||||
QJsonObject rootObj = document.object();
|
||||
|
||||
QJsonValue type = rootObj.value("type");
|
||||
QJsonValue version = rootObj.value("version");
|
||||
if (!type.isString() || !version.isString()) {
|
||||
QString err("malformed json");
|
||||
qDebug() << "Test for" << reply->url() << "failed:" << err;
|
||||
callCallback(finished, err);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
return;
|
||||
}
|
||||
|
||||
if (version.toString() != "0.0.1") {
|
||||
QString err("server of this version (" + version.toString() + ") is not supported");
|
||||
qDebug() << "Test for" << reply->url() << "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())
|
||||
callback.call(QJSValueList({QJSValue(QJSValue::NullValue)}) + arguments);
|
||||
else
|
||||
callback.call({QJSValue(error)});
|
||||
}
|
||||
}
|
||||
|
28
API/api.h
Normal file
28
API/api.h
Normal file
|
@ -0,0 +1,28 @@
|
|||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <QObject>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
#include <QJSValue>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QNetworkReply>
|
||||
|
||||
class API : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit API(const QUrl& path = QString(), QObject* parent = nullptr);
|
||||
|
||||
Q_INVOKABLE void test(const QString& path, const QJSValue& finished = QJSValue());
|
||||
|
||||
private slots:
|
||||
void onTestSuccess(QNetworkReply* reply, const QJSValue& finished) const;
|
||||
|
||||
private:
|
||||
void callCallback(const QJSValue& callback, const QString& error = QString(), const QJSValueList& arguments = QJSValueList()) const;
|
||||
|
||||
private:
|
||||
QUrl address;
|
||||
QNetworkAccessManager network;
|
||||
};
|
Loading…
Add table
Add a link
Reference in a new issue