333 lines
8.4 KiB
C++
333 lines
8.4 KiB
C++
#ifndef SYNCTHINGCONNECTION_H
|
|
#define SYNCTHINGCONNECTION_H
|
|
|
|
#include <QObject>
|
|
|
|
#include <functional>
|
|
#include <vector>
|
|
|
|
QT_FORWARD_DECLARE_CLASS(QNetworkAccessManager)
|
|
QT_FORWARD_DECLARE_CLASS(QNetworkReply)
|
|
QT_FORWARD_DECLARE_CLASS(QNetworkRequest)
|
|
QT_FORWARD_DECLARE_CLASS(QUrlQuery)
|
|
QT_FORWARD_DECLARE_CLASS(QJsonObject)
|
|
QT_FORWARD_DECLARE_CLASS(QJsonArray)
|
|
|
|
namespace Data {
|
|
|
|
QNetworkAccessManager &networkAccessManager();
|
|
|
|
enum class SyncthingStatus
|
|
{
|
|
Disconnected,
|
|
Default,
|
|
NotificationsAvailable,
|
|
Paused,
|
|
Synchronizing
|
|
};
|
|
|
|
enum class DirStatus
|
|
{
|
|
Unknown,
|
|
Idle,
|
|
Scanning,
|
|
Synchronizing,
|
|
Paused,
|
|
OutOfSync
|
|
};
|
|
|
|
struct SyncthingDir
|
|
{
|
|
QString id;
|
|
QString label;
|
|
QString path;
|
|
QStringList devices;
|
|
bool readOnly;
|
|
bool ignorePermissions;
|
|
bool autoNormalize;
|
|
int rescanInterval;
|
|
int minDiskFreePercentage;
|
|
DirStatus status;
|
|
int progressPercentage;
|
|
};
|
|
|
|
enum class DevStatus
|
|
{
|
|
Unknown,
|
|
Disconnected,
|
|
Idle,
|
|
Synchronizing,
|
|
Paused,
|
|
OutOfSync
|
|
};
|
|
|
|
struct SyncthingDev
|
|
{
|
|
QString id;
|
|
QString name;
|
|
QStringList addresses;
|
|
QString compression;
|
|
QString certName;
|
|
DevStatus status;
|
|
int progressPercentage;
|
|
bool introducer;
|
|
};
|
|
|
|
struct SyncthingLogEntry
|
|
{
|
|
QString when;
|
|
QString message;
|
|
};
|
|
|
|
class SyncthingConnection : public QObject
|
|
{
|
|
Q_OBJECT
|
|
Q_PROPERTY(QString syncthingUrl READ syncthingUrl WRITE setSyncthingUrl)
|
|
Q_PROPERTY(QByteArray apiKey READ apiKey WRITE setApiKey)
|
|
Q_PROPERTY(SyncthingStatus status READ status NOTIFY statusChanged)
|
|
Q_PROPERTY(QString configDir READ configDir NOTIFY configDirChanged)
|
|
Q_PROPERTY(QString myId READ myId NOTIFY myIdChanged)
|
|
|
|
public:
|
|
explicit SyncthingConnection(const QString &syncthingUrl = QStringLiteral("http://localhost:8080"), const QByteArray &apiKey = QByteArray(), QObject *parent = nullptr);
|
|
~SyncthingConnection();
|
|
|
|
const QString &syncthingUrl() const;
|
|
void setSyncthingUrl(const QString &url);
|
|
const QByteArray &apiKey() const;
|
|
void setApiKey(const QByteArray &apiKey);
|
|
const QString &user() const;
|
|
const QString &password() const;
|
|
void setCredentials(const QString &user, const QString &password);
|
|
SyncthingStatus status() const;
|
|
QString statusText() const;
|
|
bool isConnected() const;
|
|
const QString &configDir() const;
|
|
const QString &myId() const;
|
|
const std::vector<SyncthingDir> &dirInfo() const;
|
|
const std::vector<SyncthingDev> &devInfo() const;
|
|
void requestQrCode(const QString &text, std::function<void (const QPixmap &)> callback);
|
|
void requestLog(std::function<void (const std::vector<SyncthingLogEntry> &)> callback);
|
|
|
|
public Q_SLOTS:
|
|
void connect();
|
|
void disconnect();
|
|
void reconnect();
|
|
void pause(const QString &dev);
|
|
void pauseAllDevs();
|
|
void resume(const QString &dev);
|
|
void resumeAllDevs();
|
|
void rescan(const QString &dir);
|
|
void rescanAllDirs();
|
|
void notificationsRead();
|
|
|
|
Q_SIGNALS:
|
|
/*!
|
|
* \brief Indicates new configuration (dirs, devs, ...) is available.
|
|
* \remarks
|
|
* - Configuration is requested automatically when connecting.
|
|
* - Previous directories (and directory info objects!) are invalidated.
|
|
* - Previous devices (and device info objects!) are invalidated.
|
|
*/
|
|
void newConfig(const QJsonObject &config);
|
|
|
|
/*!
|
|
* \brief Indicates new directories are available.
|
|
* \remarks Always emitted after newConfig() as soon as new directory info objects become available.
|
|
*/
|
|
void newDirs(const std::vector<SyncthingDir> &dirs);
|
|
|
|
/*!
|
|
* \brief Indicates new devices are available.
|
|
* \remarks Always emitted after newConfig() as soon as new device info objects become available.
|
|
*/
|
|
void newDevices(const std::vector<SyncthingDev> &devs);
|
|
|
|
/*!
|
|
* \brief Indicates new events (dir status changed, ...) are available.
|
|
* \remarks New events are automatically polled when connected.
|
|
*/
|
|
void newEvents(const QJsonArray &events);
|
|
|
|
/*!
|
|
* \brief Indicates the status of the specified \a dir changed.
|
|
*/
|
|
void dirStatusChanged(const SyncthingDir &dir, int index);
|
|
|
|
void newNotification(const QString &message);
|
|
|
|
/*!
|
|
* \brief Indicates a request (for configuration, events, ...) failed.
|
|
*/
|
|
void error(const QString &errorMessage);
|
|
|
|
/*!
|
|
* \brief Indicates the status of the connection changed.
|
|
*/
|
|
void statusChanged(SyncthingStatus newStatus);
|
|
|
|
/*!
|
|
* \brief Indicates the Syncthing home/configuration directory changed.
|
|
*/
|
|
void configDirChanged(const QString &newConfigDir);
|
|
|
|
/*!
|
|
* \brief Indicates ID of the own Syncthing device changed.
|
|
*/
|
|
void myIdChanged(const QString &myNewId);
|
|
|
|
private Q_SLOTS:
|
|
void requestConfig();
|
|
void requestStatus();
|
|
void requestEvents();
|
|
|
|
void readConfig();
|
|
void readDirs(const QJsonArray &dirs);
|
|
void readDevs(const QJsonArray &devs);
|
|
|
|
void readStatus();
|
|
|
|
void readEvents();
|
|
void readStartingEvent(const QJsonObject &event);
|
|
void readStatusChangedEvent(const QJsonObject &event);
|
|
void readRescan();
|
|
void readPauseResume();
|
|
|
|
void setStatus(SyncthingStatus status);
|
|
|
|
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());
|
|
SyncthingDir *findDirInfo(const QString &dir, int &row);
|
|
|
|
QString m_syncthingUrl;
|
|
QByteArray m_apiKey;
|
|
QString m_user;
|
|
QString m_password;
|
|
SyncthingStatus m_status;
|
|
bool m_keepPolling;
|
|
bool m_reconnecting;
|
|
int m_lastEventId;
|
|
QString m_configDir;
|
|
QString m_myId;
|
|
QNetworkReply *m_configReply;
|
|
QNetworkReply *m_statusReply;
|
|
QNetworkReply *m_eventsReply;
|
|
bool m_unreadNotifications;
|
|
std::vector<SyncthingDir> m_dirs;
|
|
std::vector<SyncthingDev> m_devs;
|
|
};
|
|
|
|
/*!
|
|
* \brief Returns the URL used to connect to Syncthing.
|
|
*/
|
|
inline const QString &SyncthingConnection::syncthingUrl() const
|
|
{
|
|
return m_syncthingUrl;
|
|
}
|
|
|
|
/*!
|
|
* \brief Sets the URL used to connect to Syncthing.
|
|
*/
|
|
inline void SyncthingConnection::setSyncthingUrl(const QString &url)
|
|
{
|
|
m_syncthingUrl = url;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the API key used to connect to Syncthing.
|
|
*/
|
|
inline const QByteArray &SyncthingConnection::apiKey() const
|
|
{
|
|
return m_apiKey;
|
|
}
|
|
|
|
/*!
|
|
* \brief Sets the API key used to connect to Syncthing.
|
|
*/
|
|
inline void SyncthingConnection::setApiKey(const QByteArray &apiKey)
|
|
{
|
|
m_apiKey = apiKey;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the user name which has been set using setCredentials().
|
|
*/
|
|
inline const QString &SyncthingConnection::user() const
|
|
{
|
|
return m_user;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the password which has been set using setCredentials().
|
|
*/
|
|
inline const QString &SyncthingConnection::password() const
|
|
{
|
|
return m_password;
|
|
}
|
|
|
|
/*!
|
|
* \brief Provides credentials used for HTTP authentication.
|
|
*/
|
|
inline void SyncthingConnection::setCredentials(const QString &user, const QString &password)
|
|
{
|
|
m_user = user, m_password = password;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the connection status.
|
|
*/
|
|
inline SyncthingStatus SyncthingConnection::status() const
|
|
{
|
|
return m_status;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns whether the connection has been established.
|
|
*/
|
|
inline bool SyncthingConnection::isConnected() const
|
|
{
|
|
return m_status != SyncthingStatus::Disconnected;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the Syncthing home/configuration directory.
|
|
*/
|
|
inline const QString &SyncthingConnection::configDir() const
|
|
{
|
|
return m_configDir;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns the ID of the own Syncthing device.
|
|
*/
|
|
inline const QString &SyncthingConnection::myId() const
|
|
{
|
|
return m_myId;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns all available directory info.
|
|
* \remarks The returned object container object is persistent. However, the contained
|
|
* info objects are invalidated when the newConfig() signal is emitted.
|
|
*/
|
|
inline const std::vector<SyncthingDir> &SyncthingConnection::dirInfo() const
|
|
{
|
|
return m_dirs;
|
|
}
|
|
|
|
/*!
|
|
* \brief Returns all available device info.
|
|
* \remarks The returned object container object is persistent. However, the contained
|
|
* info objects are invalidated when the newConfig() signal is emitted.
|
|
*/
|
|
inline const std::vector<SyncthingDev> &SyncthingConnection::devInfo() const
|
|
{
|
|
return m_devs;
|
|
}
|
|
|
|
}
|
|
|
|
#endif // SYNCTHINGCONNECTION_H
|