From ff1355e1a54868cdf07f6dec718b1cca9040b7bf Mon Sep 17 00:00:00 2001 From: Christian Fetzer Date: Sun, 4 Apr 2021 16:26:09 +0200 Subject: [PATCH] somfytahoma: Avoid duplication in SomfyTahoma*Request --- somfytahoma/integrationpluginsomfytahoma.cpp | 50 +++++------ somfytahoma/integrationpluginsomfytahoma.h | 4 +- somfytahoma/somfytahomarequests.cpp | 89 +++++++++----------- somfytahoma/somfytahomarequests.h | 35 ++------ 4 files changed, 71 insertions(+), 107 deletions(-) diff --git a/somfytahoma/integrationpluginsomfytahoma.cpp b/somfytahoma/integrationpluginsomfytahoma.cpp index fc7f89ca..ab2669e6 100644 --- a/somfytahoma/integrationpluginsomfytahoma.cpp +++ b/somfytahoma/integrationpluginsomfytahoma.cpp @@ -46,11 +46,11 @@ void IntegrationPluginSomfyTahoma::startPairing(ThingPairingInfo *info) void IntegrationPluginSomfyTahoma::confirmPairing(ThingPairingInfo *info, const QString &username, const QString &password) { - SomfyTahomaLoginRequest *request = new SomfyTahomaLoginRequest(hardwareManager()->networkManager(), username, password, this); - connect(request, &SomfyTahomaLoginRequest::error, info, [info](){ + SomfyTahomaRequest *request = createSomfyTahomaLoginRequest(hardwareManager()->networkManager(), username, password, this); + connect(request, &SomfyTahomaRequest::error, info, [info](){ info->finish(Thing::ThingErrorAuthenticationFailure, QT_TR_NOOP("Failed to login to Somfy Tahoma.")); }); - connect(request, &SomfyTahomaLoginRequest::finished, info, [this, info, username, password](const QVariant &/*result*/){ + connect(request, &SomfyTahomaRequest::finished, info, [this, info, username, password](const QVariant &/*result*/){ pluginStorage()->beginGroup(info->thingId().toString()); pluginStorage()->setValue("username", username); pluginStorage()->setValue("password", password); @@ -62,14 +62,14 @@ void IntegrationPluginSomfyTahoma::confirmPairing(ThingPairingInfo *info, const void IntegrationPluginSomfyTahoma::setupThing(ThingSetupInfo *info) { if (info->thing()->thingClassId() == tahomaThingClassId) { - SomfyTahomaLoginRequest *request = createLoginRequestWithStoredCredentials(info->thing()); - connect(request, &SomfyTahomaLoginRequest::error, info, [info](){ + SomfyTahomaRequest *request = createLoginRequestWithStoredCredentials(info->thing()); + connect(request, &SomfyTahomaRequest::error, info, [info](){ info->finish(Thing::ThingErrorHardwareFailure, QT_TR_NOOP("Failed to login to Somfy Tahoma.")); }); - connect(request, &SomfyTahomaLoginRequest::finished, info, [this, info](const QVariant &/*result*/){ + connect(request, &SomfyTahomaRequest::finished, info, [this, info](const QVariant &/*result*/){ QUuid accountId = info->thing()->id(); - SomfyTahomaGetRequest *request = new SomfyTahomaGetRequest(hardwareManager()->networkManager(), "/setup", this); - connect(request, &SomfyTahomaGetRequest::finished, this, [this, accountId](const QVariant &result){ + SomfyTahomaRequest *request = createSomfyTahomaGetRequest(hardwareManager()->networkManager(), "/setup", this); + connect(request, &SomfyTahomaRequest::finished, this, [this, accountId](const QVariant &result){ QList unknownDevices; foreach (const QVariant &gatewayVariant, result.toMap()["gateways"].toList()) { QVariantMap gatewayMap = gatewayVariant.toMap(); @@ -177,11 +177,11 @@ void IntegrationPluginSomfyTahoma::refreshAccount(Thing *thing) hardwareManager()->pluginTimerManager()->unregisterTimer(m_eventPollTimer[thing]); } - SomfyTahomaGetRequest *setupRequest = new SomfyTahomaGetRequest(hardwareManager()->networkManager(), "/setup", this); - connect(setupRequest, &SomfyTahomaGetRequest::error, this, [this, thing](){ + SomfyTahomaRequest *setupRequest = createSomfyTahomaGetRequest(hardwareManager()->networkManager(), "/setup", this); + connect(setupRequest, &SomfyTahomaRequest::error, this, [this, thing](){ markDisconnected(thing); }); - connect(setupRequest, &SomfyTahomaGetRequest::finished, this, [this, thing](const QVariant &result){ + connect(setupRequest, &SomfyTahomaRequest::finished, this, [this, thing](const QVariant &result){ thing->setStateValue(tahomaLoggedInStateTypeId, true); thing->setStateValue(tahomaConnectedStateTypeId, true); foreach (const QVariant &gatewayVariant, result.toMap()["gateways"].toList()) { @@ -201,29 +201,29 @@ void IntegrationPluginSomfyTahoma::refreshAccount(Thing *thing) } }); - SomfyTahomaPostRequest *eventRegistrationRequest = new SomfyTahomaPostRequest(hardwareManager()->networkManager(), "/events/register", "application/json", QByteArray(), this); - connect(eventRegistrationRequest, &SomfyTahomaPostRequest::error, this, [this, thing](){ + SomfyTahomaRequest *eventRegistrationRequest = createSomfyTahomaPostRequest(hardwareManager()->networkManager(), "/events/register", "application/json", QByteArray(), this); + connect(eventRegistrationRequest, &SomfyTahomaRequest::error, this, [this, thing](){ qCWarning(dcSomfyTahoma()) << "Failed to register for events."; markDisconnected(thing); }); - connect(eventRegistrationRequest, &SomfyTahomaPostRequest::finished, this, [this, thing](const QVariant &result){ + connect(eventRegistrationRequest, &SomfyTahomaRequest::finished, this, [this, thing](const QVariant &result){ thing->setStateValue(tahomaConnectedStateTypeId, true); QString eventListenerId = result.toMap()["id"].toString(); m_eventPollTimer[thing] = hardwareManager()->pluginTimerManager()->registerTimer(2 /*sec*/); connect(m_eventPollTimer[thing], &PluginTimer::timeout, thing, [this, thing, eventListenerId](){ - SomfyTahomaEventFetchRequest *eventFetchRequest = new SomfyTahomaEventFetchRequest(hardwareManager()->networkManager(), eventListenerId, this); - connect(eventFetchRequest, &SomfyTahomaEventFetchRequest::error, thing, [this, thing](QNetworkReply::NetworkError error){ + SomfyTahomaRequest *eventFetchRequest = createSomfyTahomaEventFetchRequest(hardwareManager()->networkManager(), eventListenerId, this); + connect(eventFetchRequest, &SomfyTahomaRequest::error, thing, [this, thing](QNetworkReply::NetworkError error){ markDisconnected(thing); if (error == QNetworkReply::AuthenticationRequiredError) { qCInfo(dcSomfyTahoma()) << "Failed to fetch events: Authentication expired, reauthenticating"; - SomfyTahomaLoginRequest *request = createLoginRequestWithStoredCredentials(thing); - connect(request, &SomfyTahomaLoginRequest::error, this, [this, thing](){ + SomfyTahomaRequest *request = createLoginRequestWithStoredCredentials(thing); + connect(request, &SomfyTahomaRequest::error, this, [this, thing](){ // This is a fatal error. The user needs to reconfigure the account to provide new credentials. qCWarning(dcSomfyTahoma()) << "Failed to reauthenticate"; hardwareManager()->pluginTimerManager()->unregisterTimer(m_eventPollTimer[thing]); m_eventPollTimer.remove(thing); }); - connect(request, &SomfyTahomaLoginRequest::finished, this, [this, thing](const QVariant &/*result*/){ + connect(request, &SomfyTahomaRequest::finished, this, [this, thing](const QVariant &/*result*/){ qCInfo(dcSomfyTahoma()) << "Reauthentication successful"; refreshAccount(thing); }); @@ -231,7 +231,7 @@ void IntegrationPluginSomfyTahoma::refreshAccount(Thing *thing) qCWarning(dcSomfyTahoma()) << "Failed to fetch events:" << error; } }); - connect(eventFetchRequest, &SomfyTahomaEventFetchRequest::finished, thing, [this, thing](const QVariant &result){ + connect(eventFetchRequest, &SomfyTahomaRequest::finished, thing, [this, thing](const QVariant &result){ thing->setStateValue(tahomaConnectedStateTypeId, true); restoreChildConnectedState(thing); if (!result.toList().empty()) { @@ -458,11 +458,11 @@ void IntegrationPluginSomfyTahoma::executeAction(ThingActionInfo *info) {"commands", QJsonArray{QJsonObject{{"name", actionName}, {"parameters", actionParameters}}}}}}} }}; - SomfyTahomaPostRequest *request = new SomfyTahomaPostRequest(hardwareManager()->networkManager(), "/exec/apply", "application/json", jsonRequest.toJson(QJsonDocument::Compact), this); - connect(request, &SomfyTahomaPostRequest::error, info, [info](){ + SomfyTahomaRequest *request = createSomfyTahomaPostRequest(hardwareManager()->networkManager(), "/exec/apply", "application/json", jsonRequest.toJson(QJsonDocument::Compact), this); + connect(request, &SomfyTahomaRequest::error, info, [info](){ info->finish(Thing::ThingErrorHardwareFailure); }); - connect(request, &SomfyTahomaPostRequest::finished, info, [this, info](const QVariant &result){ + connect(request, &SomfyTahomaRequest::finished, info, [this, info](const QVariant &result){ qCInfo(dcSomfyTahoma()) << "Action started" << info->thing() << info->action().actionTypeId(); m_pendingActions.insert(result.toMap()["execId"].toString(), info); }); @@ -471,13 +471,13 @@ void IntegrationPluginSomfyTahoma::executeAction(ThingActionInfo *info) } } -SomfyTahomaLoginRequest *IntegrationPluginSomfyTahoma::createLoginRequestWithStoredCredentials(Thing *thing) +SomfyTahomaRequest *IntegrationPluginSomfyTahoma::createLoginRequestWithStoredCredentials(Thing *thing) { pluginStorage()->beginGroup(thing->id().toString()); QString username = pluginStorage()->value("username").toString(); QString password = pluginStorage()->value("password").toString(); pluginStorage()->endGroup(); - return new SomfyTahomaLoginRequest(hardwareManager()->networkManager(), username, password, this); + return createSomfyTahomaLoginRequest(hardwareManager()->networkManager(), username, password, this); } void IntegrationPluginSomfyTahoma::markDisconnected(Thing *thing) diff --git a/somfytahoma/integrationpluginsomfytahoma.h b/somfytahoma/integrationpluginsomfytahoma.h index 9f46dc8a..e4323b88 100644 --- a/somfytahoma/integrationpluginsomfytahoma.h +++ b/somfytahoma/integrationpluginsomfytahoma.h @@ -34,7 +34,7 @@ #include "integrations/integrationplugin.h" #include "plugintimer.h" -class SomfyTahomaLoginRequest; +class SomfyTahomaRequest; class IntegrationPluginSomfyTahoma : public IntegrationPlugin { @@ -54,7 +54,7 @@ public: void executeAction(ThingActionInfo *info) override; private: - SomfyTahomaLoginRequest *createLoginRequestWithStoredCredentials(Thing *thing); + SomfyTahomaRequest *createLoginRequestWithStoredCredentials(Thing *thing); void refreshAccount(Thing *thing); void handleEvents(const QVariantList &eventList); void updateThingStates(const QString &deviceUrl, const QVariantList &stateList); diff --git a/somfytahoma/somfytahomarequests.cpp b/somfytahoma/somfytahomarequests.cpp index d82afa20..c11b9087 100644 --- a/somfytahoma/somfytahomarequests.cpp +++ b/somfytahoma/somfytahomarequests.cpp @@ -31,75 +31,62 @@ #include "somfytahomarequests.h" #include +#include #include "network/networkaccessmanager.h" #include "extern-plugininfo.h" -SomfyTahomaPostRequest::SomfyTahomaPostRequest(NetworkAccessManager *networkManager, const QString &path, const QString &contentType, const QByteArray &body, QObject *parent): - QObject(parent) + +static const QString somfyTahomaUrl = QStringLiteral("https://tahomalink.com/enduser-mobile-web/enduserAPI"); + +SomfyTahomaRequest::SomfyTahomaRequest(QNetworkReply *reply, QObject *parent) : QObject(parent) { - QUrl url("https://tahomalink.com/enduser-mobile-web/enduserAPI" + path); + connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); + connect(reply, &QNetworkReply::finished, this, [this, reply] { + deleteLater(); + if (reply->error() != QNetworkReply::NoError) { + qCWarning(dcSomfyTahoma()) << "Request for" << reply->url().path() << "failed:" << reply->errorString(); + emit error(reply->error()); + return; + } + + QByteArray data = reply->readAll(); + QJsonParseError parseError; + QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &parseError); + if (parseError.error != QJsonParseError::NoError) { + qCWarning(dcSomfyTahoma()) << "Json parse error in reply for" << reply->url().path() << ":" << parseError.errorString(); + emit error(QNetworkReply::UnknownContentError); + return; + } + + emit finished(jsonDoc.toVariant()); + }); +} + +SomfyTahomaRequest *createSomfyTahomaPostRequest(NetworkAccessManager *networkManager, const QString &path, const QString &contentType, const QByteArray &body, QObject *parent) +{ + QUrl url(somfyTahomaUrl + path); QNetworkRequest request(url); request.setHeader(QNetworkRequest::KnownHeaders::ContentTypeHeader, contentType); QNetworkReply *reply = networkManager->post(request, body); - connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); - connect(reply, &QNetworkReply::finished, this, [this, reply, path] { - deleteLater(); - if (reply->error() != QNetworkReply::NoError) { - qCWarning(dcSomfyTahoma()) << "Request for" << path << "failed:" << reply->errorString(); - emit error(reply->error()); - return; - } - - QByteArray data = reply->readAll(); - QJsonParseError parseError; - QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &parseError); - if (parseError.error != QJsonParseError::NoError) { - qCWarning(dcSomfyTahoma()) << "Json parse error in reply for" << path << ":" << parseError.errorString(); - emit error(QNetworkReply::UnknownContentError); - return; - } - - emit finished(jsonDoc.toVariant()); - }); + return new SomfyTahomaRequest(reply, parent); } -SomfyTahomaGetRequest::SomfyTahomaGetRequest(NetworkAccessManager *networkManager, const QString &path, QObject *parent): - QObject(parent) +SomfyTahomaRequest *createSomfyTahomaGetRequest(NetworkAccessManager *networkManager, const QString &path, QObject *parent) { - QUrl url("https://tahomalink.com/enduser-mobile-web/enduserAPI" + path); + QUrl url(somfyTahomaUrl + path); QNetworkRequest request(url); QNetworkReply *reply = networkManager->get(request); - connect(reply, &QNetworkReply::finished, reply, &QNetworkReply::deleteLater); - connect(reply, &QNetworkReply::finished, this, [this, reply, path] { - deleteLater(); - if (reply->error() != QNetworkReply::NoError) { - qCWarning(dcSomfyTahoma()) << "Request for" << path << "failed:" << reply->errorString(); - emit error(reply->error()); - return; - } - - QByteArray data = reply->readAll(); - QJsonParseError parseError; - QJsonDocument jsonDoc = QJsonDocument::fromJson(data, &parseError); - if (parseError.error != QJsonParseError::NoError) { - qCWarning(dcSomfyTahoma()) << "Json parse error in reply for" << path << ":" << parseError.errorString(); - emit error(QNetworkReply::UnknownContentError); - return; - } - - emit finished(jsonDoc.toVariant()); - }); + return new SomfyTahomaRequest(reply, parent); } -SomfyTahomaLoginRequest::SomfyTahomaLoginRequest(NetworkAccessManager *networkManager, const QString &username, const QString &password, QObject *parent): - SomfyTahomaPostRequest(networkManager, "/login", "application/x-www-form-urlencoded", QString("userId=" + username + "&userPassword=" + password).toUtf8(), parent) +SomfyTahomaRequest *createSomfyTahomaLoginRequest(NetworkAccessManager *networkManager, const QString &username, const QString &password, QObject *parent) { + return createSomfyTahomaPostRequest(networkManager, "/login", "application/x-www-form-urlencoded", QString("userId=" + username + "&userPassword=" + password).toUtf8(), parent); } - -SomfyTahomaEventFetchRequest::SomfyTahomaEventFetchRequest(NetworkAccessManager *networkManager, const QString &eventListenerId, QObject *parent): - SomfyTahomaPostRequest(networkManager, "/events/" + eventListenerId + "/fetch", "application/json", QByteArray(), parent) +SomfyTahomaRequest *createSomfyTahomaEventFetchRequest(NetworkAccessManager *networkManager, const QString &eventListenerId, QObject *parent) { + return createSomfyTahomaPostRequest(networkManager, "/events/" + eventListenerId + "/fetch", "application/json", QByteArray(), parent); } diff --git a/somfytahoma/somfytahomarequests.h b/somfytahoma/somfytahomarequests.h index 60a90627..a72fbccf 100644 --- a/somfytahoma/somfytahomarequests.h +++ b/somfytahoma/somfytahomarequests.h @@ -35,44 +35,21 @@ class NetworkAccessManager; -class SomfyTahomaPostRequest : public QObject +class SomfyTahomaRequest : public QObject { Q_OBJECT public: - SomfyTahomaPostRequest(NetworkAccessManager *networkManager, const QString &path, const QString &contentType, const QByteArray &body, QObject *parent); + SomfyTahomaRequest(QNetworkReply *reply, QObject *parent); signals: void error(QNetworkReply::NetworkError error); void finished(const QVariant &results); }; -class SomfyTahomaGetRequest : public QObject -{ - Q_OBJECT - -public: - SomfyTahomaGetRequest(NetworkAccessManager *networkManager, const QString &path, QObject *parent); - -signals: - void error(QNetworkReply::NetworkError error); - void finished(const QVariant &results); -}; - -class SomfyTahomaLoginRequest : public SomfyTahomaPostRequest -{ - Q_OBJECT - -public: - SomfyTahomaLoginRequest(NetworkAccessManager *networkManager, const QString &username, const QString &password, QObject *parent); -}; - -class SomfyTahomaEventFetchRequest : public SomfyTahomaPostRequest -{ - Q_OBJECT - -public: - SomfyTahomaEventFetchRequest(NetworkAccessManager *networkManager, const QString &eventListenerId, QObject *parent); -}; +SomfyTahomaRequest *createSomfyTahomaPostRequest(NetworkAccessManager *networkManager, const QString &path, const QString &contentType, const QByteArray &body, QObject *parent); +SomfyTahomaRequest *createSomfyTahomaGetRequest(NetworkAccessManager *networkManager, const QString &path, QObject *parent); +SomfyTahomaRequest *createSomfyTahomaLoginRequest(NetworkAccessManager *networkManager, const QString &username, const QString &password, QObject *parent); +SomfyTahomaRequest *createSomfyTahomaEventFetchRequest(NetworkAccessManager *networkManager, const QString &eventListenerId, QObject *parent); #endif // SOMFYTAHOMAREQUESTS_H