mirror of
https://github.com/nextcloud/desktop.git
synced 2025-10-26 11:17:43 +00:00
Ensure the socket listener still exists
This commit is contained in:
parent
4b0122093a
commit
c273c8f71b
@ -70,8 +70,6 @@
|
||||
|
||||
#include <QProcess>
|
||||
#include <QStandardPaths>
|
||||
#include <QTemporaryFile>
|
||||
#include <networkjobs.h>
|
||||
|
||||
#ifdef Q_OS_MAC
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
@ -197,11 +195,6 @@ Q_LOGGING_CATEGORY(lcSocketApi, "nextcloud.gui.socketapi", QtInfoMsg)
|
||||
Q_LOGGING_CATEGORY(lcPublicLink, "nextcloud.gui.socketapi.publiclink", QtInfoMsg)
|
||||
|
||||
|
||||
void SocketListener::sendMessage(const QString &function, const QJsonObject &obj, bool doWait) const
|
||||
{
|
||||
sendMessage(function + QLatin1Char(':') + QJsonDocument(obj).toJson(QJsonDocument::Compact), doWait);
|
||||
}
|
||||
|
||||
void SocketListener::sendMessage(const QString &message, bool doWait) const
|
||||
{
|
||||
if (!socket) {
|
||||
@ -225,16 +218,6 @@ void SocketListener::sendMessage(const QString &message, bool doWait) const
|
||||
}
|
||||
}
|
||||
|
||||
struct ListenerHasSocketPred
|
||||
{
|
||||
QIODevice *socket;
|
||||
ListenerHasSocketPred(QIODevice *socket)
|
||||
: socket(socket)
|
||||
{
|
||||
}
|
||||
bool operator()(const SocketListener &listener) const { return listener.socket == socket; }
|
||||
};
|
||||
|
||||
SocketApi::SocketApi(QObject *parent)
|
||||
: QObject(parent)
|
||||
{
|
||||
@ -242,6 +225,7 @@ SocketApi::SocketApi(QObject *parent)
|
||||
|
||||
qRegisterMetaType<SocketListener *>("SocketListener*");
|
||||
qRegisterMetaType<QSharedPointer<SocketApiJob>>("QSharedPointer<SocketApiJob>");
|
||||
qRegisterMetaType<QSharedPointer<SocketApiJobV2>>("QSharedPointer<SocketApiJobV2>");
|
||||
|
||||
if (Utility::isWindows()) {
|
||||
socketPath = QLatin1String(R"(\\.\pipe\)")
|
||||
@ -312,7 +296,7 @@ SocketApi::~SocketApi()
|
||||
qCDebug(lcSocketApi) << "dtor";
|
||||
_localServer.close();
|
||||
// All remaining sockets will be destroyed with _localServer, their parent
|
||||
ASSERT(_listeners.isEmpty() || _listeners.first().socket->parent() == &_localServer);
|
||||
ASSERT(_listeners.isEmpty() || _listeners.first()->socket->parent() == &_localServer)
|
||||
_listeners.clear();
|
||||
}
|
||||
|
||||
@ -331,14 +315,13 @@ void SocketApi::slotNewConnection()
|
||||
connect(socket, &QObject::destroyed, this, &SocketApi::slotSocketDestroyed);
|
||||
ASSERT(socket->readAll().isEmpty());
|
||||
|
||||
_listeners.append(SocketListener(socket));
|
||||
SocketListener &listener = _listeners.last();
|
||||
|
||||
foreach (Folder *f, FolderMan::instance()->map()) {
|
||||
auto listener = QSharedPointer<SocketListener>::create(socket);
|
||||
_listeners.insert(socket, listener);
|
||||
for (Folder *f : FolderMan::instance()->map()) {
|
||||
if (f->canSync()) {
|
||||
QString message = buildRegisterPathMessage(removeTrailingSlash(f->path()));
|
||||
qCInfo(lcSocketApi) << "Trying to send SocketAPI Register Path Message -->" << message << "to" << listener.socket;
|
||||
listener.sendMessage(message);
|
||||
qCInfo(lcSocketApi) << "Trying to send SocketAPI Register Path Message -->" << message << "to" << listener->socket;
|
||||
listener->sendMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -350,13 +333,13 @@ void SocketApi::onLostConnection()
|
||||
|
||||
auto socket = qobject_cast<QIODevice *>(sender());
|
||||
ASSERT(socket);
|
||||
_listeners.erase(std::remove_if(_listeners.begin(), _listeners.end(), ListenerHasSocketPred(socket)), _listeners.end());
|
||||
_listeners.remove(socket);
|
||||
}
|
||||
|
||||
void SocketApi::slotSocketDestroyed(QObject *obj)
|
||||
{
|
||||
auto *socket = static_cast<QIODevice *>(obj);
|
||||
_listeners.erase(std::remove_if(_listeners.begin(), _listeners.end(), ListenerHasSocketPred(socket)), _listeners.end());
|
||||
_listeners.remove(socket);
|
||||
}
|
||||
|
||||
void SocketApi::slotReadSocket()
|
||||
@ -370,27 +353,38 @@ void SocketApi::slotReadSocket()
|
||||
// the readyRead() signals are received - in that case there won't be a
|
||||
// valid listener. We execute the handler anyway, but it will work with
|
||||
// a SocketListener that doesn't send any messages.
|
||||
static auto noListener = SocketListener(nullptr);
|
||||
SocketListener *listener = &noListener;
|
||||
auto listenerIt = std::find_if(_listeners.begin(), _listeners.end(), ListenerHasSocketPred(socket));
|
||||
if (listenerIt != _listeners.end()) {
|
||||
listener = &*listenerIt;
|
||||
}
|
||||
|
||||
static auto invalidListener = QSharedPointer<SocketListener>::create(nullptr);
|
||||
const auto listener = _listeners.value(socket, invalidListener);
|
||||
while (socket->canReadLine()) {
|
||||
// Make sure to normalize the input from the socket to
|
||||
// make sure that the path will match, especially on OS X.
|
||||
const QString line = QString::fromUtf8(socket->readLine().trimmed()).normalized(QString::NormalizationForm_C);
|
||||
qCInfo(lcSocketApi) << "Received SocketAPI message <--" << line << "from" << socket;
|
||||
const QByteArray command = line.midRef(0, line.indexOf(QLatin1Char(':'))).toUtf8().toUpper().replace("/", "_");
|
||||
const QByteArray functionWithArguments = "command_" + command + (command.startsWith("ASYNC_") ? "(QSharedPointer<SocketApiJob>)" : "(QString,SocketListener*)");
|
||||
const int indexOfMethod = staticMetaObject.indexOfMethod(functionWithArguments);
|
||||
const int argPos = line.indexOf(QLatin1Char(':'));
|
||||
const QByteArray command = line.midRef(0, argPos).toUtf8().toUpper();
|
||||
const int indexOfMethod = [&] {
|
||||
QByteArray functionWithArguments = QByteArrayLiteral("command_");
|
||||
if (command.startsWith("ASYNC_")) {
|
||||
functionWithArguments += command + QByteArrayLiteral("(QSharedPointer<SocketApiJob>)");
|
||||
} else if (command.startsWith("V2/")) {
|
||||
functionWithArguments += QByteArrayLiteral("V2_") + command.mid(3) + QByteArrayLiteral("(QSharedPointer<SocketApiJobV2>)");
|
||||
} else {
|
||||
functionWithArguments += command + QByteArrayLiteral("(QString,SocketListener*)");
|
||||
}
|
||||
Q_ASSERT(staticQtMetaObject.normalizedSignature(functionWithArguments) == functionWithArguments);
|
||||
const auto out = staticMetaObject.indexOfMethod(functionWithArguments);
|
||||
if (out == -1) {
|
||||
listener->sendError(QStringLiteral("Function %1 not found").arg(QString::fromUtf8(functionWithArguments)));
|
||||
}
|
||||
ASSERT(out != -1)
|
||||
return out;
|
||||
}();
|
||||
|
||||
const auto argument = line.midRef(command.length() + 1);
|
||||
const auto argument = argPos != -1 ? line.midRef(argPos + 1) : QStringRef();
|
||||
if (command.startsWith("ASYNC_")) {
|
||||
auto arguments = argument.split('|');
|
||||
if (arguments.size() != 2) {
|
||||
listener->sendMessage(QStringLiteral("argument count is wrong"));
|
||||
listener->sendError(QStringLiteral("argument count is wrong"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -409,15 +403,31 @@ void SocketApi::slotReadSocket()
|
||||
<< "with argument:" << argument;
|
||||
socketApiJob->reject(QStringLiteral("command not found"));
|
||||
}
|
||||
} else if (command.startsWith("V2/")) {
|
||||
QJsonParseError error;
|
||||
const auto json = QJsonDocument::fromJson(argument.toUtf8(), &error).object();
|
||||
if (error.error != QJsonParseError::NoError) {
|
||||
qCWarning(lcSocketApi()) << "Invalid json" << argument.toString() << error.errorString();
|
||||
listener->sendError(error.errorString());
|
||||
return;
|
||||
}
|
||||
auto socketApiJob = QSharedPointer<SocketApiJobV2>::create(listener, command, json);
|
||||
if (indexOfMethod != -1) {
|
||||
staticMetaObject.method(indexOfMethod)
|
||||
.invoke(this, Qt::QueuedConnection,
|
||||
Q_ARG(QSharedPointer<SocketApiJobV2>, socketApiJob));
|
||||
} else {
|
||||
qCWarning(lcSocketApi) << "The command is not supported by this version of the client:" << command
|
||||
<< "with argument:" << argument;
|
||||
socketApiJob->failure(QStringLiteral("command not found"));
|
||||
}
|
||||
} else {
|
||||
if (indexOfMethod != -1) {
|
||||
// to ensure that listener is still valid we need to call it with Qt::DirectConnection
|
||||
ASSERT(thread() == QThread::currentThread())
|
||||
staticMetaObject.method(indexOfMethod)
|
||||
.invoke(this, Qt::DirectConnection, Q_ARG(QString, argument.toString()),
|
||||
Q_ARG(SocketListener *, listener));
|
||||
} else {
|
||||
qCWarning(lcSocketApi) << "The command is not supported by this version of the client:" << command << "with argument:" << argument;
|
||||
Q_ARG(SocketListener *, listener.data()));
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -431,10 +441,10 @@ void SocketApi::slotRegisterPath(const QString &alias)
|
||||
|
||||
Folder *f = FolderMan::instance()->folder(alias);
|
||||
if (f) {
|
||||
QString message = buildRegisterPathMessage(removeTrailingSlash(f->path()));
|
||||
foreach (auto &listener, _listeners) {
|
||||
qCInfo(lcSocketApi) << "Trying to send SocketAPI Register Path Message -->" << message << "to" << listener.socket;
|
||||
listener.sendMessage(message);
|
||||
const QString message = buildRegisterPathMessage(removeTrailingSlash(f->path()));
|
||||
for (const auto &listener : qAsConst(_listeners)) {
|
||||
qCInfo(lcSocketApi) << "Trying to send SocketAPI Register Path Message -->" << message << "to" << listener->socket;
|
||||
listener->sendMessage(message);
|
||||
}
|
||||
}
|
||||
|
||||
@ -479,8 +489,8 @@ void SocketApi::slotUpdateFolderView(Folder *f)
|
||||
|
||||
void SocketApi::broadcastMessage(const QString &msg, bool doWait)
|
||||
{
|
||||
foreach (auto &listener, _listeners) {
|
||||
listener.sendMessage(msg, doWait);
|
||||
for (const auto &listener : qAsConst(_listeners)) {
|
||||
listener->sendMessage(msg, doWait);
|
||||
}
|
||||
}
|
||||
|
||||
@ -530,8 +540,8 @@ void SocketApi::broadcastStatusPushMessage(const QString &systemPath, SyncFileSt
|
||||
QString msg = buildMessage(QLatin1String("STATUS"), systemPath, fileStatus.toSocketAPIString());
|
||||
Q_ASSERT(!systemPath.endsWith('/'));
|
||||
uint directoryHash = qHash(systemPath.left(systemPath.lastIndexOf('/')));
|
||||
foreach (auto &listener, _listeners) {
|
||||
listener.sendMessageIfDirectoryMonitored(msg, directoryHash);
|
||||
for (const auto &listener : qAsConst(_listeners)) {
|
||||
listener->sendMessageIfDirectoryMonitored(msg, directoryHash);
|
||||
}
|
||||
}
|
||||
|
||||
@ -935,20 +945,20 @@ void SocketApi::command_MOVE_ITEM(const QString &localFile, SocketListener *)
|
||||
solver.setRemoteVersionFilename(target);
|
||||
}
|
||||
|
||||
void SocketApi::command_V2_LIST_ACCOUNTS(const QString &, SocketListener *listener) const
|
||||
void SocketApi::command_V2_LIST_ACCOUNTS(const QSharedPointer<SocketApiJobV2> &job) const
|
||||
{
|
||||
QJsonArray out;
|
||||
for (auto acc : AccountManager::instance()->accounts()) {
|
||||
// TODO: Use uuid once https://github.com/owncloud/client/pull/8397 is merged
|
||||
out << QJsonObject({ { "name", acc->account()->displayName() }, { "id", acc->account()->id() } });
|
||||
}
|
||||
listener->sendMessage(QStringLiteral("V2/ACCOUNTS"), { { "accounts", out } });
|
||||
job->success({ { "accounts", out } });
|
||||
}
|
||||
|
||||
void SocketApi::command_V2_UPLOAD_FILES_FROM(const QString &argument, SocketListener *listener) const
|
||||
void SocketApi::command_V2_UPLOAD_FILES_FROM(const QSharedPointer<SocketApiJobV2> &job) const
|
||||
{
|
||||
auto job = new SocketUploadJob(listener, argument);
|
||||
job->start();
|
||||
auto uploadJob = new SocketUploadJob(job);
|
||||
uploadJob->start();
|
||||
}
|
||||
|
||||
void SocketApi::emailPrivateLink(const QString &link)
|
||||
@ -1429,6 +1439,46 @@ QString SocketApi::buildRegisterPathMessage(const QString &path)
|
||||
return message;
|
||||
}
|
||||
|
||||
void SocketApiJob::resolve(const QString &response)
|
||||
{
|
||||
_socketListener->sendMessage(QStringLiteral("RESOLVE|") + _jobId + QLatin1Char('|') + response);
|
||||
}
|
||||
|
||||
void SocketApiJob::resolve(const QJsonObject &response)
|
||||
{
|
||||
resolve(QJsonDocument { response }.toJson());
|
||||
}
|
||||
|
||||
void SocketApiJob::reject(const QString &response)
|
||||
{
|
||||
_socketListener->sendMessage(QStringLiteral("REJECT|") + _jobId + QLatin1Char('|') + response);
|
||||
}
|
||||
|
||||
SocketApiJobV2::SocketApiJobV2(const QSharedPointer<SocketListener> &socketListener, const QByteArray &command, const QJsonObject &arguments)
|
||||
: _socketListener(socketListener)
|
||||
, _command(command)
|
||||
, _jobId(arguments[QStringLiteral("id")].toString())
|
||||
, _arguments(arguments[QStringLiteral("arguments")].toObject())
|
||||
{
|
||||
ASSERT(!_jobId.isEmpty())
|
||||
}
|
||||
|
||||
void SocketApiJobV2::success(const QJsonObject &response) const
|
||||
{
|
||||
doFinish(response);
|
||||
}
|
||||
|
||||
void SocketApiJobV2::failure(const QString &error) const
|
||||
{
|
||||
doFinish({ { QStringLiteral("error"), error } });
|
||||
}
|
||||
|
||||
void SocketApiJobV2::doFinish(const QJsonObject &obj) const
|
||||
{
|
||||
_socketListener->sendMessage(_command + QStringLiteral("_RESULT:") + QJsonDocument({ { QStringLiteral("id"), _jobId }, { QStringLiteral("arguments"), obj } }).toJson(QJsonDocument::Compact));
|
||||
Q_EMIT finished();
|
||||
}
|
||||
|
||||
} // namespace OCC
|
||||
|
||||
#include "socketapi.moc"
|
||||
|
||||
@ -40,6 +40,7 @@ class Folder;
|
||||
class SocketListener;
|
||||
class DirectEditor;
|
||||
class SocketApiJob;
|
||||
class SocketApiJobV2;
|
||||
|
||||
Q_DECLARE_LOGGING_CATEGORY(lcSocketApi)
|
||||
|
||||
@ -130,8 +131,8 @@ private:
|
||||
#endif
|
||||
|
||||
// External sync
|
||||
Q_INVOKABLE void command_V2_LIST_ACCOUNTS(const QString &argument, SocketListener *listener) const;
|
||||
Q_INVOKABLE void command_V2_UPLOAD_FILES_FROM(const QString &argument, SocketListener *listener) const;
|
||||
Q_INVOKABLE void command_V2_LIST_ACCOUNTS(const QSharedPointer<SocketApiJobV2> &job) const;
|
||||
Q_INVOKABLE void command_V2_UPLOAD_FILES_FROM(const QSharedPointer<SocketApiJobV2> &job) const;
|
||||
|
||||
// Fetch the private link and call targetFun
|
||||
void fetchPrivateLinkUrlHelper(const QString &localFile, const std::function<void(const QString &url)> &targetFun);
|
||||
@ -168,7 +169,7 @@ private:
|
||||
QString buildRegisterPathMessage(const QString &path);
|
||||
|
||||
QSet<QString> _registeredAliases;
|
||||
QList<SocketListener> _listeners;
|
||||
QMap<QIODevice *, QSharedPointer<SocketListener>> _listeners;
|
||||
SocketApiServer _localServer;
|
||||
};
|
||||
}
|
||||
|
||||
@ -62,13 +62,20 @@ class SocketListener
|
||||
public:
|
||||
QPointer<QIODevice> socket;
|
||||
|
||||
explicit SocketListener(QIODevice *socket)
|
||||
: socket(socket)
|
||||
explicit SocketListener(QIODevice *_socket)
|
||||
: socket(_socket)
|
||||
{
|
||||
}
|
||||
|
||||
void sendMessage(const QString &message, bool doWait = false) const;
|
||||
void sendMessage(const QString &function, const QJsonObject &obj, bool doWait = false) const;
|
||||
void sendWarning(const QString &message, bool doWait = false) const
|
||||
{
|
||||
sendMessage(QStringLiteral("WARNING:") + message, doWait);
|
||||
}
|
||||
void sendError(const QString &message, bool doWait = false) const
|
||||
{
|
||||
sendMessage(QStringLiteral("ERROR:") + message, doWait);
|
||||
}
|
||||
|
||||
void sendMessageIfDirectoryMonitored(const QString &message, uint systemDirectoryHash) const
|
||||
{
|
||||
@ -110,30 +117,48 @@ class SocketApiJob : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SocketApiJob(const QString &jobId, SocketListener *socketListener, const QJsonObject &arguments)
|
||||
explicit SocketApiJob(const QString &jobId, const QSharedPointer<SocketListener> &socketListener, const QJsonObject &arguments)
|
||||
: _jobId(jobId)
|
||||
, _socketListener(socketListener)
|
||||
, _arguments(arguments)
|
||||
{
|
||||
}
|
||||
|
||||
void resolve(const QString &response = QString())
|
||||
{
|
||||
_socketListener->sendMessage(QLatin1String("RESOLVE|") + _jobId + '|' + response);
|
||||
}
|
||||
void resolve(const QString &response = QString());
|
||||
|
||||
void resolve(const QJsonObject &response) { resolve(QJsonDocument { response }.toJson()); }
|
||||
void resolve(const QJsonObject &response);
|
||||
|
||||
const QJsonObject &arguments() { return _arguments; }
|
||||
|
||||
void reject(const QString &response)
|
||||
{
|
||||
_socketListener->sendMessage(QLatin1String("REJECT|") + _jobId + '|' + response);
|
||||
}
|
||||
void reject(const QString &response);
|
||||
|
||||
protected:
|
||||
QString _jobId;
|
||||
QSharedPointer<SocketListener> _socketListener;
|
||||
QJsonObject _arguments;
|
||||
};
|
||||
|
||||
class SocketApiJobV2 : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
explicit SocketApiJobV2(const QSharedPointer<SocketListener> &socketListener, const QByteArray &command, const QJsonObject &arguments);
|
||||
|
||||
void success(const QJsonObject &response) const;
|
||||
void failure(const QString &error) const;
|
||||
|
||||
const QJsonObject &arguments() const { return _arguments; }
|
||||
QByteArray command() const { return _command; }
|
||||
|
||||
Q_SIGNALS:
|
||||
void finished() const;
|
||||
|
||||
private:
|
||||
void doFinish(const QJsonObject &obj) const;
|
||||
|
||||
QSharedPointer<SocketListener> _socketListener;
|
||||
const QByteArray _command;
|
||||
QString _jobId;
|
||||
SocketListener *_socketListener;
|
||||
QJsonObject _arguments;
|
||||
};
|
||||
}
|
||||
|
||||
@ -25,24 +25,30 @@
|
||||
|
||||
using namespace OCC;
|
||||
|
||||
SocketUploadJob::SocketUploadJob(OCC::SocketListener *listener, const QString &argument, QObject *parent)
|
||||
: QObject(parent)
|
||||
, _listener(listener)
|
||||
SocketUploadJob::SocketUploadJob(const QSharedPointer<SocketApiJobV2> &job)
|
||||
: _apiJob(job)
|
||||
{
|
||||
const auto args = QJsonDocument::fromJson(argument.toUtf8()).object();
|
||||
_localPath = args[QLatin1String("localPath")].toString();
|
||||
_remotePath = args[QLatin1String("remotePath")].toString();
|
||||
if (!_remotePath.startsWith("/")) {
|
||||
connect(job.data(), &SocketApiJobV2::finished, this, &SocketUploadJob::deleteLater);
|
||||
|
||||
_localPath = _apiJob->arguments()[QLatin1String("localPath")].toString();
|
||||
_remotePath = _apiJob->arguments()[QLatin1String("remotePath")].toString();
|
||||
if (!_remotePath.startsWith(QLatin1Char('/'))) {
|
||||
_remotePath = QLatin1Char('/') + _remotePath;
|
||||
}
|
||||
|
||||
_pattern = args[QLatin1String("pattern")].toString();
|
||||
_pattern = job->arguments()[QLatin1String("pattern")].toString();
|
||||
// TODO: use uuid
|
||||
const auto accname = args[QLatin1String("account")][QLatin1String("name")].toString();
|
||||
const auto accname = job->arguments()[QLatin1String("account")][QLatin1String("name")].toString();
|
||||
auto account = AccountManager::instance()->account(accname);
|
||||
|
||||
ENFORCE(QFileInfo(_localPath).isAbsolute())
|
||||
ENFORCE(_tmp.open())
|
||||
if (!QFileInfo(_localPath).isAbsolute()) {
|
||||
job->failure(QStringLiteral("Local path must be a an absolute path"));
|
||||
return;
|
||||
}
|
||||
if (!_tmp.open()) {
|
||||
job->failure(QStringLiteral("Failed to create temporary database"));
|
||||
return;
|
||||
}
|
||||
|
||||
_db = new SyncJournalDb(_tmp.fileName(), this);
|
||||
_engine = new SyncEngine(account->account(), _localPath.endsWith(QLatin1Char('/')) ? _localPath : _localPath + QLatin1Char('/'), _remotePath, _db);
|
||||
@ -54,10 +60,12 @@ SocketUploadJob::SocketUploadJob(OCC::SocketListener *listener, const QString &a
|
||||
|
||||
connect(_engine, &OCC::SyncEngine::finished, this, [this](bool ok) {
|
||||
if (ok) {
|
||||
finish({});
|
||||
_apiJob->success({ { "localPath", _localPath }, { "syncedFiles", QJsonArray::fromStringList(_syncedFiles) } });
|
||||
}
|
||||
});
|
||||
connect(_engine, &OCC::SyncEngine::syncError, this, &SocketUploadJob::finish);
|
||||
connect(_engine, &OCC::SyncEngine::syncError, this, [this](const QString &error, ErrorCategory) {
|
||||
_apiJob->failure(error);
|
||||
});
|
||||
}
|
||||
|
||||
void SocketUploadJob::start()
|
||||
@ -65,7 +73,7 @@ void SocketUploadJob::start()
|
||||
auto opt = _engine->syncOptions();
|
||||
opt.setFilePattern(_pattern);
|
||||
if (!opt.fileRegex().isValid()) {
|
||||
finish(opt.fileRegex().errorString());
|
||||
_apiJob->failure(opt.fileRegex().errorString());
|
||||
return;
|
||||
}
|
||||
_engine->setSyncOptions(opt);
|
||||
@ -75,19 +83,10 @@ void SocketUploadJob::start()
|
||||
connect(mkdir, &OCC::MkColJob::finishedWithoutError, _engine, &OCC::SyncEngine::startSync);
|
||||
connect(mkdir, &OCC::MkColJob::finishedWithError, this, [this](QNetworkReply *reply) {
|
||||
if (reply->error() == 202) {
|
||||
finish(QStringLiteral("Destination %1 already exists").arg(_remotePath));
|
||||
_apiJob->failure(QStringLiteral("Destination %1 already exists").arg(_remotePath));
|
||||
} else {
|
||||
finish(reply->errorString());
|
||||
_apiJob->failure(reply->errorString());
|
||||
}
|
||||
});
|
||||
mkdir->start();
|
||||
}
|
||||
|
||||
void SocketUploadJob::finish(const QString &error)
|
||||
{
|
||||
if (!_finished) {
|
||||
_finished = true;
|
||||
_listener->sendMessage(QStringLiteral("V2/UPLOAD_FILES_RESULT"), { { "localPath", _localPath }, { "error", error }, { "syncedFiles", QJsonArray::fromStringList(_syncedFiles) } });
|
||||
deleteLater();
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,14 +28,11 @@ class SocketUploadJob : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
SocketUploadJob(OCC::SocketListener *listener, const QString &argument, QObject *parent = nullptr);
|
||||
|
||||
SocketUploadJob(const QSharedPointer<SocketApiJobV2> &job);
|
||||
void start();
|
||||
|
||||
void finish(const QString &error);
|
||||
|
||||
private:
|
||||
SocketListener *_listener;
|
||||
QSharedPointer<SocketApiJobV2> _apiJob;
|
||||
QString _localPath;
|
||||
QString _remotePath;
|
||||
QString _pattern;
|
||||
@ -43,7 +40,5 @@ private:
|
||||
SyncJournalDb *_db;
|
||||
SyncEngine *_engine;
|
||||
QStringList _syncedFiles;
|
||||
|
||||
bool _finished = false;
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user