Allow printing current config
This commit is contained in:
parent
e9e85e6ba9
commit
754cd0c2e1
|
@ -17,6 +17,7 @@
|
|||
|
||||
#include <QCoreApplication>
|
||||
#include <QDir>
|
||||
#include <QJsonDocument>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QStringBuilder>
|
||||
#include <QTimer>
|
||||
|
@ -57,6 +58,7 @@ Application::Application()
|
|||
: m_expectedResponse(0)
|
||||
, m_preventDisconnect(false)
|
||||
, m_callbacksInvoked(false)
|
||||
, m_requiresMainEventLoop(true)
|
||||
, m_idleDuration(0)
|
||||
, m_idleTimeout(0)
|
||||
, m_argsRead(false)
|
||||
|
@ -76,6 +78,7 @@ Application::Application()
|
|||
m_args.resume.setCallback(bind(&Application::requestPauseResume, this, false));
|
||||
m_args.waitForIdle.setCallback(bind(&Application::waitForIdle, this, _1));
|
||||
m_args.pwd.setCallback(bind(&Application::checkPwdOperationPresent, this, _1));
|
||||
m_args.cat.setCallback(bind(&Application::printConfig, this, _1));
|
||||
m_args.statusPwd.setCallback(bind(&Application::printPwdStatus, this, _1));
|
||||
m_args.rescanPwd.setCallback(bind(&Application::requestRescanPwd, this, _1));
|
||||
m_args.pausePwd.setCallback(bind(&Application::requestPausePwd, this, _1));
|
||||
|
@ -125,7 +128,7 @@ int Application::exec(int argc, const char *const *argv)
|
|||
// finally do the request or establish connection
|
||||
if (m_args.status.isPresent() || m_args.rescan.isPresent() || m_args.rescanAll.isPresent() || m_args.pause.isPresent()
|
||||
|| m_args.resume.isPresent() || m_args.waitForIdle.isPresent() || m_args.pwd.isPresent()) {
|
||||
// those arguments rquire establishing a connection first, the actual handler is called by handleStatusChanged() when
|
||||
// those arguments require establishing a connection first, the actual handler is called by handleStatusChanged() when
|
||||
// the connection has been established
|
||||
m_connection.reconnect(m_settings);
|
||||
cerr << "Connecting to " << m_settings.syncthingUrl.toLocal8Bit().data() << " ...";
|
||||
|
@ -136,23 +139,26 @@ int Application::exec(int argc, const char *const *argv)
|
|||
m_args.parser.invokeCallbacks();
|
||||
}
|
||||
|
||||
// enter event loop
|
||||
// enter main event loop
|
||||
if (!m_requiresMainEventLoop) {
|
||||
return 0;
|
||||
}
|
||||
return QCoreApplication::exec();
|
||||
}
|
||||
|
||||
int assignIntegerFromArg(const Argument &arg, int &integer)
|
||||
{
|
||||
if (arg.isPresent()) {
|
||||
try {
|
||||
integer = stringToNumber<int>(arg.firstValue());
|
||||
if (integer < 0) {
|
||||
throw ConversionException();
|
||||
}
|
||||
} catch (const ConversionException &) {
|
||||
cerr << Phrases::Error << "The specified number of milliseconds \"" << arg.firstValue() << "\" is no unsigned integer." << Phrases::End
|
||||
<< flush;
|
||||
return -4;
|
||||
if (!arg.isPresent()) {
|
||||
return 0;
|
||||
}
|
||||
try {
|
||||
integer = stringToNumber<int>(arg.firstValue());
|
||||
if (integer < 0) {
|
||||
throw ConversionException();
|
||||
}
|
||||
} catch (const ConversionException &) {
|
||||
cerr << Phrases::Error << "The specified number of milliseconds \"" << arg.firstValue() << "\" is no unsigned integer." << Phrases::EndFlush;
|
||||
return -4;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -171,10 +177,10 @@ int Application::loadConfig()
|
|||
const char *apiKeyArgValue = m_args.apiKey.firstValue();
|
||||
if (!config.restore(configFile)) {
|
||||
if (configFileArgValue) {
|
||||
cerr << Phrases::Error << "Unable to locate specified Syncthing config file \"" << configFileArgValue << "\"" << Phrases::End << flush;
|
||||
cerr << Phrases::Error << "Unable to locate specified Syncthing config file \"" << configFileArgValue << "\"" << Phrases::EndFlush;
|
||||
return -1;
|
||||
} else if (!apiKeyArgValue) {
|
||||
cerr << Phrases::Error << "Unable to locate Syncthing config file and no API key specified" << Phrases::End << flush;
|
||||
cerr << Phrases::Error << "Unable to locate Syncthing config file and no API key specified" << Phrases::EndFlush;
|
||||
return -2;
|
||||
}
|
||||
}
|
||||
|
@ -583,6 +589,15 @@ void Application::printLog(const std::vector<SyncthingLogEntry> &logEntries)
|
|||
QCoreApplication::exit();
|
||||
}
|
||||
|
||||
void Application::printConfig(const ArgumentOccurrence &)
|
||||
{
|
||||
waitForConfig();
|
||||
eraseLine(cout);
|
||||
cout << '\r' << QJsonDocument(m_connection.rawConfig()).toJson().data() << flush;
|
||||
// disable main event loop since this method is invoked directly as argument callback and we've done all async operations during the waitForConfig() call already
|
||||
m_requiresMainEventLoop = false;
|
||||
}
|
||||
|
||||
void Application::waitForIdle(const ArgumentOccurrence &)
|
||||
{
|
||||
m_preventDisconnect = true;
|
||||
|
@ -733,7 +748,7 @@ void Application::initDirCompletion(Argument &arg, const ArgumentOccurrence &)
|
|||
}
|
||||
// load config and wait for connected
|
||||
loadConfig();
|
||||
waitForConfig(2000);
|
||||
waitForConfig();
|
||||
// set directory IDs as completion values
|
||||
m_dirCompletion = m_connection.directoryIds().join(QChar(' ')).toUtf8();
|
||||
arg.setPreDefinedCompletionValues(m_dirCompletion.data());
|
||||
|
@ -747,7 +762,7 @@ void Application::initDevCompletion(Argument &arg, const ArgumentOccurrence &)
|
|||
}
|
||||
// load config and wait for connected
|
||||
loadConfig();
|
||||
waitForConfig(2000);
|
||||
waitForConfig();
|
||||
// set device IDs and names as completion values
|
||||
QStringList completionValues;
|
||||
const size_t valueCount = m_connection.devInfo().size() << 2;
|
||||
|
|
|
@ -53,8 +53,8 @@ private slots:
|
|||
|
||||
private:
|
||||
int loadConfig();
|
||||
bool waitForConnected(int timeout);
|
||||
bool waitForConfig(int timeout);
|
||||
bool waitForConnected(int timeout = 2000);
|
||||
bool waitForConfig(int timeout = 2000);
|
||||
void requestLog(const ArgumentOccurrence &);
|
||||
void requestShutdown(const ArgumentOccurrence &);
|
||||
void requestRestart(const ArgumentOccurrence &);
|
||||
|
@ -65,6 +65,7 @@ private:
|
|||
void printDev(const Data::SyncthingDev *dev) const;
|
||||
void printStatus(const ArgumentOccurrence &);
|
||||
static void printLog(const std::vector<Data::SyncthingLogEntry> &logEntries);
|
||||
void printConfig(const ArgumentOccurrence &);
|
||||
void waitForIdle(const ArgumentOccurrence &);
|
||||
bool checkWhetherIdle() const;
|
||||
void checkPwdOperationPresent(const ArgumentOccurrence &occurrence);
|
||||
|
@ -82,6 +83,7 @@ private:
|
|||
size_t m_expectedResponse;
|
||||
bool m_preventDisconnect;
|
||||
bool m_callbacksInvoked;
|
||||
bool m_requiresMainEventLoop;
|
||||
std::vector<RelevantDir> m_relevantDirs;
|
||||
std::vector<const Data::SyncthingDev *> m_relevantDevs;
|
||||
RelevantDir m_pwd;
|
||||
|
|
|
@ -16,6 +16,7 @@ Args::Args()
|
|||
, resume("resume", '\0', "resumes the specified directories and devices")
|
||||
, waitForIdle("wait-for-idle", 'w', "waits until the specified dirs/devs are idling")
|
||||
, pwd("pwd", 'p', "operates in the current working directory")
|
||||
, cat("cat", '\0', "prints the current configuration")
|
||||
, statusPwd("status", 's', "prints the status of the current working directory")
|
||||
, rescanPwd("rescan", 'r', "rescans the current working directory")
|
||||
, pausePwd("pause", 'p', "pauses the current working directory")
|
||||
|
@ -58,8 +59,8 @@ Args::Args()
|
|||
configFile.setExample(PROJECT_NAME " status --dir dir1 --config-file ~/.config/syncthing/config.xml");
|
||||
credentials.setExample(PROJECT_NAME " status --dir dir1 --credentials name supersecret");
|
||||
|
||||
parser.setMainArguments({ &status, &log, &stop, &restart, &rescan, &rescanAll, &pause, &resume, &waitForIdle, &pwd, &configFile, &apiKey, &url,
|
||||
&credentials, &certificate, &noColor, &help });
|
||||
parser.setMainArguments({ &status, &log, &stop, &restart, &rescan, &rescanAll, &pause, &resume, &waitForIdle, &pwd, &cat, &configFile, &apiKey,
|
||||
&url, &credentials, &certificate, &noColor, &help });
|
||||
|
||||
// allow setting default values via environment
|
||||
configFile.setEnvironmentVariable("SYNCTHING_CTL_CONFIG_FILE");
|
||||
|
|
|
@ -12,7 +12,7 @@ struct Args {
|
|||
ArgumentParser parser;
|
||||
HelpArgument help;
|
||||
NoColorArgument noColor;
|
||||
OperationArgument status, log, stop, restart, rescan, rescanAll, pause, resume, waitForIdle, pwd;
|
||||
OperationArgument status, log, stop, restart, rescan, rescanAll, pause, resume, waitForIdle, pwd, cat;
|
||||
OperationArgument statusPwd, rescanPwd, pausePwd, resumePwd;
|
||||
ConfigValueArgument dir, dev, allDirs, allDevs;
|
||||
ConfigValueArgument atLeast, timeout;
|
||||
|
|
|
@ -129,6 +129,7 @@ public:
|
|||
QStringList deviceIds() const;
|
||||
QString deviceNameOrId(const QString &deviceId) const;
|
||||
std::size_t connectedDevices() const;
|
||||
const QJsonObject &rawConfig() const;
|
||||
|
||||
public Q_SLOTS:
|
||||
bool loadSelfSignedCertificate();
|
||||
|
@ -560,6 +561,15 @@ inline const QList<QSslError> &SyncthingConnection::expectedSslErrors()
|
|||
{
|
||||
return m_expectedSslErrors;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Returns the raw Syncthing configuration.
|
||||
* \remarks The referenced object is updated when newConfig() is emitted.
|
||||
*/
|
||||
inline const QJsonObject &SyncthingConnection::rawConfig() const
|
||||
{
|
||||
return m_rawConfig;
|
||||
}
|
||||
} // namespace Data
|
||||
|
||||
Q_DECLARE_METATYPE(Data::SyncthingLogEntry)
|
||||
|
|
|
@ -315,7 +315,7 @@ template <typename Action, typename... SignalInfos> bool waitForSignals(Action a
|
|||
/*!
|
||||
* \brief Waits until the specified signals have been emitted when performing async operations triggered by \a action. Aborts when \a failure is emitted.
|
||||
* \arg action Specifies a method to trigger the action to run when waiting.
|
||||
* \arg timeout Specifies the max. time to wait. Set to zero to wait forever.
|
||||
* \arg timeout Specifies the max. time to wait in ms. Set to zero to wait forever.
|
||||
* \arg failure Specifies the signal indicating an error occured.
|
||||
* \arg signalInfos Specifies the signals to wait for.
|
||||
* \throws Fails if not all signals have been emitted in at least \a timeout milliseconds or when at least one of the
|
||||
|
|
Loading…
Reference in New Issue