/** 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
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());
VfsSetupParams vfsParams;
vfsParams.filesystemPath = path();
- vfsParams.remotePath = remotePath();
+ vfsParams.remotePath = remotePathTrailingSlash();
vfsParams.account = _accountState->account();
vfsParams.journal = &_journal;
vfsParams.providerName = Theme::instance()->appNameGUI();
}
// 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
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;
/// 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.
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; }
{
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);
}
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;
}
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)));
}
}
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
OCC::VfsSetupParams vfsParams;
vfsParams.filesystemPath = localPath();
- vfsParams.remotePath = "";
+ vfsParams.remotePath = "/";
vfsParams.account = _account;
vfsParams.journal = _journalDb.get();
vfsParams.providerName = "OC-TEST";