From 0ce69b12dff574ea2eaab6ad006fd83e590c8f06 Mon Sep 17 00:00:00 2001 From: Matthieu Gallien Date: Thu, 7 Apr 2022 10:44:03 +0200 Subject: [PATCH] introduce new jobs to handle lock/unlock of files close #4382 Signed-off-by: Matthieu Gallien --- src/gui/CMakeLists.txt | 2 + src/gui/ocslockfilejob.cpp | 43 +++++++++++++++++ src/gui/ocslockfilejob.h | 48 +++++++++++++++++++ src/libsync/CMakeLists.txt | 2 + src/libsync/lockfilejobs.cpp | 90 ++++++++++++++++++++++++++++++++++++ src/libsync/lockfilejobs.h | 37 +++++++++++++++ 6 files changed, 222 insertions(+) create mode 100644 src/gui/ocslockfilejob.cpp create mode 100644 src/gui/ocslockfilejob.h create mode 100644 src/libsync/lockfilejobs.cpp create mode 100644 src/libsync/lockfilejobs.h diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index 8b47d33ff5110..1625e599bc5c6 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -120,6 +120,8 @@ set(client_SRCS ocssharejob.cpp ocsshareejob.h ocsshareejob.cpp + ocslockfilejob.h + ocslockfilejob.cpp openfilemanager.h openfilemanager.cpp owncloudgui.h diff --git a/src/gui/ocslockfilejob.cpp b/src/gui/ocslockfilejob.cpp new file mode 100644 index 0000000000000..d1a8b44e644a5 --- /dev/null +++ b/src/gui/ocslockfilejob.cpp @@ -0,0 +1,43 @@ +/* + * Copyright (C) by Matthieu Gallien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "ocslockfilejob.h" + +#include "account.h" + +namespace OCC { + +OcsLockFileJob::OcsLockFileJob(const AccountPtr account) + : OcsJob(account) +{ + setPath("ocs/v2.php/apps/files_lock/lock/"); +} + +void OCC::OcsLockFileJob::acquireLock(const int fileId) +{ + appendPath(QString::number(fileId)); + setVerb("PUT"); + + start(); +} + +void OcsLockFileJob::releaseLock(const int fileId) +{ + appendPath(QString::number(fileId)); + setVerb("DELETE"); + + start(); +} + +} diff --git a/src/gui/ocslockfilejob.h b/src/gui/ocslockfilejob.h new file mode 100644 index 0000000000000..36f7ff5ac7846 --- /dev/null +++ b/src/gui/ocslockfilejob.h @@ -0,0 +1,48 @@ +/* + * Copyright (C) by Matthieu Gallien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#ifndef OCSLOCKFILEJOB_H +#define OCSLOCKFILEJOB_H + +#include "ocsjob.h" + +#include "accountfwd.h" + +#include + +class QJsonDocument; + +namespace OCC { + +/** + * @brief The OcsShareJob class + * @ingroup gui + * + * Handle talking to the OCS Share API. + * For creation, deletion and modification of shares. + */ +class OcsLockFileJob : public OcsJob +{ + Q_OBJECT +public: + explicit OcsLockFileJob(const AccountPtr account); + + void acquireLock(const int fileId); + + void releaseLock(const int fileId); +}; + +} + +#endif // OCSLOCKFILEJOB_H diff --git a/src/libsync/CMakeLists.txt b/src/libsync/CMakeLists.txt index 0ee2016bbe20a..4d1aacd7b1d85 100644 --- a/src/libsync/CMakeLists.txt +++ b/src/libsync/CMakeLists.txt @@ -110,6 +110,8 @@ set(libsync_SRCS userstatusconnector.cpp ocsprofileconnector.h ocsprofileconnector.cpp + lockfilejobs.h + lockfilejobs.cpp creds/dummycredentials.h creds/dummycredentials.cpp creds/abstractcredentials.h diff --git a/src/libsync/lockfilejobs.cpp b/src/libsync/lockfilejobs.cpp new file mode 100644 index 0000000000000..4a3ce0b3c5042 --- /dev/null +++ b/src/libsync/lockfilejobs.cpp @@ -0,0 +1,90 @@ +/* + * Copyright (C) by Matthieu Gallien + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * for more details. + */ + +#include "lockfilejobs.h" + +#include "account.h" +#include "common/syncjournaldb.h" + +#include + +namespace OCC { + +Q_LOGGING_CATEGORY(lcLockFileJob, "nextcloud.sync.networkjob.lockfile", QtInfoMsg) + +LockFileJob::LockFileJob(const AccountPtr account, + SyncJournalDb *journal, + const QString &path, + const SyncFileItem::LockStatus requestedLockState, + QObject *parent) + : AbstractNetworkJob(account, path, parent) + , _journal(journal) + , _requestedLockState(requestedLockState) +{ +} + +void LockFileJob::start() +{ + qCInfo(lcLockFileJob()) << "start" << path() << _requestedLockState; + + QNetworkRequest request; + request.setRawHeader("X-User-Lock", "1"); + + QByteArray verb; + switch(_requestedLockState) + { + case SyncFileItem::LockStatus::LockedItem: + verb = "LOCK"; + break; + case SyncFileItem::LockStatus::UnlockedItem: + verb = "UNLOCK"; + break; + } + sendRequest(verb, makeDavUrl(path()), request); + + AbstractNetworkJob::start(); +} + +bool LockFileJob::finished() +{ + if (reply()->error() != QNetworkReply::NoError) { + qCInfo(lcLockFileJob()) << "finished with error" << reply()->error() << reply()->errorString(); + Q_EMIT finishedWithError(reply()); + } else { + qCInfo(lcLockFileJob()) << "success" << path(); + SyncJournalFileRecord record; + auto relativePath = path().mid(1); + if (_journal->getFileRecord(relativePath, &record) && record.isValid()) { + switch(_requestedLockState) + { + case SyncFileItem::LockStatus::LockedItem: + record._locked = true; + record._lockOwnerType = static_cast(SyncFileItem::LockOwnerType::UserLock); + record._lockOwner = account()->davDisplayName().toUtf8(); + break; + case SyncFileItem::LockStatus::UnlockedItem: + record._locked = false; + break; + } + _journal->setFileRecord(record); + _journal->commit("lock file job"); + } else { + qCInfo(lcLockFileJob()) << "failed to update database record of" << path(); + } + Q_EMIT finishedWithoutError(); + } + return true; +} + +} diff --git a/src/libsync/lockfilejobs.h b/src/libsync/lockfilejobs.h new file mode 100644 index 0000000000000..17758272239af --- /dev/null +++ b/src/libsync/lockfilejobs.h @@ -0,0 +1,37 @@ +#ifndef LOCKFILEJOBS_H +#define LOCKFILEJOBS_H + +#include "abstractnetworkjob.h" + +#include "syncfileitem.h" + +namespace OCC { + +class SyncJournalDb; + +class OWNCLOUDSYNC_EXPORT LockFileJob : public AbstractNetworkJob +{ + Q_OBJECT + +public: + explicit LockFileJob(const AccountPtr account, + SyncJournalDb *journal, + const QString &path, + const SyncFileItem::LockStatus requestedLockState, + QObject *parent = nullptr); + void start() override; + +signals: + void finishedWithError(QNetworkReply *reply); + void finishedWithoutError(); + +private: + bool finished() override; + + SyncJournalDb* _journal = nullptr; + SyncFileItem::LockStatus _requestedLockState = SyncFileItem::LockStatus::LockedItem; +}; + +} + +#endif // LOCKFILEJOBS_H