From 39dd98354a3bc136546e2933362446b7b4e66e9b Mon Sep 17 00:00:00 2001 From: Martchus Date: Mon, 30 Jul 2018 23:00:40 +0200 Subject: [PATCH] Request Syncthing version --- connector/syncthingconnection.cpp | 46 +++++++++++++++++++++++++++++-- connector/syncthingconnection.h | 14 ++++++++++ 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/connector/syncthingconnection.cpp b/connector/syncthingconnection.cpp index 8cf6d28..18ea8b7 100644 --- a/connector/syncthingconnection.cpp +++ b/connector/syncthingconnection.cpp @@ -75,6 +75,7 @@ SyncthingConnection::SyncthingConnection(const QString &syncthingUrl, const QByt , m_connectionsReply(nullptr) , m_errorsReply(nullptr) , m_eventsReply(nullptr) + , m_versionReply(nullptr) , m_unreadNotifications(false) , m_hasConfig(false) , m_hasStatus(false) @@ -265,6 +266,7 @@ void SyncthingConnection::continueReconnecting() m_startTime = DateTime(); m_lastFileName.clear(); m_lastFileDeleted = false; + m_syncthingVersion.clear(); if (m_apiKey.isEmpty() || m_syncthingUrl.isEmpty()) { emit error(tr("Connection configuration is insufficient."), SyncthingErrorCategory::OverallConnection, QNetworkReply::NoError); return; @@ -688,7 +690,7 @@ SyncthingDev *SyncthingConnection::addDevInfo(std::vector &devs, c return nullptr; } int row; - if (SyncthingDev *existingDevInfo = findDevInfo(devId, row)) { + if (SyncthingDev *const existingDevInfo = findDevInfo(devId, row)) { devs.emplace_back(move(*existingDevInfo)); } else { devs.emplace_back(devId); @@ -708,6 +710,7 @@ void SyncthingConnection::continueConnecting() requestDirStatistics(); requestDeviceStatistics(); requestErrors(); + requestVersion(); for (const SyncthingDir &dir : m_dirs) { requestDirStatus(dir.id); if (!m_requestCompletion) { @@ -742,6 +745,9 @@ void SyncthingConnection::abortAllRequests() if (m_eventsReply) { m_eventsReply->abort(); } + if (m_versionReply) { + m_versionReply->abort(); + } } /*! @@ -851,7 +857,13 @@ void SyncthingConnection::requestCompletion(const QString &devId, const QString void SyncthingConnection::requestDeviceStatistics() { QObject::connect( - requestData(QStringLiteral("stats/device"), QUrlQuery()), &QNetworkReply::finished, this, &SyncthingConnection::readDeviceStatistics); + requestData(QStringLiteral("stats/device"), QUrlQuery()), &QNetworkReply::finished, this, &SyncthingConnection::readDeviceStatistics); +} + +void SyncthingConnection::requestVersion() +{ + QObject::connect( + m_versionReply = requestData(QStringLiteral("system/version"), QUrlQuery()), &QNetworkReply::finished, this, &SyncthingConnection::readVersion); } /*! @@ -2248,6 +2260,36 @@ void SyncthingConnection::readCompletion() } } +void SyncthingConnection::readVersion() +{ + auto *const reply = static_cast(sender()); + reply->deleteLater(); + if (reply == m_versionReply) { + m_versionReply = nullptr; + } + + switch (reply->error()) { + case QNetworkReply::NoError: { + const QByteArray response(reply->readAll()); + QJsonParseError jsonError; + const auto replyDoc(QJsonDocument::fromJson(response, &jsonError)); + if (jsonError.error != QJsonParseError::NoError) { + emitError(tr("Unable to parse version: "), jsonError, reply, response); + return; + } + + const auto replyObj(replyDoc.object()); + m_syncthingVersion = replyObj.value(QLatin1String("longVersion")).toString(); + + break; + } + case QNetworkReply::OperationCanceledError: + return; // intended, not an error + default: + emitError(tr("Unable to request version: "), SyncthingErrorCategory::OverallConnection, reply); + } +} + /*! * \brief Sets the connection status. Ensures statusChanged() is emitted. * \param status Specifies the status; should be either SyncthingStatus::Disconnected, SyncthingStatus::Reconnecting, or diff --git a/connector/syncthingconnection.h b/connector/syncthingconnection.h index 0ff8437..0f9edb7 100644 --- a/connector/syncthingconnection.h +++ b/connector/syncthingconnection.h @@ -83,6 +83,7 @@ class LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingConnection : public QObject { Q_PROPERTY(double totalIncomingRate READ totalIncomingRate NOTIFY trafficChanged) Q_PROPERTY(double totalOutgoingRate READ totalOutgoingRate NOTIFY trafficChanged) Q_PROPERTY(QString lastSyncedFile READ lastSyncedFile) + Q_PROPERTY(QString syncthingVersion READ syncthingVersion) Q_PROPERTY(ChronoUtilities::DateTime lastSyncTime READ lastSyncTime) Q_PROPERTY(QList expectedSslErrors READ expectedSslErrors) Q_PROPERTY(std::vector connectedDevices READ connectedDevices) @@ -133,6 +134,7 @@ public: ChronoUtilities::DateTime lastSyncTime() const; ChronoUtilities::DateTime startTime() const; ChronoUtilities::TimeSpan uptime() const; + const QString &syncthingVersion() const; QMetaObject::Connection requestQrCode(const QString &text, std::function callback); QMetaObject::Connection requestLog(std::function &)> callback); const QList &expectedSslErrors() const; @@ -180,6 +182,7 @@ public Q_SLOTS: void requestDirStatus(const QString &dirId); void requestCompletion(const QString &devId, const QString &dirId); void requestDeviceStatistics(); + void requestVersion(); void postConfigFromJsonObject(const QJsonObject &rawConfig); void postConfigFromByteArray(const QByteArray &rawConfig); @@ -252,6 +255,7 @@ private Q_SLOTS: void readDirRejected(ChronoUtilities::DateTime eventTime, const QString &dirId, const QJsonObject &eventData); void readDevRejected(ChronoUtilities::DateTime eventTime, const QString &devId, const QJsonObject &eventData); void readCompletion(); + void readVersion(); void continueConnecting(); void continueReconnecting(); @@ -298,6 +302,7 @@ private: QNetworkReply *m_connectionsReply; QNetworkReply *m_errorsReply; QNetworkReply *m_eventsReply; + QNetworkReply *m_versionReply; bool m_unreadNotifications; bool m_hasConfig; bool m_hasStatus; @@ -308,6 +313,7 @@ private: ChronoUtilities::DateTime m_lastErrorTime; ChronoUtilities::DateTime m_startTime; QString m_lastFileName; + QString m_syncthingVersion; bool m_lastFileDeleted; QList m_expectedSslErrors; QJsonObject m_rawConfig; @@ -621,6 +627,14 @@ inline ChronoUtilities::TimeSpan SyncthingConnection::uptime() const return ChronoUtilities::DateTime::gmtNow() - m_startTime; } +/*! + * \brief Returns the Syncthing version. + */ +inline const QString &SyncthingConnection::syncthingVersion() const +{ + return m_syncthingVersion; +} + /*! * \brief Returns a list of all expected certificate errors. This is meant to allow self-signed certificates. * \remarks This list is updated via loadSelfSignedCertificate().