Simplify CLI code
This commit is contained in:
parent
447928a018
commit
45b242b91a
|
@ -74,20 +74,14 @@ Application::Application()
|
|||
m_args.rescanAll.setCallback(bind(&Application::requestRescanAll, this, _1));
|
||||
m_args.pause.setCallback(bind(&Application::requestPauseResume, this, true));
|
||||
m_args.resume.setCallback(bind(&Application::requestPauseResume, this, false));
|
||||
m_args.pauseAllDevs.setCallback(bind(&Application::requestPauseAllDevs, this, _1));
|
||||
m_args.pauseAllDirs.setCallback(bind(&Application::requestPauseAllDirs, this, _1));
|
||||
m_args.resumeAllDevs.setCallback(bind(&Application::requestResumeAllDevs, this, _1));
|
||||
m_args.resumeAllDirs.setCallback(bind(&Application::requestResumeAllDirs, this, _1));
|
||||
m_args.waitForIdle.setCallback(bind(&Application::waitForIdle, this, _1));
|
||||
m_args.pwd.setCallback(bind(&Application::checkPwdOperationPresent, 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));
|
||||
m_args.resumePwd.setCallback(bind(&Application::requestResumePwd, this, _1));
|
||||
m_args.pauseDir.setCallback(bind(&Application::initDirCompletion, this, ref(m_args.pauseDir), _1));
|
||||
m_args.statusDir.setCallback(bind(&Application::initDirCompletion, this, ref(m_args.statusDir), _1));
|
||||
m_args.pauseDev.setCallback(bind(&Application::initDevCompletion, this, ref(m_args.pauseDev), _1));
|
||||
m_args.statusDev.setCallback(bind(&Application::initDevCompletion, this, ref(m_args.statusDev), _1));
|
||||
m_args.dir.setCallback(bind(&Application::initDirCompletion, this, ref(m_args.dir), _1));
|
||||
m_args.dev.setCallback(bind(&Application::initDevCompletion, this, ref(m_args.dev), _1));
|
||||
|
||||
// connect signals and slots
|
||||
connect(&m_connection, &SyncthingConnection::statusChanged, this, &Application::handleStatusChanged);
|
||||
|
@ -129,8 +123,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.pauseAllDirs.isPresent()
|
||||
|| m_args.pauseAllDevs.isPresent() || m_args.resumeAllDirs.isPresent() || m_args.resumeAllDevs.isPresent() || m_args.pause.isPresent()
|
||||
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
|
||||
// the connection has been established
|
||||
|
@ -406,102 +399,59 @@ void Application::requestPauseResume(bool pause)
|
|||
cerr << flush;
|
||||
}
|
||||
|
||||
void Application::requestPauseAllDevs(const ArgumentOccurrence &)
|
||||
{
|
||||
findRelevantDirsAndDevs(OperationType::PauseResume);
|
||||
connect(&m_connection, &SyncthingConnection::devicePauseTriggered, this, &Application::handleResponse);
|
||||
if (!m_connection.pauseAllDevs()) {
|
||||
cerr << Phrases::Warning << "No devices to be paused." << Phrases::End << flush;
|
||||
exit(0);
|
||||
}
|
||||
cerr << "Request pausing all devices ..." << endl;
|
||||
m_expectedResponse = 1;
|
||||
}
|
||||
|
||||
void Application::requestPauseAllDirs(const ArgumentOccurrence &)
|
||||
{
|
||||
connect(&m_connection, &SyncthingConnection::directoryPauseTriggered, this, &Application::handleResponse);
|
||||
if (!m_connection.pauseAllDirs()) {
|
||||
cerr << Phrases::Warning << "No directories to be paused." << Phrases::End << flush;
|
||||
exit(0);
|
||||
}
|
||||
cerr << "Request pausing all directories ..." << endl;
|
||||
m_expectedResponse = 1;
|
||||
}
|
||||
|
||||
void Application::requestResumeAllDevs(const ArgumentOccurrence &)
|
||||
{
|
||||
connect(&m_connection, &SyncthingConnection::deviceResumeTriggered, this, &Application::handleResponse);
|
||||
if (!m_connection.resumeAllDevs()) {
|
||||
cerr << Phrases::Warning << "No devices to be resumed." << Phrases::End << flush;
|
||||
exit(0);
|
||||
}
|
||||
cerr << "Request resuming all devices ..." << endl;
|
||||
m_expectedResponse = 1;
|
||||
}
|
||||
|
||||
void Application::requestResumeAllDirs(const ArgumentOccurrence &)
|
||||
{
|
||||
connect(&m_connection, &SyncthingConnection::deviceResumeTriggered, this, &Application::handleResponse);
|
||||
if (!m_connection.resumeAllDirs()) {
|
||||
cerr << Phrases::Warning << "No directories to be resumed." << Phrases::End << flush;
|
||||
exit(0);
|
||||
}
|
||||
cerr << "Request resuming all directories ..." << endl;
|
||||
m_expectedResponse = 1;
|
||||
}
|
||||
|
||||
void Application::findRelevantDirsAndDevs(OperationType operationType)
|
||||
{
|
||||
int dummy;
|
||||
|
||||
Argument *dirArg, *devArg;
|
||||
switch (operationType) {
|
||||
case OperationType::Status:
|
||||
dirArg = &m_args.statusDir;
|
||||
devArg = &m_args.statusDev;
|
||||
break;
|
||||
case OperationType::PauseResume:
|
||||
dirArg = &m_args.pauseDir;
|
||||
devArg = &m_args.pauseDev;
|
||||
// find relevant dirs
|
||||
const bool allDirs = m_args.allDirs.isPresent();
|
||||
if (!allDirs) {
|
||||
const Argument &dirArg = m_args.dir;
|
||||
if (dirArg.isPresent()) {
|
||||
m_relevantDirs.reserve(dirArg.occurrences());
|
||||
for (size_t i = 0; i != dirArg.occurrences(); ++i) {
|
||||
const QString dirIdentifier(argToQString(dirArg.values(i).front()));
|
||||
const RelevantDir relevantDir(findDirectory(dirIdentifier));
|
||||
if (relevantDir.dirObj) {
|
||||
m_relevantDirs.emplace_back(move(relevantDir));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dirArg->isPresent()) {
|
||||
m_relevantDirs.reserve(dirArg->occurrences());
|
||||
for (size_t i = 0; i != dirArg->occurrences(); ++i) {
|
||||
const QString dirIdentifier(argToQString(dirArg->values(i).front()));
|
||||
const RelevantDir relevantDir(findDirectory(dirIdentifier));
|
||||
if (relevantDir.dirObj) {
|
||||
m_relevantDirs.emplace_back(move(relevantDir));
|
||||
// find relevant devs
|
||||
const bool allDevs = m_args.allDevs.isPresent();
|
||||
if (!allDevs) {
|
||||
Argument &devArg = m_args.dev;
|
||||
if (devArg.isPresent()) {
|
||||
m_relevantDevs.reserve(devArg.occurrences());
|
||||
for (size_t i = 0; i != devArg.occurrences(); ++i) {
|
||||
const SyncthingDev *dev = m_connection.findDevInfo(argToQString(devArg.values(i).front()), dummy);
|
||||
if (!dev) {
|
||||
dev = m_connection.findDevInfoByName(argToQString(devArg.values(i).front()), dummy);
|
||||
}
|
||||
if (dev) {
|
||||
m_relevantDevs.emplace_back(dev);
|
||||
} else {
|
||||
cerr << Phrases::Warning << "Specified device \"" << devArg.values(i).front() << "\" does not exist and will be ignored."
|
||||
<< Phrases::End;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (devArg->isPresent()) {
|
||||
m_relevantDevs.reserve(devArg->occurrences());
|
||||
for (size_t i = 0; i != devArg->occurrences(); ++i) {
|
||||
const SyncthingDev *dev = m_connection.findDevInfo(argToQString(devArg->values(i).front()), dummy);
|
||||
if (!dev) {
|
||||
dev = m_connection.findDevInfoByName(argToQString(devArg->values(i).front()), dummy);
|
||||
}
|
||||
if (dev) {
|
||||
m_relevantDevs.emplace_back(dev);
|
||||
} else {
|
||||
cerr << Phrases::Warning << "Specified device \"" << devArg->values(i).front() << "\" does not exist and will be ignored."
|
||||
<< Phrases::End;
|
||||
}
|
||||
|
||||
// when displaying status information and no dirs/devs have been specified, just print information for all
|
||||
const bool displayEverything = operationType == OperationType::Status && m_relevantDirs.empty() && m_relevantDevs.empty();
|
||||
if (allDirs || (!allDevs && displayEverything)) {
|
||||
m_relevantDirs.reserve(m_connection.dirInfo().size());
|
||||
for (const SyncthingDir &dir : m_connection.dirInfo()) {
|
||||
m_relevantDirs.emplace_back(&dir, QString());
|
||||
}
|
||||
}
|
||||
if (operationType == OperationType::Status) {
|
||||
// when displaying status information and no dirs/devs have been specified, just print information for all
|
||||
if (m_relevantDirs.empty() && m_relevantDevs.empty()) {
|
||||
m_relevantDirs.reserve(m_connection.dirInfo().size());
|
||||
for (const SyncthingDir &dir : m_connection.dirInfo()) {
|
||||
m_relevantDirs.emplace_back(&dir, QString());
|
||||
}
|
||||
m_relevantDevs.reserve(m_connection.devInfo().size());
|
||||
for (const SyncthingDev &dev : m_connection.devInfo()) {
|
||||
m_relevantDevs.emplace_back(&dev);
|
||||
}
|
||||
if (allDevs || (!allDirs && displayEverything)) {
|
||||
m_relevantDevs.reserve(m_connection.devInfo().size());
|
||||
for (const SyncthingDev &dev : m_connection.devInfo()) {
|
||||
m_relevantDevs.emplace_back(&dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -61,10 +61,6 @@ private:
|
|||
void requestRescan(const ArgumentOccurrence &occurrence);
|
||||
void requestRescanAll(const ArgumentOccurrence &);
|
||||
void requestPauseResume(bool pause);
|
||||
void requestPauseAllDevs(const ArgumentOccurrence &);
|
||||
void requestPauseAllDirs(const ArgumentOccurrence &);
|
||||
void requestResumeAllDevs(const ArgumentOccurrence &);
|
||||
void requestResumeAllDirs(const ArgumentOccurrence &);
|
||||
static void printDir(const RelevantDir &relevantDir);
|
||||
static void printDev(const Data::SyncthingDev *dev);
|
||||
void printStatus(const ArgumentOccurrence &);
|
||||
|
|
42
cli/args.cpp
42
cli/args.cpp
|
@ -13,21 +13,17 @@ Args::Args()
|
|||
, rescan("rescan", 'r', "rescans the specified directories")
|
||||
, rescanAll("rescan-all", '\0', "rescans all directories")
|
||||
, pause("pause", '\0', "pauses the specified devices")
|
||||
, pauseAllDevs("pause-all-devs", '\0', "pauses all devices")
|
||||
, pauseAllDirs("pause-all-dirs", '\0', "pauses all directories")
|
||||
, resume("resume", '\0', "resumes the specified devices")
|
||||
, resumeAllDevs("resume-all-devs", '\0', "resumes all devices")
|
||||
, resumeAllDirs("resume-all-dirs", '\0', "resumes all directories")
|
||||
, waitForIdle("wait-for-idle", 'w', "waits until the specified dirs/devs are idling")
|
||||
, pwd("pwd", 'p', "operates in the current working directory")
|
||||
, 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")
|
||||
, resumePwd("resume", '\0', "resumes the current working directory")
|
||||
, statusDir("dir", 'd', "specifies the directories, default is all dirs", { "ID" })
|
||||
, statusDev("dev", '\0', "specifies the devices, default is all devs", { "ID" })
|
||||
, pauseDir("dir", 'd', "specifies the directories", { "ID" })
|
||||
, pauseDev("dev", '\0', "specifies the devices", { "ID" })
|
||||
, dir("dir", 'd', "specifies a directory", { "ID" })
|
||||
, dev("dev", '\0', "specifies a device", { "ID" })
|
||||
, allDirs("all-dirs", '\0', "apply operation for all directories")
|
||||
, allDevs("all-devs", '\0', "apply operation for all devices")
|
||||
, atLeast("at-least", 'a', "specifies for how many milliseconds Syncthing must idle (prevents exiting to early in case of flaky status)",
|
||||
{ "number" })
|
||||
, timeout("timeout", 't', "specifies how many milliseconds to wait at most", { "number" })
|
||||
|
@ -37,18 +33,14 @@ Args::Args()
|
|||
, credentials("credentials", 'c', "specifies user name and password", { "user name", "password" })
|
||||
, certificate("cert", '\0', "specifies the certificate used by the Syncthing instance", { "path" })
|
||||
{
|
||||
for (Argument *arg : { &statusDir, &pauseDir }) {
|
||||
arg->setConstraints(0, Argument::varValueCount);
|
||||
arg->setValueCompletionBehavior(
|
||||
ValueCompletionBehavior::PreDefinedValues | ValueCompletionBehavior::Directories | ValueCompletionBehavior::InvokeCallback);
|
||||
}
|
||||
for (Argument *arg : { &statusDev, &pauseDev }) {
|
||||
arg->setConstraints(0, Argument::varValueCount);
|
||||
arg->setValueCompletionBehavior(ValueCompletionBehavior::PreDefinedValues | ValueCompletionBehavior::InvokeCallback);
|
||||
}
|
||||
status.setSubArguments({ &statusDir, &statusDev });
|
||||
dir.setConstraints(0, Argument::varValueCount);
|
||||
dir.setValueCompletionBehavior(
|
||||
ValueCompletionBehavior::PreDefinedValues | ValueCompletionBehavior::Directories | ValueCompletionBehavior::InvokeCallback);
|
||||
dev.setConstraints(0, Argument::varValueCount);
|
||||
dev.setValueCompletionBehavior(ValueCompletionBehavior::PreDefinedValues | ValueCompletionBehavior::InvokeCallback);
|
||||
status.setSubArguments({ &dir, &dev, &allDirs, &allDevs });
|
||||
status.setExample(PROJECT_NAME " status # shows all dirs and devs\n" PROJECT_NAME " status --dir dir1 --dir dir2 --dev dev1 --dev dev2");
|
||||
waitForIdle.setSubArguments({ &statusDir, &statusDev, &atLeast, &timeout });
|
||||
waitForIdle.setSubArguments({ &dir, &dev, &atLeast, &timeout });
|
||||
waitForIdle.setExample(PROJECT_NAME " wait-for-idle --timeout 1800000 --at-least 5000 && systemctl poweroff\n" PROJECT_NAME
|
||||
" wait-for-idle --dir dir1 --dir dir2 --dev dev1 --dev dev2 --at-least 5000");
|
||||
pwd.setSubArguments({ &statusPwd, &rescanPwd, &pausePwd, &resumePwd });
|
||||
|
@ -58,16 +50,16 @@ Args::Args()
|
|||
rescan.setValueCompletionBehavior(
|
||||
ValueCompletionBehavior::PreDefinedValues | ValueCompletionBehavior::Directories | ValueCompletionBehavior::InvokeCallback);
|
||||
rescan.setExample(PROJECT_NAME " rescan dir1 dir2 dir4 dir5");
|
||||
pause.setSubArguments({ &pauseDir, &pauseDev });
|
||||
pause.setExample(PROJECT_NAME " pause --dir dir1 --dir dir2 --dev dev1 --dev dev2");
|
||||
resume.setSubArguments({ &pauseDir, &pauseDev });
|
||||
resume.setExample(PROJECT_NAME " resume --dir dir1 --dir dir2 --dev dev1 --dev dev2");
|
||||
pause.setSubArguments({ &dir, &dev, &allDirs, &allDevs });
|
||||
pause.setExample(PROJECT_NAME " pause --dir dir1 --dir dir2 --dev dev1 --dev dev2\n" PROJECT_NAME " pause --all-dirs");
|
||||
resume.setSubArguments({ &dir, &dev, &allDirs, &allDevs });
|
||||
resume.setExample(PROJECT_NAME " resume --dir dir1 --dir dir2 --dev dev1 --dev dev2\n" PROJECT_NAME " resume --all-devs");
|
||||
|
||||
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, &pauseAllDevs, &pauseAllDirs, &resume, &resumeAllDevs,
|
||||
&resumeAllDirs, &waitForIdle, &pwd, &configFile, &apiKey, &url, &credentials, &certificate, &noColor, &help });
|
||||
parser.setMainArguments({ &status, &log, &stop, &restart, &rescan, &rescanAll, &pause, &resume, &waitForIdle, &pwd, &configFile, &apiKey, &url,
|
||||
&credentials, &certificate, &noColor, &help });
|
||||
|
||||
// allow setting default values via environment
|
||||
configFile.setEnvironmentVariable("SYNCTHING_CTL_CONFIG_FILE");
|
||||
|
|
|
@ -12,10 +12,9 @@ struct Args {
|
|||
ArgumentParser parser;
|
||||
HelpArgument help;
|
||||
NoColorArgument noColor;
|
||||
OperationArgument status, log, stop, restart, rescan, rescanAll, pause, pauseAllDevs, pauseAllDirs, resume, resumeAllDevs, resumeAllDirs,
|
||||
waitForIdle, pwd;
|
||||
OperationArgument status, log, stop, restart, rescan, rescanAll, pause, resume, waitForIdle, pwd;
|
||||
OperationArgument statusPwd, rescanPwd, pausePwd, resumePwd;
|
||||
ConfigValueArgument statusDir, statusDev, pauseDir, pauseDev;
|
||||
ConfigValueArgument dir, dev, allDirs, allDevs;
|
||||
ConfigValueArgument atLeast, timeout;
|
||||
ConfigValueArgument configFile, apiKey, url, credentials, certificate;
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue