Skip to content

Commit

Permalink
Merge pull request #5904 from nextcloud/backport/5853/stable-3.9
Browse files Browse the repository at this point in the history
[stable-3.9] Set VFS PinState to Excluded for ignored files.
  • Loading branch information
mgallien authored Jul 20, 2023
2 parents d4041fb + 470a983 commit f8dae64
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 18 deletions.
7 changes: 7 additions & 0 deletions src/common/pinstate.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,13 @@ enum class PinState {
* dehydrated (which is an arbitrary decision).
*/
Unspecified = 3,

/** The file will never be synced to the cloud.
*
* Usefull for ignored files to indicate to the OS the file will never be
* synced
*/
Excluded = 4,
};
Q_ENUM_NS(PinState)

Expand Down
32 changes: 32 additions & 0 deletions src/gui/folder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,23 @@ void Folder::slotWatchedPathChanged(const QString &path, ChangeReason reason)

auto relativePath = path.midRef(this->path().size());

if (pathIsIgnored(path)) {
const auto pinState = _vfs->pinState(relativePath.toString());
if (!pinState || *pinState != PinState::Excluded) {
if (!_vfs->setPinState(relativePath.toString(), PinState::Excluded)) {
qCWarning(lcFolder) << "Could not set pin state of" << relativePath << "to excluded";
}
}
return;
} else {
const auto pinState = _vfs->pinState(relativePath.toString());
if (pinState && *pinState == PinState::Excluded) {
if (!_vfs->setPinState(relativePath.toString(), PinState::Inherited)) {
qCWarning(lcFolder) << "Could not switch pin state of" << relativePath << "from" << *pinState << "to inherited";
}
}
}

// Add to list of locally modified paths
//
// We do this before checking for our own sync-related changes to make
Expand Down Expand Up @@ -806,6 +823,21 @@ void Folder::removeFromSettings() const
settings->remove(FolderMan::escapeAlias(_definition.alias));
}

bool Folder::pathIsIgnored(const QString &path) const
{
if (path.isEmpty()) {
return true;
}

#ifndef OWNCLOUD_TEST
if (isFileExcludedAbsolute(path) && !Utility::isConflictFile(path)) {
qCDebug(lcFolder) << "* Ignoring file" << path;
return true;
}
#endif
return false;
}

bool Folder::isFileExcludedAbsolute(const QString &fullPath) const
{
return _engine->excludedFiles().isExcluded(fullPath, path(), _definition.ignoreHiddenFiles);
Expand Down
3 changes: 3 additions & 0 deletions src/gui/folder.h
Original file line number Diff line number Diff line change
Expand Up @@ -233,6 +233,9 @@ class Folder : public QObject
/// Removes the folder from the account's settings.
void removeFromSettings() const;

/* Check if the path is ignored. */
[[nodiscard]] bool pathIsIgnored(const QString &path) const;

/**
* Returns whether a file inside this folder should be excluded.
*/
Expand Down
15 changes: 2 additions & 13 deletions src/gui/folderwatcher.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,20 +66,9 @@ void FolderWatcher::init(const QString &root)
_timer.start();
}

bool FolderWatcher::pathIsIgnored(const QString &path)
bool FolderWatcher::pathIsIgnored(const QString &path) const
{
if (path.isEmpty())
return true;
if (!_folder)
return false;

#ifndef OWNCLOUD_TEST
if (_folder->isFileExcludedAbsolute(path) && !Utility::isConflictFile(path)) {
qCDebug(lcFolderWatcher) << "* Ignoring file" << path;
return true;
}
#endif
return false;
return path.isEmpty();
}

bool FolderWatcher::isReliable() const
Expand Down
6 changes: 3 additions & 3 deletions src/gui/folderwatcher.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,6 @@ class FolderWatcher : public QObject
*/
void init(const QString &root);

/* Check if the path is ignored. */
bool pathIsIgnored(const QString &path);

/**
* Returns false if the folder watcher can't be trusted to capture all
* notifications.
Expand Down Expand Up @@ -135,6 +132,9 @@ private slots:
QString possiblyAddUnlockedFilePath(const QString &path);
QString findMatchingUnlockedFileInDir(const QString &dirPath, const QString &lockFileName);

/* Check if the path should be igored by the FolderWatcher. */
[[nodiscard]] bool pathIsIgnored(const QString &path) const;

/** Path of the expected test notification */
QString _testNotificationPath;

Expand Down
4 changes: 4 additions & 0 deletions src/libsync/vfs/cfapi/cfapiwrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,8 @@ OCC::PinState cfPinStateToPinState(CF_PIN_STATE state)
return OCC::PinState::OnlineOnly;
case CF_PIN_STATE_INHERIT:
return OCC::PinState::Inherited;
case CF_PIN_STATE_EXCLUDED:
return OCC::PinState::Excluded;
default:
Q_UNREACHABLE();
return OCC::PinState::Inherited;
Expand All @@ -309,6 +311,8 @@ CF_PIN_STATE pinStateToCfPinState(OCC::PinState state)
return CF_PIN_STATE_UNPINNED;
case OCC::PinState::Unspecified:
return CF_PIN_STATE_UNSPECIFIED;
case OCC::PinState::Excluded:
return CF_PIN_STATE_EXCLUDED;
default:
Q_UNREACHABLE();
return CF_PIN_STATE_UNSPECIFIED;
Expand Down
19 changes: 17 additions & 2 deletions src/libsync/vfs/cfapi/vfs_cfapi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -224,12 +224,17 @@ Result<void, QString> VfsCfApi::dehydratePlaceholder(const SyncFileItem &item)

Result<Vfs::ConvertToPlaceholderResult, QString> VfsCfApi::convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &replacesFile)
{
const auto localPath = QDir::toNativeSeparators(filename);

if (item._type != ItemTypeDirectory && OCC::FileSystem::isLnkFile(filename)) {
qCInfo(lcCfApi) << "File \"" << filename << "\" is a Windows shortcut. Not converting it to a placeholder.";
const auto pinState = pinStateLocal(localPath);
if (!pinState || *pinState != PinState::Excluded) {
setPinStateLocal(localPath, PinState::Excluded);
}
return Vfs::ConvertToPlaceholderResult::Ok;
}

const auto localPath = QDir::toNativeSeparators(filename);
const auto replacesPath = QDir::toNativeSeparators(replacesFile);

if (cfapi::findPlaceholderInfo(localPath)) {
Expand Down Expand Up @@ -293,6 +298,11 @@ bool VfsCfApi::setPinState(const QString &folderPath, PinState state)

const auto localPath = QDir::toNativeSeparators(params().filesystemPath + folderPath);

return setPinStateLocal(localPath, state);
}

bool VfsCfApi::setPinStateLocal(const QString &localPath, PinState state)
{
if (cfapi::setPinState(localPath, state, cfapi::Recurse)) {
return true;
} else {
Expand All @@ -304,9 +314,14 @@ Optional<PinState> VfsCfApi::pinState(const QString &folderPath)
{
const auto localPath = QDir::toNativeSeparators(params().filesystemPath + folderPath);

return pinStateLocal(localPath);
}

Optional<PinState> VfsCfApi::pinStateLocal(const QString &localPath) const
{
const auto info = cfapi::findPlaceholderInfo(localPath);
if (!info) {
qCWarning(lcCfApi) << "Couldn't find pin state for regular non-placeholder file" << localPath;
qCDebug(lcCfApi) << "Couldn't find pin state for regular non-placeholder file" << localPath;
return {};
}

Expand Down
3 changes: 3 additions & 0 deletions src/libsync/vfs/cfapi/vfs_cfapi.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,9 @@ public slots:
void onHydrationJobFinished(HydrationJob *job);
HydrationJob *findHydrationJob(const QString &requestId) const;

bool setPinStateLocal(const QString &localPath, PinState state);
[[nodiscard]] Optional<PinState> pinStateLocal(const QString &localPath) const;

struct HasHydratedDehydrated {
bool hasHydrated = false;
bool hasDehydrated = false;
Expand Down

0 comments on commit f8dae64

Please sign in to comment.