Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
mickenordin authored Jan 19, 2024
2 parents 3f35720 + c4f2537 commit cf5773b
Show file tree
Hide file tree
Showing 72 changed files with 853 additions and 787 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/clang-format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ jobs:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
- uses: cpp-linter/[email protected].2
- uses: cpp-linter/[email protected].6
id: linter
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/fixup.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ name: Block fixup and squash commits

on:
pull_request:
types: [opened, synchronize, reopened]
types: [opened, ready_for_review, reopened, synchronize]

permissions:
contents: read
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1226,7 +1226,7 @@
/* Begin XCRemoteSwiftPackageReference section */
5307A6E42965C6FA001E0C6A /* XCRemoteSwiftPackageReference "NextcloudKit" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/nextcloud/NextcloudKit";
repositoryURL = "https://github.com/nextcloud/NextcloudKit.git";
requirement = {
branch = develop;
kind = branch;
Expand Down
74 changes: 38 additions & 36 deletions src/common/utility.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,14 @@
#include "utility_unix.cpp"
#endif

namespace {
constexpr auto bytes = 1024;
constexpr auto kilobytes = bytes;
constexpr auto megabytes = bytes * kilobytes;
constexpr qint64 gigabytes = bytes * megabytes;
constexpr qint64 terabytes = bytes * gigabytes;
}

namespace OCC {

Q_LOGGING_CATEGORY(lcUtility, "nextcloud.sync.utility", QtInfoMsg)
Expand Down Expand Up @@ -114,46 +122,40 @@ void Utility::removeFavLink(const QString &folder)
removeFavLink_private(folder);
}

QString Utility::octetsToString(qint64 octets)
{
#define THE_FACTOR 1024
static const qint64 kb = THE_FACTOR;
static const qint64 mb = THE_FACTOR * kb;
static const qint64 gb = THE_FACTOR * mb;

QString s;
qreal value = octets;

// Whether we care about decimals: only for GB/MB and only
// if it's less than 10 units.
bool round = true;

// do not display terra byte with the current units, as when
// the MB, GB and KB units were made, there was no TB,
// see the JEDEC standard
// https://en.wikipedia.org/wiki/JEDEC_memory_standards
if (octets >= gb) {
s = QCoreApplication::translate("Utility", "%L1 GB");
value /= gb;
round = false;
} else if (octets >= mb) {
s = QCoreApplication::translate("Utility", "%L1 MB");
value /= mb;
round = false;
} else if (octets >= kb) {
s = QCoreApplication::translate("Utility", "%L1 KB");
value /= kb;
} else {
s = QCoreApplication::translate("Utility", "%L1 B");
QString Utility::octetsToString(const qint64 octets)
{
auto unitName = QCoreApplication::translate("Utility", "%L1 B");
qreal dataSize = octets;

// Display decimals when value < TB and unit < 10
auto showDecimals = true;

if (octets >= terabytes) {
unitName = QCoreApplication::translate("Utility", "%L1 TB");
dataSize /= terabytes;
showDecimals = false;
} else if (octets >= gigabytes) {
unitName = QCoreApplication::translate("Utility", "%L1 GB");
dataSize /= gigabytes;
showDecimals = false;
} else if (octets >= megabytes) {
unitName = QCoreApplication::translate("Utility", "%L1 MB");
dataSize /= megabytes;
showDecimals = false;
} else if (octets >= kilobytes) {
unitName = QCoreApplication::translate("Utility", "%L1 KB");
dataSize /= kilobytes;
}

if (value > 9.95)
round = true;
if (dataSize > 9.95) {
showDecimals = true;
}

if (round)
return s.arg(qRound(value));
if (showDecimals) {
return unitName.arg(qRound(dataSize));
}

return s.arg(value, 0, 'g', 2);
return unitName.arg(dataSize, 0, 'g', 2);
}

// Qtified version of get_platforms() in csync_owncloud.c
Expand Down
2 changes: 1 addition & 1 deletion src/common/utility.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ namespace Utility {
OCSYNC_EXPORT void setupFavLink(const QString &folder);
OCSYNC_EXPORT void removeFavLink(const QString &folder);
OCSYNC_EXPORT bool writeRandomFile(const QString &fname, int size = -1);
OCSYNC_EXPORT QString octetsToString(qint64 octets);
OCSYNC_EXPORT QString octetsToString(const qint64 octets);
OCSYNC_EXPORT QByteArray userAgentString();
OCSYNC_EXPORT QByteArray friendlyUserAgentString();
/**
Expand Down
18 changes: 16 additions & 2 deletions src/gui/application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,11 @@ namespace {
#elif defined(Q_OS_MAC)
return QApplication::applicationDirPath() + QLatin1String("/../Resources/Translations"); // path defaults to app dir.
#elif defined(Q_OS_UNIX)
return QString::fromLatin1(SHAREDIR "/" APPLICATION_EXECUTABLE "/i18n/");
if (qEnvironmentVariableIsSet("APPIMAGE")) {
return QApplication::applicationDirPath() + QLatin1String("/../share/" APPLICATION_EXECUTABLE "/i18n/");
} else {
return QString::fromLatin1(SHAREDIR "/" APPLICATION_EXECUTABLE "/i18n/");
}
#endif
}
}
Expand Down Expand Up @@ -961,8 +965,14 @@ void Application::setupTranslations()
for (QString lang : qAsConst(uiLanguages)) {
lang.replace(QLatin1Char('-'), QLatin1Char('_')); // work around QTBUG-25973
lang = substLang(lang);
const QString trPath = applicationTrPath();
const auto trPath = applicationTrPath();
const auto trFolder = QDir{trPath};
if (!trFolder.exists()) {
qCWarning(lcApplication()) << trPath << "folder containing translations is missing. Impossible to load translations";
break;
}
const QString trFile = QLatin1String("client_") + lang;
qCDebug(lcApplication()) << "trying to load" << lang << "in" << trFile << "from" << trPath;
if (translator->load(trFile, trPath) || lang.startsWith(QLatin1String("en"))) {
// Permissive approach: Qt and keychain translations
// may be missing, but Qt translations must be there in order
Expand Down Expand Up @@ -992,6 +1002,10 @@ void Application::setupTranslations()
if (!qtkeychainTranslator->isEmpty())
installTranslator(qtkeychainTranslator);
break;
} else {
qCWarning(lcApplication()) << "translation catalog failed to load";
const auto folderContent = trFolder.entryList();
qCDebug(lcApplication()) << "folder content" << folderContent.join(QStringLiteral(", "));
}
if (property("ui_lang").isNull()) {
setProperty("ui_lang", "C");
Expand Down
3 changes: 2 additions & 1 deletion src/gui/editlocallyjob.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -650,7 +650,8 @@ void EditLocallyJob::lockFile()
_folderForFile->remotePathTrailingSlash(),
_folderForFile->path(),
_folderForFile->journalDb(),
SyncFileItem::LockStatus::LockedItem);
SyncFileItem::LockStatus::LockedItem,
SyncFileItem::LockOwnerType::TokenLock);
}

void EditLocallyJob::disconnectFolderSignals()
Expand Down
9 changes: 6 additions & 3 deletions src/gui/folder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -649,7 +649,7 @@ void Folder::slotFilesLockReleased(const QSet<QString> &files)
}
const auto canUnlockFile = isFileRecordValid
&& rec._lockstate._locked
&& rec._lockstate._lockOwnerType == static_cast<qint64>(SyncFileItem::LockOwnerType::UserLock)
&& rec._lockstate._lockOwnerType == static_cast<qint64>(SyncFileItem::LockOwnerType::TokenLock)
&& rec._lockstate._lockOwnerId == _accountState->account()->davUser();

if (!canUnlockFile) {
Expand All @@ -668,11 +668,13 @@ void Folder::slotFilesLockReleased(const QSet<QString> &files)
disconnect(_officeFileLockReleaseUnlockFailure);
qCWarning(lcFolder) << "Failed to unlock a file:" << remoteFilePath << message;
});
const auto lockOwnerType = static_cast<SyncFileItem::LockOwnerType>(rec._lockstate._lockOwnerType);
_accountState->account()->setLockFileState(remoteFilePath,
remotePathTrailingSlash(),
path(),
journalDb(),
SyncFileItem::LockStatus::UnlockedItem);
SyncFileItem::LockStatus::UnlockedItem,
lockOwnerType);
}
}

Expand Down Expand Up @@ -719,7 +721,8 @@ void Folder::slotLockedFilesFound(const QSet<QString> &files)
remotePathTrailingSlash(),
path(),
journalDb(),
SyncFileItem::LockStatus::LockedItem);
SyncFileItem::LockStatus::LockedItem,
SyncFileItem::LockOwnerType::TokenLock);
}
}

Expand Down
9 changes: 8 additions & 1 deletion src/gui/socketapi/socketapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1091,11 +1091,18 @@ void SocketApi::setFileLock(const QString &localFile, const SyncFileItem::LockSt
return;
}

const auto record = fileData.journalRecord();
if (static_cast<SyncFileItem::LockOwnerType>(record._lockstate._lockOwnerType) != SyncFileItem::LockOwnerType::UserLock) {
qCDebug(lcSocketApi) << "Only user lock state or non-locked files can be affected manually!";
return;
}

shareFolder->accountState()->account()->setLockFileState(fileData.serverRelativePath,
shareFolder->remotePathTrailingSlash(),
shareFolder->path(),
shareFolder->journalDb(),
lockState);
lockState,
SyncFileItem::LockOwnerType::UserLock);

shareFolder->journalDb()->schedulePathForRemoteDiscovery(fileData.serverRelativePath);
shareFolder->scheduleThisFolderSoon();
Expand Down
5 changes: 3 additions & 2 deletions src/libsync/account.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -959,15 +959,16 @@ void Account::setLockFileState(const QString &serverRelativePath,
const QString &remoteSyncPathWithTrailingSlash,
const QString &localSyncPath,
SyncJournalDb * const journal,
const SyncFileItem::LockStatus lockStatus)
const SyncFileItem::LockStatus lockStatus,
const SyncFileItem::LockOwnerType lockOwnerType)
{
auto& lockStatusJobInProgress = _lockStatusChangeInprogress[serverRelativePath];
if (lockStatusJobInProgress.contains(lockStatus)) {
qCWarning(lcAccount) << "Already running a job with lockStatus:" << lockStatus << " for: " << serverRelativePath;
return;
}
lockStatusJobInProgress.push_back(lockStatus);
auto job = std::make_unique<LockFileJob>(sharedFromThis(), journal, serverRelativePath, remoteSyncPathWithTrailingSlash, localSyncPath, lockStatus);
auto job = std::make_unique<LockFileJob>(sharedFromThis(), journal, serverRelativePath, remoteSyncPathWithTrailingSlash, localSyncPath, lockStatus, lockOwnerType);
connect(job.get(), &LockFileJob::finishedWithoutError, this, [this, serverRelativePath, lockStatus]() {
removeLockStatusChangeInprogress(serverRelativePath, lockStatus);
Q_EMIT lockFileSuccess();
Expand Down
3 changes: 2 additions & 1 deletion src/libsync/account.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,8 @@ class OWNCLOUDSYNC_EXPORT Account : public QObject
const QString &remoteSyncPathWithTrailingSlash,
const QString &localSyncPath,
SyncJournalDb * const journal,
const SyncFileItem::LockStatus lockStatus);
const SyncFileItem::LockStatus lockStatus,
const SyncFileItem::LockOwnerType lockOwnerType);

SyncFileItem::LockStatus fileLockStatus(SyncJournalDb * const journal,
const QString &folderRelativePath) const;
Expand Down
5 changes: 5 additions & 0 deletions src/libsync/capabilities.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,11 @@ bool Capabilities::filesLockAvailable() const
return _capabilities["files"].toMap()["locking"].toByteArray() >= "1.0";
}

bool Capabilities::filesLockTypeAvailable() const
{
return _capabilities["files"].toMap()["api-feature-lock-type"].toByteArray() >= "1.0";
}

bool Capabilities::userStatus() const
{
if (!_capabilities.contains("user_status")) {
Expand Down
1 change: 1 addition & 0 deletions src/libsync/capabilities.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ class OWNCLOUDSYNC_EXPORT Capabilities
[[nodiscard]] bool chunkingNg() const;
[[nodiscard]] bool bulkUpload() const;
[[nodiscard]] bool filesLockAvailable() const;
[[nodiscard]] bool filesLockTypeAvailable() const;
[[nodiscard]] bool userStatus() const;
[[nodiscard]] bool userStatusSupportsEmoji() const;
[[nodiscard]] QColor serverColor() const;
Expand Down
15 changes: 13 additions & 2 deletions src/libsync/lockfilejobs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,10 +31,12 @@ LockFileJob::LockFileJob(const AccountPtr account,
const QString &remoteSyncPathWithTrailingSlash,
const QString &localSyncPath,
const SyncFileItem::LockStatus requestedLockState,
const SyncFileItem::LockOwnerType lockOwnerType,
QObject *parent)
: AbstractNetworkJob(account, path, parent)
, _journal(journal)
, _requestedLockState(requestedLockState)
, _requestedLockOwnerType(lockOwnerType)
, _remoteSyncPathWithTrailingSlash(remoteSyncPathWithTrailingSlash)
, _localSyncPath(localSyncPath)
{
Expand All @@ -48,7 +50,14 @@ void LockFileJob::start()
qCInfo(lcLockFileJob()) << "start" << path() << _requestedLockState;

QNetworkRequest request;
request.setRawHeader("X-User-Lock", "1");
request.setRawHeader(QByteArrayLiteral("X-User-Lock"), QByteArrayLiteral("1"));
if (_account->capabilities().filesLockTypeAvailable()) {
if (_requestedLockOwnerType == SyncFileItem::LockOwnerType::UserLock) {
request.setRawHeader(QByteArrayLiteral("X-User-Lock-Type"), ("0"));
} else if (_requestedLockOwnerType == SyncFileItem::LockOwnerType::TokenLock) {
request.setRawHeader(QByteArrayLiteral("X-User-Lock-Type"), ("2"));
}
}

QByteArray verb;
switch(_requestedLockState)
Expand Down Expand Up @@ -174,7 +183,7 @@ SyncJournalFileRecord LockFileJob::handleReply()
if (_journal->getFileRecord(relativePathInDb, &record) && record.isValid()) {
setFileRecordLocked(record);
if ((_lockStatus == SyncFileItem::LockStatus::LockedItem)
&& (_lockOwnerType != SyncFileItem::LockOwnerType::UserLock || _userId != account()->davUser())) {
&& (_lockOwnerType == SyncFileItem::LockOwnerType::AppLock || _userId != account()->davUser())) {
FileSystem::setFileReadOnly(_localSyncPath + relativePathInDb, true);
}
const auto result = _journal->setFileRecord(record);
Expand Down Expand Up @@ -205,6 +214,8 @@ void LockFileJob::decodeStartElement(const QString &name,
const auto convertedValue = valueText.toInt(&isValid);
if (isValid) {
_lockOwnerType = static_cast<SyncFileItem::LockOwnerType>(convertedValue);
} else {
_lockOwnerType = SyncFileItem::LockOwnerType::UserLock;
}
} else if (name == QStringLiteral("lock-owner-displayname")) {
_userDisplayName = reader.readElementText();
Expand Down
2 changes: 2 additions & 0 deletions src/libsync/lockfilejobs.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class OWNCLOUDSYNC_EXPORT LockFileJob : public AbstractNetworkJob
const QString &remoteSyncPathWithTrailingSlash,
const QString &localSyncPath,
const SyncFileItem::LockStatus requestedLockState,
const SyncFileItem::LockOwnerType lockOwnerType,
QObject *parent = nullptr);
void start() override;

Expand All @@ -48,6 +49,7 @@ class OWNCLOUDSYNC_EXPORT LockFileJob : public AbstractNetworkJob

SyncJournalDb* _journal = nullptr;
SyncFileItem::LockStatus _requestedLockState = SyncFileItem::LockStatus::LockedItem;
SyncFileItem::LockOwnerType _requestedLockOwnerType = SyncFileItem::LockOwnerType::UserLock;

SyncFileItem::LockStatus _lockStatus = SyncFileItem::LockStatus::UnlockedItem;
SyncFileItem::LockOwnerType _lockOwnerType = SyncFileItem::LockOwnerType::UserLock;
Expand Down
Loading

0 comments on commit cf5773b

Please sign in to comment.