Folder: Add remoteFolderTrailingSlash()

There were cases where the "/" exception wasn't handled correctly
and there'd be extra slashes in generated paths.
This commit is contained in:
Christian Kamm 2019-01-25 07:46:16 +01:00 committed by Kevin Ottens
parent 41f1ddb5fc
commit 0eb4065197
No known key found for this signature in database
GPG key ID: 074BBBCB8DECC9E2
8 changed files with 43 additions and 27 deletions

View file

@ -37,9 +37,16 @@ class SyncFileItem;
/** Collection of parameters for initializing a Vfs instance. */
struct OCSYNC_EXPORT VfsSetupParams
{
/// The full path to the folder on the local filesystem
/** The full path to the folder on the local filesystem
*
* Always ends with /.
*/
QString filesystemPath;
/// The path to the synced folder on the account
/** The path to the synced folder on the account
*
* Always ends with /.
*/
QString remotePath;
/// Account url, credentials etc for network calls

View file

@ -256,6 +256,14 @@ QString Folder::remotePath() const
return _definition.targetPath;
}
QString Folder::remotePathTrailingSlash() const
{
QString result = remotePath();
if (!result.endsWith('/'))
result.append('/');
return result;
}
QUrl Folder::remoteUrl() const
{
return Utility::concatUrlPath(_accountState->account()->davUrl(), remotePath());
@ -476,7 +484,7 @@ void Folder::startVfs()
VfsSetupParams vfsParams;
vfsParams.filesystemPath = path();
vfsParams.remotePath = remotePath();
vfsParams.remotePath = remotePathTrailingSlash();
vfsParams.account = _accountState->account();
vfsParams.journal = &_journal;
vfsParams.providerName = Theme::instance()->appNameGUI();
@ -1303,7 +1311,7 @@ bool FolderDefinition::load(QSettings &settings, const QString &alias,
}
// Old settings can contain paths with native separators. In the rest of the
// code we assum /, so clean it up now.
// code we assume /, so clean it up now.
folder->localPath = prepareLocalPath(folder->localPath);
// Target paths also have a convention

View file

@ -51,11 +51,11 @@ class FolderDefinition
public:
/// The name of the folder in the ui and internally
QString alias;
/// path on local machine
/// path on local machine (always trailing /)
QString localPath;
/// path to the journal, usually relative to localPath
QString journalPath;
/// path on remote
/// path on remote (usually no trailing /, exception "/")
QString targetPath;
/// whether the folder is paused
bool paused = false;
@ -88,7 +88,7 @@ public:
/// Ensure / as separator and trailing /.
static QString prepareLocalPath(const QString &path);
/// Ensure starting / and no ending /.
/// Remove ending /, then ensure starting '/': so "/foo/bar" and "/".
static QString prepareTargetPath(const QString &path);
/// journalPath relative to localPath.
@ -146,10 +146,15 @@ public:
QString cleanPath() const;
/**
* remote folder path
* remote folder path, usually without trailing /, exception "/"
*/
QString remotePath() const;
/**
* remote folder path, always with a trailing /
*/
QString remotePathTrailingSlash() const;
void setNavigationPaneClsid(const QUuid &clsid) { _definition.navigationPaneClsid = clsid; }
QUuid navigationPaneClsid() const { return _definition.navigationPaneClsid; }

View file

@ -1091,16 +1091,20 @@ QStringList FolderMan::findFileInLocalFolders(const QString &relPath, const Acco
{
QStringList re;
// We'll be comparing against Folder::remotePath which always starts with /
QString serverPath = relPath;
if (!serverPath.startsWith('/'))
serverPath.prepend('/');
for (Folder *folder : this->map().values()) {
if (acc && folder->accountState()->account() != acc) {
continue;
}
QString path = folder->cleanPath();
QString remRelPath;
// cut off the remote path from the server path.
remRelPath = relPath.mid(folder->remotePath().length());
path += "/";
path += remRelPath;
if (!serverPath.startsWith(folder->remotePath()))
continue;
QString path = folder->cleanPath() + '/';
path += serverPath.midRef(folder->remotePathTrailingSlash().length());
if (QFile::exists(path)) {
re.append(path);
}

View file

@ -570,11 +570,8 @@ void FolderStatusModel::fetchMore(const QModelIndex &parent)
if (!info || info->_fetched || info->_fetchingJob)
return;
info->resetSubs(this, parent);
QString path = info->_folder->remotePath();
QString path = info->_folder->remotePathTrailingSlash();
if (info->_path != QLatin1String("/")) {
if (!path.endsWith(QLatin1Char('/'))) {
path += QLatin1Char('/');
}
path += info->_path;
}

View file

@ -449,13 +449,10 @@ bool FolderWizardRemotePath::isComplete() const
if (f->accountState()->account() != _account) {
continue;
}
QString curDir = f->remotePath();
if (!curDir.startsWith(QLatin1Char('/'))) {
curDir.prepend(QLatin1Char('/'));
}
QString curDir = f->remotePathTrailingSlash();
if (QDir::cleanPath(dir) == QDir::cleanPath(curDir)) {
warnStrings.append(tr("This folder is already being synced."));
} else if (dir.startsWith(curDir + QLatin1Char('/'))) {
} else if (dir.startsWith(curDir)) {
warnStrings.append(tr("You are already syncing <i>%1</i>, which is a parent folder of <i>%2</i>.").arg(Utility::escape(curDir), Utility::escape(dir)));
}
}

View file

@ -37,9 +37,7 @@ static void updateFolder(const AccountPtr &account, const QString &path)
if (path.startsWith(folderPath) && (path == folderPath || folderPath.endsWith('/') || path[folderPath.size()] == '/')) {
// Workaround the fact that the server does not invalidate the etags of parent directories
// when something is shared.
auto relative = path.midRef(folderPath.size());
if (relative.startsWith('/'))
relative = relative.mid(1);
auto relative = path.midRef(f->remotePathTrailingSlash().length());
f->journalDb()->avoidReadFromDbOnNextSync(relative.toString());
// Schedule a sync so it can update the remote permission flag and let the socket API

View file

@ -947,7 +947,7 @@ public:
OCC::VfsSetupParams vfsParams;
vfsParams.filesystemPath = localPath();
vfsParams.remotePath = "";
vfsParams.remotePath = "/";
vfsParams.account = _account;
vfsParams.journal = _journalDb.get();
vfsParams.providerName = "OC-TEST";