cli: Use nested operations for pwd

This commit is contained in:
Martchus 2017-04-06 00:08:24 +02:00
parent 40b8713ba6
commit 0278f05023
5 changed files with 99 additions and 60 deletions

View File

@ -20,7 +20,7 @@ set(SRC_FILES
)
# find c++utilities
find_package(c++utilities 4.1.0 REQUIRED)
find_package(c++utilities 4.7.0 REQUIRED)
use_cpp_utilities()
# find qtutilities

View File

@ -69,7 +69,11 @@ Application::Application() :
m_args.resumeAllDevs.setCallback(bind(&Application::requestResumeAllDevs, this, _1));
m_args.resumeAllDirs.setCallback(bind(&Application::requestResumeAllDirs, this, _1));
m_args.waitForIdle.setCallback(bind(&Application::initWaitForIdle, this, _1));
m_args.pwd.setCallback(bind(&Application::operateOnPwd, 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));
// connect signals and slots
connect(&m_connection, &SyncthingConnection::statusChanged, this, &Application::handleStatusChanged);
@ -382,6 +386,24 @@ void Application::findRelevantDirsAndDevs(OperationType operationType)
}
}
bool Application::findPwd()
{
const QString pwd(QDir::currentPath());
for(const SyncthingDir &dir : m_connection.dirInfo()) {
if(pwd == dir.pathWithoutTrailingSlash()) {
m_pwd = &dir;
return true;
} else if(pwd.startsWith(dir.path)) {
m_pwd = &dir;
m_relativePath = pwd.mid(dir.path.size());
return true;
}
}
cerr << "Error: The current working directory \"" << pwd.toLocal8Bit().data() << "\" is not (part of) a Syncthing directory." << endl;
QCoreApplication::exit(2);
return false;
}
void Application::printDir(const SyncthingDir *dir)
{
cout << " - ";
@ -515,67 +537,73 @@ void Application::waitForIdle()
QCoreApplication::exit();
}
void Application::operateOnPwd(const ArgumentOccurrence &occurrence)
void Application::checkPwdOperationPresent(const ArgumentOccurrence &occurrence)
{
// find SyncthingDir for pwd
const QString pwd(QDir::currentPath());
const SyncthingDir *relatedDir = nullptr;
QString relativePath;
for(const SyncthingDir &dir : m_connection.dirInfo()) {
if(pwd == dir.pathWithoutTrailingSlash()) {
relatedDir = &dir;
} else if(pwd.startsWith(dir.path)) {
relatedDir = &dir;
relativePath = pwd.mid(dir.path.size());
}
}
if(!relatedDir) {
cerr << "Error: The current working directory \"" << pwd.toLocal8Bit().data() << "\" is not (part of) a Syncthing directory." << endl;
QCoreApplication::exit(2);
return;
}
// do specified operation
const char *operation = occurrence.values.front();
if(!strcmp(operation, "status")) {
printDir(relatedDir);
} else if(!strcmp(operation, "rescan")) {
if(relativePath.isEmpty()) {
cerr << "Request rescanning directory \"" << relatedDir->path.toLocal8Bit().data() << "\" ..." << endl;
} else {
cerr << "Request rescanning item \"" << relativePath.toLocal8Bit().data() << "\" in directory \"" << relatedDir->path.toLocal8Bit().data() << "\" ..." << endl;
}
m_connection.rescan(relatedDir->id, relativePath);
connect(&m_connection, &SyncthingConnection::rescanTriggered, this, &Application::handleResponse);
m_expectedResponse = 1;
return;
} else if(!strcmp(operation, "pause")) {
if(m_connection.pauseDirectories(QStringList(relatedDir->id))) {
cerr << "Request pausing directory \"" << relatedDir->path.toLocal8Bit().data() << "\" ..." << endl;
connect(&m_connection, &SyncthingConnection::directoryPauseTriggered, this, &Application::handleResponse);
m_preventDisconnect = true;
m_expectedResponse = 1;
// FIXME: implement requiring at least one operation and default operation in argument parser
for(const Argument *pwdOperationArg : m_args.pwd.subArguments()) {
if(pwdOperationArg->denotesOperation() && pwdOperationArg->isPresent()) {
return;
} else {
cerr << "Directory \"" << relatedDir->path.toLocal8Bit().data() << " already paused" << endl;
}
} else if(!strcmp(operation, "resume")) {
if(m_connection.resumeDirectories(QStringList(relatedDir->id))) {
cerr << "Request resuming directory \"" << relatedDir->path.toLocal8Bit().data() << "\" ..." << endl;
connect(&m_connection, &SyncthingConnection::directoryResumeTriggered, this, &Application::handleResponse);
m_preventDisconnect = true;
m_expectedResponse = 1;
return;
} else {
cerr << "Directory \"" << relatedDir->path.toLocal8Bit().data() << " not paused" << endl;
}
} else {
cerr << "Error: The specified operation \"" << operation << "\" is invalid." << endl;
QCoreApplication::exit(1);
}
// print status when no operation specified
printPwdStatus(occurrence);
}
void Application::printPwdStatus(const ArgumentOccurrence &)
{
if(!findPwd()) {
return;
}
printDir(m_pwd);
QCoreApplication::quit();
}
void Application::requestRescanPwd(const ArgumentOccurrence &)
{
if(!findPwd()) {
return;
}
if(m_relativePath.isEmpty()) {
cerr << "Request rescanning directory \"" << m_pwd->path.toLocal8Bit().data() << "\" ..." << endl;
} else {
cerr << "Request rescanning item \"" << m_relativePath.toLocal8Bit().data() << "\" in directory \"" << m_pwd->path.toLocal8Bit().data() << "\" ..." << endl;
}
m_connection.rescan(m_pwd->id, m_relativePath);
connect(&m_connection, &SyncthingConnection::rescanTriggered, this, &Application::handleResponse);
m_expectedResponse = 1;
}
void Application::requestPausePwd(const ArgumentOccurrence &)
{
if(!findPwd()) {
return;
}
if(m_connection.pauseDirectories(QStringList(m_pwd->id))) {
cerr << "Request pausing directory \"" << m_pwd->path.toLocal8Bit().data() << "\" ..." << endl;
connect(&m_connection, &SyncthingConnection::directoryPauseTriggered, this, &Application::handleResponse);
m_preventDisconnect = true;
m_expectedResponse = 1;
} else {
cerr << "Directory \"" << m_pwd->path.toLocal8Bit().data() << " already paused" << endl;
QCoreApplication::quit();
}
}
void Application::requestResumePwd(const ArgumentOccurrence &)
{
if(!findPwd()) {
return;
}
if(m_connection.resumeDirectories(QStringList(m_pwd->id))) {
cerr << "Request resuming directory \"" << m_pwd->path.toLocal8Bit().data() << "\" ..." << endl;
connect(&m_connection, &SyncthingConnection::directoryResumeTriggered, this, &Application::handleResponse);
m_preventDisconnect = true;
m_expectedResponse = 1;
return;
} else {
cerr << "Directory \"" << m_pwd->path.toLocal8Bit().data() << " not paused" << endl;
QCoreApplication::quit();
}
}
} // namespace Cli

View File

@ -34,6 +34,7 @@ private slots:
void handleError(const QString &message);
void findRelevantDirsAndDevs();
void findRelevantDirsAndDevs(OperationType operationType);
bool findPwd();
private:
void requestLog(const ArgumentOccurrence &);
@ -52,7 +53,11 @@ private:
static void printLog(const std::vector<Data::SyncthingLogEntry> &logEntries);
void initWaitForIdle(const ArgumentOccurrence &);
void waitForIdle();
void operateOnPwd(const ArgumentOccurrence &occurrence);
void checkPwdOperationPresent(const ArgumentOccurrence &occurrence);
void printPwdStatus(const ArgumentOccurrence &occurrence);
void requestRescanPwd(const ArgumentOccurrence &occurrence);
void requestPausePwd(const ArgumentOccurrence &occurrence);
void requestResumePwd(const ArgumentOccurrence &occurrence);
Args m_args;
Data::SyncthingConnectionSettings m_settings;
@ -62,6 +67,8 @@ private:
bool m_callbacksInvoked;
std::vector<const Data::SyncthingDir *> m_relevantDirs;
std::vector<const Data::SyncthingDev *> m_relevantDevs;
const Data::SyncthingDir *m_pwd;
QString m_relativePath;
};

View File

@ -18,6 +18,10 @@ Args::Args() :
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 directoies (default is all dirs)", {"ID"}),
statusDev("dev", '\0', "specifies the devices (default is all devs)", {"ID"}),
pauseDir("dir", 'd', "specifies the directories", {"ID"}),
@ -33,8 +37,7 @@ Args::Args() :
}
status.setSubArguments({&statusDir, &statusDev});
waitForIdle.setSubArguments({&statusDir, &statusDev});
pwd.setValueNames({"status/rescan/pause/resume"});
pwd.setRequiredValueCount(1);
pwd.setSubArguments({&statusPwd, &rescanPwd, &pausePwd, &resumePwd});
rescan.setValueNames({"dir ID"});
rescan.setRequiredValueCount(-1);

View File

@ -13,6 +13,7 @@ struct Args
ArgumentParser parser;
HelpArgument help;
OperationArgument status, log, stop, restart, rescan, rescanAll, pause, pauseAllDevs, pauseAllDirs, resume, resumeAllDevs, resumeAllDirs, waitForIdle, pwd;
OperationArgument statusPwd, rescanPwd, pausePwd, resumePwd;
ConfigValueArgument statusDir, statusDev, pauseDir, pauseDev;
ConfigValueArgument configFile, apiKey, url, credentials, certificate;
};