connector: Update raw config after pausing/resuming
It seems like (cached) raw config is not automatically updated via newConfig() after pausing/resuming a dir/dev. So this is now done manually. Additionally, pausing/resuming devs is now also implemented by posting new config.
This commit is contained in:
parent
5d05e9a5df
commit
04c9caf7d4
|
@ -291,12 +291,21 @@ void Application::requestPauseResume(bool pause)
|
|||
++m_expectedResponse;
|
||||
}
|
||||
}
|
||||
for (const SyncthingDev *dev : m_relevantDevs) {
|
||||
if (pause) {
|
||||
cerr << "Request pausing device ";
|
||||
if (!m_relevantDevs.empty()) {
|
||||
QStringList devIds;
|
||||
devIds.reserve(m_relevantDirs.size());
|
||||
for (const SyncthingDev *dev : m_relevantDevs) {
|
||||
devIds << dev->id;
|
||||
}
|
||||
if (pause) {
|
||||
cerr << "Request pausing devices ";
|
||||
} else {
|
||||
cerr << "Request resuming devices ";
|
||||
}
|
||||
cerr << devIds.join(QStringLiteral(", ")).toLocal8Bit().data() << " ...\n";
|
||||
if (pause ? m_connection.pauseDirectories(devIds) : m_connection.resumeDirectories(devIds)) {
|
||||
++m_expectedResponse;
|
||||
}
|
||||
cerr << dev->id.toLocal8Bit().data() << " ...\n";
|
||||
pause ? m_connection.pauseDevice(dev->id) : m_connection.resumeDevice(dev->id);
|
||||
}
|
||||
cerr.flush();
|
||||
}
|
||||
|
|
|
@ -243,18 +243,13 @@ void SyncthingConnection::autoReconnect()
|
|||
}
|
||||
|
||||
/*!
|
||||
* \brief Requests pausing the device with the specified ID.
|
||||
* \brief Requests pausing the devices with the specified IDs.
|
||||
*
|
||||
* The signal error() is emitted when the request was not successful.
|
||||
*/
|
||||
void SyncthingConnection::pauseDevice(const QString &devId)
|
||||
bool SyncthingConnection::pauseDevice(const QStringList &devIds)
|
||||
{
|
||||
QUrlQuery query;
|
||||
query.addQueryItem(QStringLiteral("device"), devId);
|
||||
QNetworkReply *reply = postData(QStringLiteral("system/pause"), query);
|
||||
reply->setProperty("devId", devId);
|
||||
reply->setProperty("resume", false);
|
||||
QObject::connect(reply, &QNetworkReply::finished, this, &SyncthingConnection::readDevPauseResume);
|
||||
return pauseResumeDevice(devIds, true);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -262,26 +257,19 @@ void SyncthingConnection::pauseDevice(const QString &devId)
|
|||
*
|
||||
* The signal error() is emitted when the request was not successful.
|
||||
*/
|
||||
void SyncthingConnection::pauseAllDevs()
|
||||
bool SyncthingConnection::pauseAllDevs()
|
||||
{
|
||||
for (const SyncthingDev &dev : m_devs) {
|
||||
pauseDevice(dev.id);
|
||||
}
|
||||
return pauseResumeDevice(deviceIds(), true);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Requests resuming the device with the specified ID.
|
||||
* \brief Requests resuming the devices with the specified IDs.
|
||||
*
|
||||
* The signal error() is emitted when the request was not successful.
|
||||
*/
|
||||
void SyncthingConnection::resumeDevice(const QString &devId)
|
||||
bool SyncthingConnection::resumeDevice(const QStringList &devIds)
|
||||
{
|
||||
QUrlQuery query;
|
||||
query.addQueryItem(QStringLiteral("device"), devId);
|
||||
QNetworkReply *reply = postData(QStringLiteral("system/resume"), query);
|
||||
reply->setProperty("devId", devId);
|
||||
reply->setProperty("resume", true);
|
||||
QObject::connect(reply, &QNetworkReply::finished, this, &SyncthingConnection::readDevPauseResume);
|
||||
return pauseResumeDevice(devIds, false);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -289,39 +277,9 @@ void SyncthingConnection::resumeDevice(const QString &devId)
|
|||
*
|
||||
* The signal error() is emitted when the request was not successful.
|
||||
*/
|
||||
void SyncthingConnection::resumeAllDevs()
|
||||
bool SyncthingConnection::resumeAllDevs()
|
||||
{
|
||||
for (const SyncthingDev &dev : m_devs) {
|
||||
resumeDevice(dev.id);
|
||||
}
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Alters the specified \a config so that the specified \a dirs are paused or not.
|
||||
* \returns Returns whether the config has been altered (all dirs might have been already paused/unpaused).
|
||||
*/
|
||||
bool setPaused(QJsonObject &config, const QStringList &dirs, bool paused)
|
||||
{
|
||||
bool altered = false;
|
||||
QJsonValueRef folders = config.find(QLatin1String("folders")).value();
|
||||
if (folders.isArray()) {
|
||||
QJsonArray foldersArray = folders.toArray();
|
||||
for (QJsonValueRef folder : foldersArray) {
|
||||
QJsonObject folderObj = folder.toObject();
|
||||
if (dirs.isEmpty() || dirs.contains(folderObj.value(QLatin1String("id")).toString())) {
|
||||
QJsonValueRef pausedValue = folderObj.find(QLatin1String("paused")).value();
|
||||
if (pausedValue.toBool(false) != paused) {
|
||||
pausedValue = paused;
|
||||
folder = folderObj;
|
||||
altered = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (altered) {
|
||||
folders = foldersArray;
|
||||
}
|
||||
}
|
||||
return altered;
|
||||
return pauseResumeDevice(deviceIds(), false);
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -461,7 +419,37 @@ QNetworkReply *SyncthingConnection::postData(const QString &path, const QUrlQuer
|
|||
* \brief Internally used to pause/resume directories.
|
||||
* \returns Returns whether a request has been made.
|
||||
* \remarks This might currently result in errors caused by Syncthing not
|
||||
* handling E notation correctly:
|
||||
* handling E notation correctly when using Qt < 5.9:
|
||||
* https://github.com/syncthing/syncthing/issues/4001
|
||||
*/
|
||||
bool SyncthingConnection::pauseResumeDevice(const QStringList &devIds, bool paused)
|
||||
{
|
||||
if (devIds.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
if (!isConnected()) {
|
||||
emit error(tr("Unable to pause/resume a devices when not connected"), SyncthingErrorCategory::SpecificRequest, QNetworkReply::NoError);
|
||||
return false;
|
||||
}
|
||||
|
||||
QJsonObject config = m_rawConfig;
|
||||
if (setDevicesPaused(config, devIds, paused)) {
|
||||
QJsonDocument doc;
|
||||
doc.setObject(config);
|
||||
QNetworkReply *reply = postData(QStringLiteral("system/config"), QUrlQuery(), doc.toJson(QJsonDocument::Compact));
|
||||
reply->setProperty("devIds", devIds);
|
||||
reply->setProperty("resume", !paused);
|
||||
QObject::connect(reply, &QNetworkReply::finished, this, &SyncthingConnection::readDevPauseResume);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Internally used to pause/resume directories.
|
||||
* \returns Returns whether a request has been made.
|
||||
* \remarks This might currently result in errors caused by Syncthing not
|
||||
* handling E notation correctly when using Qt < 5.9:
|
||||
* https://github.com/syncthing/syncthing/issues/4001
|
||||
*/
|
||||
bool SyncthingConnection::pauseResumeDirectory(const QStringList &dirIds, bool paused)
|
||||
|
@ -475,7 +463,7 @@ bool SyncthingConnection::pauseResumeDirectory(const QStringList &dirIds, bool p
|
|||
}
|
||||
|
||||
QJsonObject config = m_rawConfig;
|
||||
if (setPaused(config, dirIds, paused)) {
|
||||
if (setDirectoriesPaused(config, dirIds, paused)) {
|
||||
QJsonDocument doc;
|
||||
doc.setObject(config);
|
||||
QNetworkReply *reply = postData(QStringLiteral("system/config"), QUrlQuery(), doc.toJson(QJsonDocument::Compact));
|
||||
|
@ -1631,14 +1619,17 @@ void SyncthingConnection::readDevPauseResume()
|
|||
auto *reply = static_cast<QNetworkReply *>(sender());
|
||||
reply->deleteLater();
|
||||
switch (reply->error()) {
|
||||
case QNetworkReply::NoError:
|
||||
case QNetworkReply::NoError: {
|
||||
const QStringList devIds(reply->property("devIds").toStringList());
|
||||
const bool resume = reply->property("resume").toBool();
|
||||
setDevicesPaused(m_rawConfig, devIds, !resume);
|
||||
if (reply->property("resume").toBool()) {
|
||||
emit deviceResumeTriggered(reply->property("devId").toString());
|
||||
emit deviceResumeTriggered(devIds);
|
||||
} else {
|
||||
emit devicePauseTriggered(reply->property("devId").toString());
|
||||
emit devicePauseTriggered(devIds);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
} default:
|
||||
emit error(tr("Unable to request device pause/resume: ") + reply->errorString(), SyncthingErrorCategory::SpecificRequest, reply->error());
|
||||
}
|
||||
}
|
||||
|
@ -1648,14 +1639,17 @@ void SyncthingConnection::readDirPauseResume()
|
|||
auto *reply = static_cast<QNetworkReply *>(sender());
|
||||
reply->deleteLater();
|
||||
switch (reply->error()) {
|
||||
case QNetworkReply::NoError:
|
||||
if (reply->property("resume").toBool()) {
|
||||
emit directoryResumeTriggered(reply->property("dirIds").toStringList());
|
||||
case QNetworkReply::NoError: {
|
||||
const QStringList dirIds(reply->property("dirIds").toStringList());
|
||||
const bool resume = reply->property("resume").toBool();
|
||||
setDirectoriesPaused(m_rawConfig, dirIds, !resume);
|
||||
if (resume) {
|
||||
emit directoryResumeTriggered(dirIds);
|
||||
} else {
|
||||
emit directoryPauseTriggered(reply->property("dirIds").toStringList());
|
||||
emit directoryPauseTriggered(dirIds);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
} default:
|
||||
emit error(tr("Unable to request directory pause/resume: ") + reply->errorString(), SyncthingErrorCategory::SpecificRequest, reply->error());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -123,10 +123,10 @@ public Q_SLOTS:
|
|||
void disconnect();
|
||||
void reconnect();
|
||||
void reconnect(SyncthingConnectionSettings &connectionSettings);
|
||||
void pauseDevice(const QString &devId);
|
||||
void pauseAllDevs();
|
||||
void resumeDevice(const QString &devId);
|
||||
void resumeAllDevs();
|
||||
bool pauseDevice(const QStringList &devIds);
|
||||
bool pauseAllDevs();
|
||||
bool resumeDevice(const QStringList &devIds);
|
||||
bool resumeAllDevs();
|
||||
bool pauseDirectories(const QStringList &dirIds);
|
||||
bool pauseAllDirs();
|
||||
bool resumeDirectories(const QStringList &dirIds);
|
||||
|
@ -152,8 +152,8 @@ Q_SIGNALS:
|
|||
void myIdChanged(const QString &myNewId);
|
||||
void trafficChanged(uint64 totalIncomingTraffic, uint64 totalOutgoingTraffic);
|
||||
void rescanTriggered(const QString &dirId);
|
||||
void devicePauseTriggered(const QString &devId);
|
||||
void deviceResumeTriggered(const QString &devId);
|
||||
void devicePauseTriggered(const QStringList &devIds);
|
||||
void deviceResumeTriggered(const QStringList &devIds);
|
||||
void directoryPauseTriggered(const QStringList &dirIds);
|
||||
void directoryResumeTriggered(const QStringList &dirIds);
|
||||
void restartTriggered();
|
||||
|
@ -203,6 +203,7 @@ private:
|
|||
QNetworkRequest prepareRequest(const QString &path, const QUrlQuery &query, bool rest = true);
|
||||
QNetworkReply *requestData(const QString &path, const QUrlQuery &query, bool rest = true);
|
||||
QNetworkReply *postData(const QString &path, const QUrlQuery &query, const QByteArray &data = QByteArray());
|
||||
bool pauseResumeDevice(const QStringList &devIds, bool paused);
|
||||
bool pauseResumeDirectory(const QStringList &dirIds, bool paused);
|
||||
SyncthingDir *addDirInfo(std::vector<SyncthingDir> &dirs, const QString &dirId);
|
||||
SyncthingDev *addDevInfo(std::vector<SyncthingDev> &devs, const QString &devId);
|
||||
|
|
|
@ -4,6 +4,9 @@
|
|||
|
||||
#include <QCoreApplication>
|
||||
#include <QHostAddress>
|
||||
#include <QJsonArray>
|
||||
#include <QJsonObject>
|
||||
#include <QJsonValue>
|
||||
#include <QNetworkInterface>
|
||||
#include <QString>
|
||||
#include <QUrl>
|
||||
|
@ -36,4 +39,60 @@ bool isLocal(const QUrl &url)
|
|||
return host.compare(QLatin1String("localhost"), Qt::CaseInsensitive) == 0 || hostAddress.isLoopback()
|
||||
|| QNetworkInterface::allAddresses().contains(hostAddress);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Alters the specified \a syncthingConfig so that the dirs with specified IDs are paused or not.
|
||||
* \returns Returns whether the config has been altered (all dirs might have been already paused/unpaused).
|
||||
*/
|
||||
bool setDirectoriesPaused(QJsonObject &syncthingConfig, const QStringList &dirIds, bool paused)
|
||||
{
|
||||
bool altered = false;
|
||||
QJsonValueRef folders = syncthingConfig.find(QLatin1String("folders")).value();
|
||||
if (folders.isArray()) {
|
||||
QJsonArray foldersArray = folders.toArray();
|
||||
for (QJsonValueRef folder : foldersArray) {
|
||||
QJsonObject folderObj = folder.toObject();
|
||||
if (dirIds.isEmpty() || dirIds.contains(folderObj.value(QLatin1String("id")).toString())) {
|
||||
QJsonValueRef pausedValue = folderObj.find(QLatin1String("paused")).value();
|
||||
if (pausedValue.toBool(false) != paused) {
|
||||
pausedValue = paused;
|
||||
folder = folderObj;
|
||||
altered = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (altered) {
|
||||
folders = foldersArray;
|
||||
}
|
||||
}
|
||||
return altered;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Alters the specified \a syncthingConfig so that the devs with the specified IDs are paused or not.
|
||||
* \returns Returns whether the config has been altered (all devs might have been already paused/unpaused).
|
||||
*/
|
||||
bool setDevicesPaused(QJsonObject &syncthingConfig, const QStringList &devIds, bool paused)
|
||||
{
|
||||
bool altered = false;
|
||||
QJsonValueRef devices = syncthingConfig.find(QLatin1String("devices")).value();
|
||||
if (devices.isArray()) {
|
||||
QJsonArray devicesArray = devices.toArray();
|
||||
for (QJsonValueRef device : devicesArray) {
|
||||
QJsonObject deviceObj = device.toObject();
|
||||
if (devIds.isEmpty() || devIds.contains(deviceObj.value(QLatin1String("deviceID")).toString())) {
|
||||
QJsonValueRef pausedValue = deviceObj.find(QLatin1String("paused")).value();
|
||||
if (pausedValue.toBool(false) != paused) {
|
||||
pausedValue = paused;
|
||||
device = deviceObj;
|
||||
altered = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (altered) {
|
||||
devices = devicesArray;
|
||||
}
|
||||
}
|
||||
return altered;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#include <QStringList>
|
||||
|
||||
QT_FORWARD_DECLARE_CLASS(QUrl)
|
||||
QT_FORWARD_DECLARE_CLASS(QJsonObject)
|
||||
|
||||
namespace ChronoUtilities {
|
||||
class DateTime;
|
||||
|
@ -15,6 +16,8 @@ namespace Data {
|
|||
|
||||
QString LIB_SYNCTHING_CONNECTOR_EXPORT agoString(ChronoUtilities::DateTime dateTime);
|
||||
bool LIB_SYNCTHING_CONNECTOR_EXPORT isLocal(const QUrl &url);
|
||||
bool LIB_SYNCTHING_CONNECTOR_EXPORT setDirectoriesPaused(QJsonObject &syncthingConfig, const QStringList &dirIds, bool paused);
|
||||
bool LIB_SYNCTHING_CONNECTOR_EXPORT setDevicesPaused(QJsonObject &syncthingConfig, const QStringList &dirs, bool paused);
|
||||
|
||||
template <class Objects> QStringList LIB_SYNCTHING_CONNECTOR_EXPORT ids(const Objects &objects)
|
||||
{
|
||||
|
|
|
@ -464,9 +464,9 @@ void TrayWidget::scanDir(const SyncthingDir &dir)
|
|||
void TrayWidget::pauseResumeDev(const SyncthingDev &dev)
|
||||
{
|
||||
if (dev.paused) {
|
||||
m_connection.resumeDevice(dev.id);
|
||||
m_connection.resumeDevice(QStringList(dev.id));
|
||||
} else {
|
||||
m_connection.pauseDevice(dev.id);
|
||||
m_connection.pauseDevice(QStringList(dev.id));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue