#include "api.h" #include #include #include 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 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() || 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)}); } }