Skip to content

Commit

Permalink
Merge pull request #121 from sieren/retrieve-api-key-config
Browse files Browse the repository at this point in the history
Support Syncthing v13 and use API from Config
  • Loading branch information
sieren committed May 26, 2016
2 parents ec2fde6 + 129cfc1 commit 530400a
Show file tree
Hide file tree
Showing 10 changed files with 164 additions and 75 deletions.
63 changes: 33 additions & 30 deletions src/apihandler.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ namespace api

struct APIHandlerBase
{
const int version = 0;

std::pair<QString, bool> getConnectionInfo(QNetworkReply *reply)
{
QString result;
Expand Down Expand Up @@ -127,20 +129,6 @@ namespace api
return {curInBytes/kBytesToKilobytes, curOutBytes/kBytesToKilobytes};
}

QString getCurrentAPIKey(QByteArray reply)
{
QString apiKey;
if (reply.size() > 0)
{
QString m_DownloadedData = static_cast<QString>(reply);
QJsonDocument replyDoc = QJsonDocument::fromJson(m_DownloadedData.toUtf8());
QJsonObject replyData = replyDoc.object();
QJsonObject guiData = replyData["gui"].toObject();
apiKey = guiData["apiKey"].toString();
}
return apiKey;
}

LastSyncedFileList getLastSyncedFiles(QByteArray reply)
{
QString m_DownloadedData = static_cast<QString>(reply);
Expand Down Expand Up @@ -195,8 +183,10 @@ namespace api
// API Specializations

// Syncthing API V11 Specializations
struct V12API : public APIHandlerBase
struct V11API : public APIHandlerBase
{
const int version = 11;

ConnectionHealthStatus getConnections(QByteArray reply) override
{
ConnectionHealthStatus result;
Expand All @@ -214,23 +204,18 @@ namespace api
QJsonDocument replyDoc = QJsonDocument::fromJson(m_DownloadedData.toUtf8());
QJsonObject replyData = replyDoc.object();
QJsonObject connectionArray = replyData["connections"].toObject();
int active = 0;
for (QJsonObject::Iterator it = connectionArray.begin();
it != connectionArray.end(); it++)
{
QJsonObject jObj = it->toObject();
active += jObj.find("connected").value().toBool() ? 1 : 0;
}
result.emplace("activeConnections", QString(active));
result.emplace("totalConnections", QString(connectionArray.size()));
result.emplace("activeConnections", QString::number(connectionArray.size()));
result.emplace("totalConnections", QString::number(connectionArray.size()));
}
return result;
}
};
// Syncthing API V11 Specializations
struct V11API : public APIHandlerBase

// Syncthing API V12 Specializations
struct V12API : public APIHandlerBase
{
const int version = 12;

ConnectionHealthStatus getConnections(QByteArray reply) override
{
ConnectionHealthStatus result;
Expand All @@ -248,25 +233,43 @@ namespace api
QJsonDocument replyDoc = QJsonDocument::fromJson(m_DownloadedData.toUtf8());
QJsonObject replyData = replyDoc.object();
QJsonObject connectionArray = replyData["connections"].toObject();
result.emplace("activeConnections", QString(connectionArray.size()));
result.emplace("totalConnections", QString(connectionArray.size()));
int active = 0;
for (QJsonObject::Iterator it = connectionArray.begin();
it != connectionArray.end(); it++)
{
QJsonObject jObj = it->toObject();
active += jObj.find("connected").value().toBool() ? 1 : 0;
}
result.emplace("activeConnections", QString::number(active));
result.emplace("totalConnections", QString::number(connectionArray.size()));
}
return result;
}
};

// Syncthing API V13 Specializations
struct V13API : public V12API
{
const int version = 13;
using V12API::getConnections;
};


inline APIHandlerBase *APIHandlerBase::getAPIForVersion(int version)
{
switch (version)
{
case 13:
return new V13API;
break;
case 12:
return new V12API;
break;
case 11:
return new V11API;
break;
default:
return new V12API;
return new V13API;
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/platforms/darwin/macUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
#include <string>
#include <iostream>
#include <Carbon/Carbon.h>
#include <QProcessEnvironment>
#include <QString>
#define UNUSED(x) (void)(x)

namespace qst
Expand Down Expand Up @@ -87,6 +89,13 @@ namespace darwin
return result;
}

static QString getDefaultSyncthingConfig()
{
QString path = QProcessEnvironment::systemEnvironment().value("HOME", "~");
path.append("/Library/Application Support/Syncthing/config.xml");
return{path};
}

template<typename U, typename T>
void doubleClicked(U&& func, T ref)
{
Expand Down
9 changes: 9 additions & 0 deletions src/platforms/linux/posixUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <sstream>
#include <string>
#include <iostream>
#include <QProcessEnvironment>
#include <QString>
#define UNUSED(x) (void)(x)

namespace qst
Expand Down Expand Up @@ -68,6 +70,13 @@ namespace gnu_linux
return result;
}

static QString getDefaultSyncthingConfig()
{
QString path = QProcessEnvironment::systemEnvironment().value("HOME", "~");
path.append("/.config/syncthing/config.xml");
return{path};
}

template<typename U, typename T>
void doubleClicked(U&& func, T ref)
{
Expand Down
9 changes: 9 additions & 0 deletions src/platforms/windows/winUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,11 @@
#include <string>
#include <iostream>
#include <cstdio>
#include <QProcessEnvironment>
#include <windows.h>
#include <tlhelp32.h>
#include <comdef.h>
#include <QString>
#define UNUSED(x) (void)(x)

namespace qst
Expand Down Expand Up @@ -76,6 +78,13 @@ namespace windows

}

static QString getDefaultSyncthingConfig()
{
QString path = QProcessEnvironment::systemEnvironment().value("localappdata", "localappdata");
path.append("\\Syncthing\\config.xml");
return{path};
}

template<typename U, typename T>
void doubleClicked(U&& func, T ref)
{
Expand Down
10 changes: 4 additions & 6 deletions src/startuptab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ StartupTab::StartupTab(std::shared_ptr<qst::connector::SyncConnector> pSyncConne
&StartupTab::processSpawnedChanged);

mpSyncConnector->spawnSyncthingProcess(mCurrentSyncthingPath, mShouldLaunchSyncthing);
mpSyncConnector->spawnINotifyProcess(mCurrentINotifyPath, mShouldLaunchINotify);
}


Expand Down Expand Up @@ -205,6 +204,7 @@ void StartupTab::launchINotifyBoxChanged(int state)
mShouldLaunchINotify = state == Qt::Checked ? true : false;
saveSettings();
pathEnterPressed();
mpSyncConnector->checkAndSpawnINotifyProcess(false);
}


Expand All @@ -231,12 +231,9 @@ void StartupTab::saveSettings()
pathEnterPressed();
}
mSettings.setValue("inotifypath", tr(mCurrentINotifyPath.c_str()));
if (mSettings.value("launchINotifyAtStartup").toBool() != mShouldLaunchINotify)
{
mpSyncConnector->spawnINotifyProcess(mCurrentINotifyPath, mShouldLaunchINotify);
}
mSettings.setValue("launchINotifyAtStartup", mShouldLaunchINotify);
mSettings.setValue("ShutdownOnExit", mShouldShutdownOnExit);
mpSyncConnector->onSettingsChanged();
}


Expand All @@ -256,6 +253,7 @@ void StartupTab::loadSettings()

void StartupTab::pathEnterPressed()
{
saveSettings();
mCurrentSyncthingPath = mpFilePathLine->text().toStdString();
mCurrentINotifyPath = mpINotifyFilePath->text().toStdString();
if (mSettings.value("syncthingpath").toString().toStdString() != mCurrentSyncthingPath)
Expand All @@ -264,7 +262,7 @@ void StartupTab::pathEnterPressed()
}
if (mSettings.value("inotifypath").toString().toStdString() != mCurrentINotifyPath)
{
mpSyncConnector->spawnINotifyProcess(mCurrentINotifyPath, true, true);
mpSyncConnector->checkAndSpawnINotifyProcess(true);
}
}

Expand Down
52 changes: 35 additions & 17 deletions src/syncconnector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ SyncConnector::SyncConnector(QUrl url) :
mCurrentUrl(url)
, mSettings("sieren", "QSyncthingTray")
{
onSettingsChanged();
connect(
&network, SIGNAL (finished(QNetworkReply*)),
this, SLOT (netRequestfinished(QNetworkReply*))
Expand All @@ -53,7 +54,6 @@ SyncConnector::SyncConnector(QUrl url) :
SLOT(checkConnectionHealth()));
connect(mpConnectionAvailabilityTimer.get(), SIGNAL(timeout()), this,
SLOT(testUrlAvailability()));
onSettingsChanged();
}


Expand All @@ -79,6 +79,8 @@ void SyncConnector::testUrlAvailability()
QUrl url = mCurrentUrl;
url.setPath(tr("/rest/system/version"));
QNetworkRequest request(url);
QByteArray headerByte(mAPIKey.toStdString().c_str(), mAPIKey.size());
request.setRawHeader(QByteArray("X-API-Key"), headerByte);
network.clearAccessCache();
QNetworkReply *reply = network.get(request);
requestMap[reply] = kRequestMethod::urlTested;
Expand Down Expand Up @@ -124,7 +126,7 @@ void SyncConnector::urlTested(QNetworkReply* reply)
if (reply->error() == QNetworkReply::TimeoutError ||
reply->error() == QNetworkReply::ConnectionRefusedError)
{
mAPIHandler = nullptr;
shutdownINotifyProcess();
mpConnectionAvailabilityTimer->start(1000);
}
else
Expand All @@ -133,7 +135,7 @@ void SyncConnector::urlTested(QNetworkReply* reply)
api::V12API().getConnectionInfo(reply);

int versionNumber = getCurrentVersion(connectionInfo.first);
if (mAPIHandler == nullptr)
if (mAPIHandler == nullptr || mAPIHandler->version != versionNumber)
{
mAPIHandler =
std::unique_ptr<api::APIHandlerBase>(api::V12API().getAPIForVersion(versionNumber));
Expand All @@ -144,6 +146,7 @@ void SyncConnector::urlTested(QNetworkReply* reply)
}
mpConnectionAvailabilityTimer->stop();
mpConnectionHealthTimer->start(mConnectionHealthTime);
checkAndSpawnINotifyProcess(false);
}
reply->deleteLater();
}
Expand All @@ -156,6 +159,8 @@ void SyncConnector::checkConnectionHealth()
QUrl requestUrl = mCurrentUrl;
requestUrl.setPath(tr("/rest/system/connections"));
QNetworkRequest healthRequest(requestUrl);
QByteArray headerByte(mAPIKey.toStdString().c_str(), mAPIKey.size());
healthRequest.setRawHeader(QByteArray("X-API-Key"), headerByte);
QNetworkReply *reply = network.get(healthRequest);
requestMap[reply] = kRequestMethod::connectionHealth;

Expand All @@ -176,7 +181,8 @@ void SyncConnector::getCurrentConfig()
QUrl requestUrl = mCurrentUrl;
requestUrl.setPath(tr("/rest/system/config"));
QNetworkRequest request(requestUrl);

QByteArray headerByte(mAPIKey.toStdString().c_str(), mAPIKey.size());
request.setRawHeader(QByteArray("X-API-Key"), headerByte);
QNetworkReply *reply = network.get(request);
requestMap[reply] = kRequestMethod::getCurrentConfig;
}
Expand Down Expand Up @@ -262,7 +268,6 @@ void SyncConnector::currentConfigReceived(QNetworkReply *reply)
{
replyData = reply->readAll();
}
mAPIKey = mAPIHandler->getCurrentAPIKey(replyData);
mFolders = mAPIHandler->getCurrentFolderList(replyData);
reply->deleteLater();
}
Expand Down Expand Up @@ -303,7 +308,7 @@ void SyncConnector::pauseSyncthing(bool paused)
else
{
spawnSyncthingProcess(mSyncthingFilePath, true);
spawnINotifyProcess(mINotifyFilePath, true);
checkAndSpawnINotifyProcess(false);
setURL(mCurrentUrl, mCurrentUrl.userName().toStdString(),
mCurrentUrl.password().toStdString(), mConnectionStateCallback);
}
Expand Down Expand Up @@ -340,6 +345,9 @@ void SyncConnector::onSettingsChanged()
mConnectionHealthTime = std::round(
1000 * mSettings.value("pollingInterval").toDouble());
mConnectionHealthTime = mConnectionHealthTime == 0 ? 1000 : mConnectionHealthTime;
mAPIKey = mSettings.value("apiKey").toString();
mINotifyFilePath = mSettings.value("inotifypath").toString();
mShouldLaunchINotify = mSettings.value("launchINotifyAtStartup").toBool();
}


Expand Down Expand Up @@ -394,13 +402,15 @@ void SyncConnector::spawnSyncthingProcess(

//------------------------------------------------------------------------------------//

void SyncConnector::spawnINotifyProcess(
std::string filePath, const bool shouldSpawn, const bool onSetPath)
void SyncConnector::checkAndSpawnINotifyProcess(bool isRequestedExternal)
{
mINotifyFilePath = filePath;
if (shouldSpawn)
if (isRequestedExternal)
{
if (!checkIfFileExists(tr(filePath.c_str())) && onSetPath)
onSettingsChanged();
}
if (mShouldLaunchINotify)
{
if (!checkIfFileExists(mINotifyFilePath) && isRequestedExternal)
{
QMessageBox msgBox;
msgBox.setText("Could not find iNotify.");
Expand All @@ -412,17 +422,25 @@ void SyncConnector::spawnINotifyProcess(
if (!systemUtil.isBinaryRunning(std::string("syncthing-inotify")))
{
mpSyncthingNotifierProcess = std::unique_ptr<QProcess>(new QProcess(this));
QString processPath = QDir::toNativeSeparators(filePath.c_str());
QString processPath = QDir::toNativeSeparators(mINotifyFilePath);
mpSyncthingNotifierProcess->start(processPath, QStringList(), QIODevice::Unbuffered);
}
}
else
{
if (mpSyncthingNotifierProcess != nullptr
&& mpSyncthingNotifierProcess->state() == QProcess::Running)
{
mpSyncthingNotifierProcess->kill();
}
shutdownINotifyProcess();
}
}


//------------------------------------------------------------------------------------//

void SyncConnector::shutdownINotifyProcess()
{
if (mpSyncthingNotifierProcess != nullptr &&
mpSyncthingNotifierProcess->state() == QProcess::Running)
{
mpSyncthingNotifierProcess->kill();
}
}

Expand Down
Loading

0 comments on commit 530400a

Please sign in to comment.