cli: Add shortcut for current working directory
syncthingctl pwd status/rescan/resume/pause
This commit is contained in:
parent
4d7c6b5a61
commit
1168e31f55
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
#include <QCoreApplication>
|
#include <QCoreApplication>
|
||||||
#include <QNetworkAccessManager>
|
#include <QNetworkAccessManager>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
@ -46,7 +47,9 @@ inline QString argToQString(const char *arg, int size = -1)
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::Application() :
|
Application::Application() :
|
||||||
m_expectedResponse(0)
|
m_expectedResponse(0),
|
||||||
|
m_preventDisconnect(false),
|
||||||
|
m_callbacksInvoked(false)
|
||||||
{
|
{
|
||||||
// take ownership over the global QNetworkAccessManager
|
// take ownership over the global QNetworkAccessManager
|
||||||
networkAccessManager().setParent(this);
|
networkAccessManager().setParent(this);
|
||||||
|
@ -66,6 +69,7 @@ Application::Application() :
|
||||||
m_args.resumeAllDevs.setCallback(bind(&Application::requestResumeAllDevs, this, _1));
|
m_args.resumeAllDevs.setCallback(bind(&Application::requestResumeAllDevs, this, _1));
|
||||||
m_args.resumeAllDirs.setCallback(bind(&Application::requestResumeAllDirs, this, _1));
|
m_args.resumeAllDirs.setCallback(bind(&Application::requestResumeAllDirs, this, _1));
|
||||||
m_args.waitForIdle.setCallback(bind(&Application::initWaitForIdle, this, _1));
|
m_args.waitForIdle.setCallback(bind(&Application::initWaitForIdle, this, _1));
|
||||||
|
m_args.pwd.setCallback(bind(&Application::operateOnPwd, this, _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);
|
||||||
|
@ -143,7 +147,7 @@ int Application::exec(int argc, const char * const *argv)
|
||||||
// finally to request / establish connection
|
// finally to request / establish connection
|
||||||
if(m_args.status.isPresent() || m_args.rescanAll.isPresent() || m_args.pauseAllDirs.isPresent() || m_args.pauseAllDevs.isPresent()
|
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.resumeAllDirs.isPresent() || m_args.resumeAllDevs.isPresent() || m_args.pause.isPresent()
|
||||||
|| m_args.resume.isPresent() || m_args.waitForIdle.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 rquire establishing a connection first, the actual handler is called by handleStatusChanged() when
|
||||||
// the connection has been established
|
// the connection has been established
|
||||||
m_connection.reconnect(m_settings);
|
m_connection.reconnect(m_settings);
|
||||||
|
@ -167,11 +171,15 @@ int Application::exec(int argc, const char * const *argv)
|
||||||
void Application::handleStatusChanged(SyncthingStatus newStatus)
|
void Application::handleStatusChanged(SyncthingStatus newStatus)
|
||||||
{
|
{
|
||||||
Q_UNUSED(newStatus)
|
Q_UNUSED(newStatus)
|
||||||
|
if(m_callbacksInvoked) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if(m_connection.isConnected()) {
|
if(m_connection.isConnected()) {
|
||||||
eraseLine(cout);
|
eraseLine(cout);
|
||||||
cout << '\r';
|
cout << '\r';
|
||||||
|
m_callbacksInvoked = true;
|
||||||
m_args.parser.invokeCallbacks();
|
m_args.parser.invokeCallbacks();
|
||||||
if(!m_args.waitForIdle.isPresent()) {
|
if(!m_preventDisconnect) {
|
||||||
m_connection.disconnect();
|
m_connection.disconnect();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,7 +211,7 @@ void Application::findRelevantDirsAndDevs()
|
||||||
|
|
||||||
void Application::requestLog(const ArgumentOccurrence &)
|
void Application::requestLog(const ArgumentOccurrence &)
|
||||||
{
|
{
|
||||||
m_connection.requestLog(bind(&Application::printLog, this, _1));
|
m_connection.requestLog(&Application::printLog);
|
||||||
cerr << "Request log from " << m_settings.syncthingUrl.toLocal8Bit().data() << " ...";
|
cerr << "Request log from " << m_settings.syncthingUrl.toLocal8Bit().data() << " ...";
|
||||||
cerr.flush();
|
cerr.flush();
|
||||||
}
|
}
|
||||||
|
@ -374,6 +382,59 @@ void Application::findRelevantDirsAndDevs(OperationType operationType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::printDir(const SyncthingDir *dir)
|
||||||
|
{
|
||||||
|
cout << " - ";
|
||||||
|
setStyle(cout, TextAttribute::Bold);
|
||||||
|
cout << dir->id.toLocal8Bit().data() << '\n';
|
||||||
|
setStyle(cout);
|
||||||
|
printProperty("Label", dir->label);
|
||||||
|
printProperty("Path", dir->path);
|
||||||
|
printProperty("Status", dir->statusString());
|
||||||
|
printProperty("Last scan time", dir->lastScanTime);
|
||||||
|
printProperty("Last file time", dir->lastFileTime);
|
||||||
|
printProperty("Last file name", dir->lastFileName);
|
||||||
|
printProperty("Download progress", dir->downloadLabel);
|
||||||
|
printProperty("Devices", dir->devices);
|
||||||
|
printProperty("Read-only", dir->readOnly);
|
||||||
|
printProperty("Ignore permissions", dir->ignorePermissions);
|
||||||
|
printProperty("Auto-normalize", dir->autoNormalize);
|
||||||
|
printProperty("Rescan interval", TimeSpan::fromSeconds(dir->rescanInterval));
|
||||||
|
printProperty("Min. free disk percentage", dir->minDiskFreePercentage);
|
||||||
|
if(!dir->errors.empty()) {
|
||||||
|
cout << " Errors\n";
|
||||||
|
for(const SyncthingDirError &error : dir->errors) {
|
||||||
|
printProperty(" - Message", error.message);
|
||||||
|
printProperty(" File", error.path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
cout << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
|
void Application::printDev(const SyncthingDev *dev)
|
||||||
|
{
|
||||||
|
cout << " - ";
|
||||||
|
setStyle(cout, TextAttribute::Bold);
|
||||||
|
cout << dev->name.toLocal8Bit().data() << '\n';
|
||||||
|
setStyle(cout);
|
||||||
|
printProperty("ID", dev->id);
|
||||||
|
printProperty("Status", dev->statusString());
|
||||||
|
printProperty("Addresses", dev->addresses);
|
||||||
|
printProperty("Compression", dev->compression);
|
||||||
|
printProperty("Cert name", dev->certName);
|
||||||
|
printProperty("Connection address", dev->connectionAddress);
|
||||||
|
printProperty("Connection type", dev->connectionType);
|
||||||
|
printProperty("Client version", dev->clientVersion);
|
||||||
|
printProperty("Last seen", dev->lastSeen);
|
||||||
|
if(dev->totalIncomingTraffic > 0) {
|
||||||
|
printProperty("Incoming traffic", dataSizeToString(static_cast<uint64>(dev->totalIncomingTraffic)).data());
|
||||||
|
}
|
||||||
|
if(dev->totalOutgoingTraffic > 0) {
|
||||||
|
printProperty("Outgoing traffic", dataSizeToString(static_cast<uint64>(dev->totalOutgoingTraffic)).data());
|
||||||
|
}
|
||||||
|
cout << '\n';
|
||||||
|
}
|
||||||
|
|
||||||
void Application::printStatus(const ArgumentOccurrence &)
|
void Application::printStatus(const ArgumentOccurrence &)
|
||||||
{
|
{
|
||||||
findRelevantDirsAndDevs();
|
findRelevantDirsAndDevs();
|
||||||
|
@ -383,33 +444,7 @@ void Application::printStatus(const ArgumentOccurrence &)
|
||||||
setStyle(cout, TextAttribute::Bold);
|
setStyle(cout, TextAttribute::Bold);
|
||||||
cout << "Directories\n";
|
cout << "Directories\n";
|
||||||
setStyle(cout);
|
setStyle(cout);
|
||||||
for(const SyncthingDir *dir : m_relevantDirs) {
|
for_each(m_relevantDirs.cbegin(), m_relevantDirs.cend(), &Application::printDir);
|
||||||
cout << " - ";
|
|
||||||
setStyle(cout, TextAttribute::Bold);
|
|
||||||
cout << dir->id.toLocal8Bit().data() << '\n';
|
|
||||||
setStyle(cout);
|
|
||||||
printProperty("Label", dir->label);
|
|
||||||
printProperty("Path", dir->path);
|
|
||||||
printProperty("Status", dir->statusString());
|
|
||||||
printProperty("Last scan time", dir->lastScanTime);
|
|
||||||
printProperty("Last file time", dir->lastFileTime);
|
|
||||||
printProperty("Last file name", dir->lastFileName);
|
|
||||||
printProperty("Download progress", dir->downloadLabel);
|
|
||||||
printProperty("Devices", dir->devices);
|
|
||||||
printProperty("Read-only", dir->readOnly);
|
|
||||||
printProperty("Ignore permissions", dir->ignorePermissions);
|
|
||||||
printProperty("Auto-normalize", dir->autoNormalize);
|
|
||||||
printProperty("Rescan interval", TimeSpan::fromSeconds(dir->rescanInterval));
|
|
||||||
printProperty("Min. free disk percentage", dir->minDiskFreePercentage);
|
|
||||||
if(!dir->errors.empty()) {
|
|
||||||
cout << " Errors\n";
|
|
||||||
for(const SyncthingDirError &error : dir->errors) {
|
|
||||||
printProperty(" - Message", error.message);
|
|
||||||
printProperty(" File", error.path);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cout << '\n';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// display devs
|
// display devs
|
||||||
|
@ -417,28 +452,7 @@ void Application::printStatus(const ArgumentOccurrence &)
|
||||||
setStyle(cout, TextAttribute::Bold);
|
setStyle(cout, TextAttribute::Bold);
|
||||||
cout << "Devices\n";
|
cout << "Devices\n";
|
||||||
setStyle(cout);
|
setStyle(cout);
|
||||||
for(const SyncthingDev *dev : m_relevantDevs) {
|
for_each(m_relevantDevs.cbegin(), m_relevantDevs.cend(), &Application::printDev);
|
||||||
cout << " - ";
|
|
||||||
setStyle(cout, TextAttribute::Bold);
|
|
||||||
cout << dev->name.toLocal8Bit().data() << '\n';
|
|
||||||
setStyle(cout);
|
|
||||||
printProperty("ID", dev->id);
|
|
||||||
printProperty("Status", dev->statusString());
|
|
||||||
printProperty("Addresses", dev->addresses);
|
|
||||||
printProperty("Compression", dev->compression);
|
|
||||||
printProperty("Cert name", dev->certName);
|
|
||||||
printProperty("Connection address", dev->connectionAddress);
|
|
||||||
printProperty("Connection type", dev->connectionType);
|
|
||||||
printProperty("Client version", dev->clientVersion);
|
|
||||||
printProperty("Last seen", dev->lastSeen);
|
|
||||||
if(dev->totalIncomingTraffic > 0) {
|
|
||||||
printProperty("Incoming traffic", dataSizeToString(static_cast<uint64>(dev->totalIncomingTraffic)).data());
|
|
||||||
}
|
|
||||||
if(dev->totalOutgoingTraffic > 0) {
|
|
||||||
printProperty("Outgoing traffic", dataSizeToString(static_cast<uint64>(dev->totalOutgoingTraffic)).data());
|
|
||||||
}
|
|
||||||
cout << '\n';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cout.flush();
|
cout.flush();
|
||||||
|
@ -459,6 +473,8 @@ void Application::printLog(const std::vector<SyncthingLogEntry> &logEntries)
|
||||||
|
|
||||||
void Application::initWaitForIdle(const ArgumentOccurrence &)
|
void Application::initWaitForIdle(const ArgumentOccurrence &)
|
||||||
{
|
{
|
||||||
|
m_preventDisconnect = true;
|
||||||
|
|
||||||
findRelevantDirsAndDevs();
|
findRelevantDirsAndDevs();
|
||||||
|
|
||||||
// might idle already
|
// might idle already
|
||||||
|
@ -499,4 +515,67 @@ void Application::waitForIdle()
|
||||||
QCoreApplication::exit();
|
QCoreApplication::exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::operateOnPwd(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;
|
||||||
|
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);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QCoreApplication::quit();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Cli
|
} // namespace Cli
|
||||||
|
|
|
@ -46,15 +46,20 @@ private:
|
||||||
void requestPauseAllDirs(const ArgumentOccurrence &);
|
void requestPauseAllDirs(const ArgumentOccurrence &);
|
||||||
void requestResumeAllDevs(const ArgumentOccurrence &);
|
void requestResumeAllDevs(const ArgumentOccurrence &);
|
||||||
void requestResumeAllDirs(const ArgumentOccurrence &);
|
void requestResumeAllDirs(const ArgumentOccurrence &);
|
||||||
|
static void printDir(const Data::SyncthingDir *dir);
|
||||||
|
static void printDev(const Data::SyncthingDev *dev);
|
||||||
void printStatus(const ArgumentOccurrence &);
|
void printStatus(const ArgumentOccurrence &);
|
||||||
void printLog(const std::vector<Data::SyncthingLogEntry> &logEntries);
|
static void printLog(const std::vector<Data::SyncthingLogEntry> &logEntries);
|
||||||
void initWaitForIdle(const ArgumentOccurrence &);
|
void initWaitForIdle(const ArgumentOccurrence &);
|
||||||
void waitForIdle();
|
void waitForIdle();
|
||||||
|
void operateOnPwd(const ArgumentOccurrence &occurrence);
|
||||||
|
|
||||||
Args m_args;
|
Args m_args;
|
||||||
Data::SyncthingConnectionSettings m_settings;
|
Data::SyncthingConnectionSettings m_settings;
|
||||||
Data::SyncthingConnection m_connection;
|
Data::SyncthingConnection m_connection;
|
||||||
size_t m_expectedResponse;
|
size_t m_expectedResponse;
|
||||||
|
bool m_preventDisconnect;
|
||||||
|
bool m_callbacksInvoked;
|
||||||
std::vector<const Data::SyncthingDir *> m_relevantDirs;
|
std::vector<const Data::SyncthingDir *> m_relevantDirs;
|
||||||
std::vector<const Data::SyncthingDev *> m_relevantDevs;
|
std::vector<const Data::SyncthingDev *> m_relevantDevs;
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ Args::Args() :
|
||||||
resumeAllDevs("resume-all-devs", '\0', "resumes all devices"),
|
resumeAllDevs("resume-all-devs", '\0', "resumes all devices"),
|
||||||
resumeAllDirs("resume-all-dirs", '\0', "resumes all directories"),
|
resumeAllDirs("resume-all-dirs", '\0', "resumes all directories"),
|
||||||
waitForIdle("wait-for-idle", 'w', "waits until the specified dirs/devs are idling"),
|
waitForIdle("wait-for-idle", 'w', "waits until the specified dirs/devs are idling"),
|
||||||
|
pwd("pwd", 'p', "operates in the current working directory"),
|
||||||
statusDir("dir", 'd', "specifies the directoies (default is all dirs)", {"ID"}),
|
statusDir("dir", 'd', "specifies the directoies (default is all dirs)", {"ID"}),
|
||||||
statusDev("dev", '\0', "specifies the devices (default is all devs)", {"ID"}),
|
statusDev("dev", '\0', "specifies the devices (default is all devs)", {"ID"}),
|
||||||
pauseDir("dir", 'd', "specifies the directories", {"ID"}),
|
pauseDir("dir", 'd', "specifies the directories", {"ID"}),
|
||||||
|
@ -32,6 +33,8 @@ Args::Args() :
|
||||||
}
|
}
|
||||||
status.setSubArguments({&statusDir, &statusDev});
|
status.setSubArguments({&statusDir, &statusDev});
|
||||||
waitForIdle.setSubArguments({&statusDir, &statusDev});
|
waitForIdle.setSubArguments({&statusDir, &statusDev});
|
||||||
|
pwd.setValueNames({"status/rescan/pause/resume"});
|
||||||
|
pwd.setRequiredValueCount(1);
|
||||||
|
|
||||||
rescan.setValueNames({"dir ID"});
|
rescan.setValueNames({"dir ID"});
|
||||||
rescan.setRequiredValueCount(-1);
|
rescan.setRequiredValueCount(-1);
|
||||||
|
@ -39,7 +42,7 @@ Args::Args() :
|
||||||
resume.setSubArguments({&pauseDir, &pauseDev});
|
resume.setSubArguments({&pauseDir, &pauseDev});
|
||||||
|
|
||||||
parser.setMainArguments({&status, &log, &stop, &restart, &rescan, &rescanAll, &pause, &pauseAllDevs, &pauseAllDirs, &resume, &resumeAllDevs,
|
parser.setMainArguments({&status, &log, &stop, &restart, &rescan, &rescanAll, &pause, &pauseAllDevs, &pauseAllDirs, &resume, &resumeAllDevs,
|
||||||
&resumeAllDirs, &waitForIdle, &configFile, &apiKey, &url, &credentials, &certificate, &help});
|
&resumeAllDirs, &waitForIdle, &pwd, &configFile, &apiKey, &url, &credentials, &certificate, &help});
|
||||||
|
|
||||||
// allow setting default values via environment
|
// allow setting default values via environment
|
||||||
configFile.setEnvironmentVariable("SYNCTHING_CTL_CONFIG_FILE");
|
configFile.setEnvironmentVariable("SYNCTHING_CTL_CONFIG_FILE");
|
||||||
|
|
|
@ -12,7 +12,7 @@ struct Args
|
||||||
Args();
|
Args();
|
||||||
ArgumentParser parser;
|
ArgumentParser parser;
|
||||||
HelpArgument help;
|
HelpArgument help;
|
||||||
OperationArgument status, log, stop, restart, rescan, rescanAll, pause, pauseAllDevs, pauseAllDirs, resume, resumeAllDevs, resumeAllDirs, waitForIdle;
|
OperationArgument status, log, stop, restart, rescan, rescanAll, pause, pauseAllDevs, pauseAllDirs, resume, resumeAllDevs, resumeAllDirs, waitForIdle, pwd;
|
||||||
ConfigValueArgument statusDir, statusDev, pauseDir, pauseDev;
|
ConfigValueArgument statusDir, statusDev, pauseDir, pauseDev;
|
||||||
ConfigValueArgument configFile, apiKey, url, credentials, certificate;
|
ConfigValueArgument configFile, apiKey, url, credentials, certificate;
|
||||||
};
|
};
|
||||||
|
|
|
@ -130,6 +130,19 @@ QString SyncthingDir::statusString() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QStringRef SyncthingDir::pathWithoutTrailingSlash() const
|
||||||
|
{
|
||||||
|
QStringRef dirPath(&path);
|
||||||
|
while(dirPath.endsWith(QChar('/'))) {
|
||||||
|
#if QT_VERSION_MAJOR >= 5 && QT_VERSION_MINOR >= 8
|
||||||
|
dirPath.chop(1);
|
||||||
|
#else
|
||||||
|
dirPath = dirPath.left(dirPath.size() - 1);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
return dirPath;
|
||||||
|
}
|
||||||
|
|
||||||
SyncthingItemDownloadProgress::SyncthingItemDownloadProgress(const QString &containingDirPath, const QString &relativeItemPath, const QJsonObject &values) :
|
SyncthingItemDownloadProgress::SyncthingItemDownloadProgress(const QString &containingDirPath, const QString &relativeItemPath, const QJsonObject &values) :
|
||||||
relativePath(relativeItemPath),
|
relativePath(relativeItemPath),
|
||||||
fileInfo(containingDirPath % QChar('/') % QString(relativeItemPath).replace(QChar('\\'), QChar('/'))),
|
fileInfo(containingDirPath % QChar('/') % QString(relativeItemPath).replace(QChar('\\'), QChar('/'))),
|
||||||
|
|
|
@ -66,6 +66,7 @@ struct LIB_SYNCTHING_CONNECTOR_EXPORT SyncthingDir
|
||||||
bool assignStatus(SyncthingDirStatus newStatus, ChronoUtilities::DateTime time);
|
bool assignStatus(SyncthingDirStatus newStatus, ChronoUtilities::DateTime time);
|
||||||
QString displayName() const;
|
QString displayName() const;
|
||||||
QString statusString() const;
|
QString statusString() const;
|
||||||
|
QStringRef pathWithoutTrailingSlash() const;
|
||||||
|
|
||||||
QString id;
|
QString id;
|
||||||
QString label;
|
QString label;
|
||||||
|
|
|
@ -278,14 +278,7 @@ QList<QAction *> SyncthingFileItemAction::createActions(const KFileItemListPrope
|
||||||
QList<SyncthingItem> detectedItems;
|
QList<SyncthingItem> detectedItems;
|
||||||
const SyncthingDir *lastDir;
|
const SyncthingDir *lastDir;
|
||||||
for(const SyncthingDir &dir : dirs) {
|
for(const SyncthingDir &dir : dirs) {
|
||||||
QStringRef dirPath(&dir.path);
|
QStringRef dirPath(dir.pathWithoutTrailingSlash());
|
||||||
while(dirPath.endsWith(QChar('/'))) {
|
|
||||||
#if QT_VERSION_MAJOR >= 5 && QT_VERSION_MINOR >= 8
|
|
||||||
dirPath.chop(1);
|
|
||||||
#else
|
|
||||||
dirPath = dirPath.left(dirPath.size() - 1);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
for(const QString &path : paths) {
|
for(const QString &path : paths) {
|
||||||
if(path == dirPath) {
|
if(path == dirPath) {
|
||||||
lastDir = &dir;
|
lastDir = &dir;
|
||||||
|
|
|
@ -8,27 +8,27 @@
|
||||||
<translation type="vanished">nicht mehr verfügbar</translation>
|
<translation type="vanished">nicht mehr verfügbar</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="106"/>
|
<location filename="../syncthingfileitemaction.cpp" line="107"/>
|
||||||
<source>Status: not available anymore</source>
|
<source>Status: not available anymore</source>
|
||||||
<translation>Status: nicht mehr verfügbar</translation>
|
<translation>Status: nicht mehr verfügbar</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="115"/>
|
<location filename="../syncthingfileitemaction.cpp" line="116"/>
|
||||||
<source>Directory info for %1</source>
|
<source>Directory info for %1</source>
|
||||||
<translation>Verzeichnisinfo für %1</translation>
|
<translation>Verzeichnisinfo für %1</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="117"/>
|
<location filename="../syncthingfileitemaction.cpp" line="118"/>
|
||||||
<source>Status: </source>
|
<source>Status: </source>
|
||||||
<translation>Status: </translation>
|
<translation>Status: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="140"/>
|
<location filename="../syncthingfileitemaction.cpp" line="141"/>
|
||||||
<source>Last scan time: </source>
|
<source>Last scan time: </source>
|
||||||
<translation>Letzter Scan: </translation>
|
<translation>Letzter Scan: </translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="142"/>
|
<location filename="../syncthingfileitemaction.cpp" line="143"/>
|
||||||
<source>Rescan interval: %1 seconds</source>
|
<source>Rescan interval: %1 seconds</source>
|
||||||
<translation>Scanintervall: %1 Sekunden</translation>
|
<translation>Scanintervall: %1 Sekunden</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -36,60 +36,65 @@
|
||||||
<context>
|
<context>
|
||||||
<name>SyncthingFileItemAction</name>
|
<name>SyncthingFileItemAction</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="302"/>
|
<location filename="../syncthingfileitemaction.cpp" line="303"/>
|
||||||
<source>Rescan %1 (in %2)</source>
|
<source>Rescan %1 (in %2)</source>
|
||||||
<translation>"%1" neu scannen (in "%2")</translation>
|
<translation>"%1" neu scannen (in "%2")</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="303"/>
|
<location filename="../syncthingfileitemaction.cpp" line="304"/>
|
||||||
<source>Rescan selected items</source>
|
<source>Rescan selected items</source>
|
||||||
<translation>Auswahl neu scannen</translation>
|
<translation>Auswahl neu scannen</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="321"/>
|
<location filename="../syncthingfileitemaction.cpp" line="322"/>
|
||||||
<source>Rescan selected directories</source>
|
<source>Rescan selected directories</source>
|
||||||
<translation>Ausgewählte Verzeichnisse neu scannen</translation>
|
<translation>Ausgewählte Verzeichnisse neu scannen</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="348"/>
|
<location filename="../syncthingfileitemaction.cpp" line="349"/>
|
||||||
<source>Resume selected directories</source>
|
<source>Resume selected directories</source>
|
||||||
<translation>Ausgewählte verzeichnisse fortsetzen</translation>
|
<translation>Ausgewählte verzeichnisse fortsetzen</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="320"/>
|
<location filename="../syncthingfileitemaction.cpp" line="321"/>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="371"/>
|
<location filename="../syncthingfileitemaction.cpp" line="372"/>
|
||||||
<source>Rescan %1</source>
|
<source>Rescan %1</source>
|
||||||
<translation>"%1" neu scannen</translation>
|
<translation>"%1" neu scannen</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="347"/>
|
<location filename="../syncthingfileitemaction.cpp" line="233"/>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="397"/>
|
<source>Syncthing connection error</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../syncthingfileitemaction.cpp" line="348"/>
|
||||||
|
<location filename="../syncthingfileitemaction.cpp" line="398"/>
|
||||||
<source>Resume %1</source>
|
<source>Resume %1</source>
|
||||||
<translation>"%1" fortsetzen</translation>
|
<translation>"%1" fortsetzen</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="354"/>
|
<location filename="../syncthingfileitemaction.cpp" line="355"/>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="404"/>
|
<location filename="../syncthingfileitemaction.cpp" line="405"/>
|
||||||
<source>Pause %1</source>
|
<source>Pause %1</source>
|
||||||
<translation>"%1" pausieren</translation>
|
<translation>"%1" pausieren</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="355"/>
|
<location filename="../syncthingfileitemaction.cpp" line="356"/>
|
||||||
<source>Pause selected directories</source>
|
<source>Pause selected directories</source>
|
||||||
<translation>Ausgewählte Verzeichnisse pausieren</translation>
|
<translation>Ausgewählte Verzeichnisse pausieren</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="372"/>
|
<location filename="../syncthingfileitemaction.cpp" line="373"/>
|
||||||
<source>Rescan containing directories</source>
|
<source>Rescan containing directories</source>
|
||||||
<translation>Beinhaltendes Verzeichnis neu scannen</translation>
|
<translation>Beinhaltendes Verzeichnis neu scannen</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="398"/>
|
<location filename="../syncthingfileitemaction.cpp" line="399"/>
|
||||||
<source>Resume containing directories</source>
|
<source>Resume containing directories</source>
|
||||||
<translation>Beinhaltendes Verzeichnis fortsetzen</translation>
|
<translation>Beinhaltendes Verzeichnis fortsetzen</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="405"/>
|
<location filename="../syncthingfileitemaction.cpp" line="406"/>
|
||||||
<source>Pause containing directories</source>
|
<source>Pause containing directories</source>
|
||||||
<translation>Beinhaltendes Verzeichnis pausieren</translation>
|
<translation>Beinhaltendes Verzeichnis pausieren</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -106,8 +111,8 @@
|
||||||
<translation type="vanished">Scanintervall: %1 Sekunden</translation>
|
<translation type="vanished">Scanintervall: %1 Sekunden</translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="240"/>
|
<location filename="../syncthingfileitemaction.cpp" line="248"/>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="431"/>
|
<location filename="../syncthingfileitemaction.cpp" line="432"/>
|
||||||
<source>About</source>
|
<source>About</source>
|
||||||
<translation>Über</translation>
|
<translation>Über</translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -115,12 +120,12 @@
|
||||||
<context>
|
<context>
|
||||||
<name>SyncthingMenuAction</name>
|
<name>SyncthingMenuAction</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="68"/>
|
<location filename="../syncthingfileitemaction.cpp" line="69"/>
|
||||||
<source>Syncthing</source>
|
<source>Syncthing</source>
|
||||||
<translation></translation>
|
<translation></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="82"/>
|
<location filename="../syncthingfileitemaction.cpp" line="83"/>
|
||||||
<source>Syncthing - connecting</source>
|
<source>Syncthing - connecting</source>
|
||||||
<translation>Syncthing - verbinde</translation>
|
<translation>Syncthing - verbinde</translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
|
@ -4,27 +4,27 @@
|
||||||
<context>
|
<context>
|
||||||
<name>SyncthingDirActions</name>
|
<name>SyncthingDirActions</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="106"/>
|
<location filename="../syncthingfileitemaction.cpp" line="107"/>
|
||||||
<source>Status: not available anymore</source>
|
<source>Status: not available anymore</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="115"/>
|
<location filename="../syncthingfileitemaction.cpp" line="116"/>
|
||||||
<source>Directory info for %1</source>
|
<source>Directory info for %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="117"/>
|
<location filename="../syncthingfileitemaction.cpp" line="118"/>
|
||||||
<source>Status: </source>
|
<source>Status: </source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="140"/>
|
<location filename="../syncthingfileitemaction.cpp" line="141"/>
|
||||||
<source>Last scan time: </source>
|
<source>Last scan time: </source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="142"/>
|
<location filename="../syncthingfileitemaction.cpp" line="143"/>
|
||||||
<source>Rescan interval: %1 seconds</source>
|
<source>Rescan interval: %1 seconds</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -32,66 +32,71 @@
|
||||||
<context>
|
<context>
|
||||||
<name>SyncthingFileItemAction</name>
|
<name>SyncthingFileItemAction</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="302"/>
|
<location filename="../syncthingfileitemaction.cpp" line="303"/>
|
||||||
<source>Rescan %1 (in %2)</source>
|
<source>Rescan %1 (in %2)</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="303"/>
|
<location filename="../syncthingfileitemaction.cpp" line="304"/>
|
||||||
<source>Rescan selected items</source>
|
<source>Rescan selected items</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="321"/>
|
<location filename="../syncthingfileitemaction.cpp" line="322"/>
|
||||||
<source>Rescan selected directories</source>
|
<source>Rescan selected directories</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="348"/>
|
<location filename="../syncthingfileitemaction.cpp" line="349"/>
|
||||||
<source>Resume selected directories</source>
|
<source>Resume selected directories</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="320"/>
|
<location filename="../syncthingfileitemaction.cpp" line="321"/>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="371"/>
|
<location filename="../syncthingfileitemaction.cpp" line="372"/>
|
||||||
<source>Rescan %1</source>
|
<source>Rescan %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="347"/>
|
<location filename="../syncthingfileitemaction.cpp" line="233"/>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="397"/>
|
<source>Syncthing connection error</source>
|
||||||
|
<translation type="unfinished"></translation>
|
||||||
|
</message>
|
||||||
|
<message>
|
||||||
|
<location filename="../syncthingfileitemaction.cpp" line="348"/>
|
||||||
|
<location filename="../syncthingfileitemaction.cpp" line="398"/>
|
||||||
<source>Resume %1</source>
|
<source>Resume %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="354"/>
|
<location filename="../syncthingfileitemaction.cpp" line="355"/>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="404"/>
|
<location filename="../syncthingfileitemaction.cpp" line="405"/>
|
||||||
<source>Pause %1</source>
|
<source>Pause %1</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="355"/>
|
<location filename="../syncthingfileitemaction.cpp" line="356"/>
|
||||||
<source>Pause selected directories</source>
|
<source>Pause selected directories</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="372"/>
|
<location filename="../syncthingfileitemaction.cpp" line="373"/>
|
||||||
<source>Rescan containing directories</source>
|
<source>Rescan containing directories</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="398"/>
|
<location filename="../syncthingfileitemaction.cpp" line="399"/>
|
||||||
<source>Resume containing directories</source>
|
<source>Resume containing directories</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="405"/>
|
<location filename="../syncthingfileitemaction.cpp" line="406"/>
|
||||||
<source>Pause containing directories</source>
|
<source>Pause containing directories</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="240"/>
|
<location filename="../syncthingfileitemaction.cpp" line="248"/>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="431"/>
|
<location filename="../syncthingfileitemaction.cpp" line="432"/>
|
||||||
<source>About</source>
|
<source>About</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
@ -99,12 +104,12 @@
|
||||||
<context>
|
<context>
|
||||||
<name>SyncthingMenuAction</name>
|
<name>SyncthingMenuAction</name>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="68"/>
|
<location filename="../syncthingfileitemaction.cpp" line="69"/>
|
||||||
<source>Syncthing</source>
|
<source>Syncthing</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
<message>
|
<message>
|
||||||
<location filename="../syncthingfileitemaction.cpp" line="82"/>
|
<location filename="../syncthingfileitemaction.cpp" line="83"/>
|
||||||
<source>Syncthing - connecting</source>
|
<source>Syncthing - connecting</source>
|
||||||
<translation type="unfinished"></translation>
|
<translation type="unfinished"></translation>
|
||||||
</message>
|
</message>
|
||||||
|
|
Loading…
Reference in New Issue