cli: Show directory and device names in shell completion
This commit is contained in:
parent
30347f1845
commit
3e9e933411
|
@ -51,6 +51,7 @@ Application::Application()
|
||||||
: m_expectedResponse(0)
|
: m_expectedResponse(0)
|
||||||
, m_preventDisconnect(false)
|
, m_preventDisconnect(false)
|
||||||
, m_callbacksInvoked(false)
|
, m_callbacksInvoked(false)
|
||||||
|
, m_argsRead(false)
|
||||||
{
|
{
|
||||||
// take ownership over the global QNetworkAccessManager
|
// take ownership over the global QNetworkAccessManager
|
||||||
networkAccessManager().setParent(this);
|
networkAccessManager().setParent(this);
|
||||||
|
@ -75,6 +76,10 @@ Application::Application()
|
||||||
m_args.rescanPwd.setCallback(bind(&Application::requestRescanPwd, this, _1));
|
m_args.rescanPwd.setCallback(bind(&Application::requestRescanPwd, this, _1));
|
||||||
m_args.pausePwd.setCallback(bind(&Application::requestPausePwd, this, _1));
|
m_args.pausePwd.setCallback(bind(&Application::requestPausePwd, this, _1));
|
||||||
m_args.resumePwd.setCallback(bind(&Application::requestResumePwd, 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));
|
||||||
|
|
||||||
// connect signals and slots
|
// connect signals and slots
|
||||||
connect(&m_connection, &SyncthingConnection::statusChanged, this, &Application::handleStatusChanged);
|
connect(&m_connection, &SyncthingConnection::statusChanged, this, &Application::handleStatusChanged);
|
||||||
|
@ -97,6 +102,12 @@ int Application::exec(int argc, const char *const *argv)
|
||||||
}
|
}
|
||||||
|
|
||||||
m_args.parser.checkConstraints();
|
m_args.parser.checkConstraints();
|
||||||
|
m_argsRead = true;
|
||||||
|
|
||||||
|
} catch (const Failure &failure) {
|
||||||
|
cerr << failure;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
// handle help argument
|
// handle help argument
|
||||||
if (m_args.help.isPresent()) {
|
if (m_args.help.isPresent()) {
|
||||||
|
@ -104,6 +115,34 @@ int Application::exec(int argc, const char *const *argv)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// load configuration
|
||||||
|
if (const int res = loadConfig()) {
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
// finally do the request or establish connection
|
||||||
|
if (m_args.status.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() || 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
|
||||||
|
m_connection.reconnect(m_settings);
|
||||||
|
cerr << "Connecting to " << m_settings.syncthingUrl.toLocal8Bit().data() << " ...";
|
||||||
|
cerr.flush();
|
||||||
|
} else {
|
||||||
|
// call handler for any other arguments directly
|
||||||
|
m_connection.applySettings(m_settings);
|
||||||
|
m_args.parser.invokeCallbacks();
|
||||||
|
}
|
||||||
|
|
||||||
|
// enter event loop
|
||||||
|
return QCoreApplication::exec();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int Application::loadConfig()
|
||||||
|
{
|
||||||
// locate and read Syncthing config file
|
// locate and read Syncthing config file
|
||||||
QString configFile;
|
QString configFile;
|
||||||
const char *configFileArgValue = m_args.configFile.firstValue();
|
const char *configFileArgValue = m_args.configFile.firstValue();
|
||||||
|
@ -116,8 +155,7 @@ int Application::exec(int argc, const char *const *argv)
|
||||||
const char *apiKeyArgValue = m_args.apiKey.firstValue();
|
const char *apiKeyArgValue = m_args.apiKey.firstValue();
|
||||||
if (!config.restore(configFile)) {
|
if (!config.restore(configFile)) {
|
||||||
if (configFileArgValue) {
|
if (configFileArgValue) {
|
||||||
cerr << Phrases::Error << "Unable to locate specified Syncthing config file \"" << configFileArgValue << "\"" << Phrases::End
|
cerr << Phrases::Error << "Unable to locate specified Syncthing config file \"" << configFileArgValue << "\"" << Phrases::End << flush;
|
||||||
<< flush;
|
|
||||||
return -1;
|
return -1;
|
||||||
} else if (!apiKeyArgValue) {
|
} 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::End << flush;
|
||||||
|
@ -146,33 +184,13 @@ int Application::exec(int argc, const char *const *argv)
|
||||||
if (const char *certArgValue = m_args.certificate.firstValue()) {
|
if (const char *certArgValue = m_args.certificate.firstValue()) {
|
||||||
m_settings.httpsCertPath = argToQString(certArgValue);
|
m_settings.httpsCertPath = argToQString(certArgValue);
|
||||||
if (m_settings.httpsCertPath.isEmpty() || !m_settings.loadHttpsCert()) {
|
if (m_settings.httpsCertPath.isEmpty() || !m_settings.loadHttpsCert()) {
|
||||||
cerr << Phrases::Error << "Unable to load specified certificate \"" << m_args.certificate.firstValue() << '\"' << Phrases::End
|
cerr << Phrases::Error << "Unable to load specified certificate \"" << m_args.certificate.firstValue() << '\"' << Phrases::End << flush;
|
||||||
<< flush;
|
|
||||||
return -3;
|
return -3;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// finally do the request or establish connection
|
return 0;
|
||||||
if (m_args.status.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() || 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
|
|
||||||
m_connection.reconnect(m_settings);
|
|
||||||
cerr << "Connecting to " << m_settings.syncthingUrl.toLocal8Bit().data() << " ...";
|
|
||||||
cerr.flush();
|
|
||||||
} else {
|
|
||||||
// call handler for any other arguments directly
|
|
||||||
m_connection.applySettings(m_settings);
|
|
||||||
m_args.parser.invokeCallbacks();
|
|
||||||
}
|
|
||||||
|
|
||||||
// enter event loop
|
|
||||||
return QCoreApplication::exec();
|
|
||||||
|
|
||||||
} catch (const Failure &failure) {
|
|
||||||
cerr << failure;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,6 +272,11 @@ void Application::requestRestart(const ArgumentOccurrence &)
|
||||||
|
|
||||||
void Application::requestRescan(const ArgumentOccurrence &occurrence)
|
void Application::requestRescan(const ArgumentOccurrence &occurrence)
|
||||||
{
|
{
|
||||||
|
if (!m_argsRead) {
|
||||||
|
initDirCompletion(m_args.rescan, occurrence);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
m_expectedResponse = occurrence.values.size();
|
m_expectedResponse = occurrence.values.size();
|
||||||
if (!m_expectedResponse) {
|
if (!m_expectedResponse) {
|
||||||
cerr << Phrases::Error << "No directories specified." << Phrases::End << flush;
|
cerr << Phrases::Error << "No directories specified." << Phrases::End << flush;
|
||||||
|
@ -662,4 +685,31 @@ void Application::requestResumePwd(const ArgumentOccurrence &)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::initDirCompletion(Argument &arg, const ArgumentOccurrence &)
|
||||||
|
{
|
||||||
|
// load config and wait for connected
|
||||||
|
loadConfig();
|
||||||
|
waitForConnected(2000);
|
||||||
|
// set directory IDs as completion values
|
||||||
|
arg.setPreDefinedCompletionValues(m_connection.directoryIds().join(QChar(' ')).toUtf8().data());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::initDevCompletion(Argument &arg, const ArgumentOccurrence &)
|
||||||
|
{
|
||||||
|
// load config and wait for connected
|
||||||
|
loadConfig();
|
||||||
|
waitForConnected(2000);
|
||||||
|
// set device IDs and names as completion values
|
||||||
|
QStringList completionValues;
|
||||||
|
const size_t valueCount = m_connection.devInfo().size() << 2;
|
||||||
|
if (valueCount > numeric_limits<int>::max()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
completionValues.reserve(static_cast<int>(valueCount));
|
||||||
|
for (const SyncthingDev &dev : m_connection.devInfo()) {
|
||||||
|
completionValues << dev.id << dev.name;
|
||||||
|
}
|
||||||
|
arg.setPreDefinedCompletionValues(completionValues.join(QChar(' ')).toUtf8().data());
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Cli
|
} // namespace Cli
|
||||||
|
|
|
@ -33,6 +33,7 @@ private slots:
|
||||||
bool findPwd();
|
bool findPwd();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
int loadConfig();
|
||||||
void requestLog(const ArgumentOccurrence &);
|
void requestLog(const ArgumentOccurrence &);
|
||||||
void requestShutdown(const ArgumentOccurrence &);
|
void requestShutdown(const ArgumentOccurrence &);
|
||||||
void requestRestart(const ArgumentOccurrence &);
|
void requestRestart(const ArgumentOccurrence &);
|
||||||
|
@ -54,6 +55,8 @@ private:
|
||||||
void requestRescanPwd(const ArgumentOccurrence &occurrence);
|
void requestRescanPwd(const ArgumentOccurrence &occurrence);
|
||||||
void requestPausePwd(const ArgumentOccurrence &occurrence);
|
void requestPausePwd(const ArgumentOccurrence &occurrence);
|
||||||
void requestResumePwd(const ArgumentOccurrence &occurrence);
|
void requestResumePwd(const ArgumentOccurrence &occurrence);
|
||||||
|
void initDirCompletion(Argument &arg, const ArgumentOccurrence &);
|
||||||
|
void initDevCompletion(Argument &arg, const ArgumentOccurrence &);
|
||||||
|
|
||||||
Args m_args;
|
Args m_args;
|
||||||
Data::SyncthingConnectionSettings m_settings;
|
Data::SyncthingConnectionSettings m_settings;
|
||||||
|
@ -65,6 +68,7 @@ private:
|
||||||
std::vector<const Data::SyncthingDev *> m_relevantDevs;
|
std::vector<const Data::SyncthingDev *> m_relevantDevs;
|
||||||
const Data::SyncthingDir *m_pwd;
|
const Data::SyncthingDir *m_pwd;
|
||||||
QString m_relativePath;
|
QString m_relativePath;
|
||||||
|
bool m_argsRead;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Cli
|
} // namespace Cli
|
||||||
|
|
Loading…
Reference in New Issue