#endif
}
-QString OwncloudPropagator::getFilePath(const QString &tmp_file_name) const
+QString OwncloudPropagator::fullLocalPath(const QString &tmp_file_name) const
{
return _localDir + tmp_file_name;
}
+QString OwncloudPropagator::localPath() const
+{
+ return _localDir;
+}
+
void OwncloudPropagator::scheduleNextJob()
{
if (_jobScheduled) return; // don't schedule more than 1
bool OwncloudPropagator::createConflict(const SyncFileItemPtr &item,
PropagatorCompositeJob *composite, QString *error)
{
- QString fn = getFilePath(item->_file);
+ QString fn = fullLocalPath(item->_file);
QString renameError;
auto conflictModTime = FileSystem::getModTime(fn);
conflictUserName = account()->davDisplayName();
QString conflictFileName = Utility::makeConflictFileName(
item->_file, Utility::qDateTimeFromTime_t(conflictModTime), conflictUserName);
- QString conflictFilePath = getFilePath(conflictFileName);
+ QString conflictFilePath = fullLocalPath(conflictFileName);
emit touchedFile(fn);
emit touchedFile(conflictFilePath);
if (_item->_instruction == CSYNC_INSTRUCTION_NEW && _item->_direction == SyncFileItem::Down) {
// special case for local MKDIR, set local directory mtime
// (it's not synced later at all, but can be nice to have it set initially)
- FileSystem::setModTime(propagator()->getFilePath(_item->destination()), _item->_modtime);
+ FileSystem::setModTime(propagator()->fullLocalPath(_item->destination()), _item->_modtime);
}
// For new directories we always want to update the etag once
// Continue with the next entry, or finish
start();
}
+
+QString OwncloudPropagator::fullRemotePath(const QString &tmp_file_name) const
+{
+ // TODO: should this be part of the _item (SyncFileItemPtr)?
+ return _remoteFolder + tmp_file_name;
+}
+
+QString OwncloudPropagator::remotePath() const
+{
+ return _remoteFolder;
+}
}
{
Q_OBJECT
public:
- const QString _localDir; // absolute path to the local directory. ends with '/'
- const QString _remoteFolder; // remote folder, ends with '/'
-
SyncJournalDb *const _journal;
bool _finishedEmited; // used to ensure that finished is only emitted once
*/
bool hasCaseClashAccessibilityProblem(const QString &relfile);
- /* returns the local file path for the given tmp_file_name */
- QString getFilePath(const QString &tmp_file_name) const;
+ Q_REQUIRED_RESULT QString fullLocalPath(const QString &tmp_file_name) const;
+ QString localPath() const;
+
+ /**
+ * Returns the full remote path including the folder root of a
+ * folder sync path.
+ */
+ Q_REQUIRED_RESULT QString fullRemotePath(const QString &tmp_file_name) const;
+ QString remotePath() const;
/** Creates the job for an item.
*/
QScopedPointer<PropagateRootDirectory> _rootJob;
SyncOptions _syncOptions;
bool _jobScheduled = false;
+
+ const QString _localDir; // absolute path to the local directory. ends with '/'
+ const QString _remoteFolder; // remote folder, ends with '/'
};
qCDebug(lcPropagateDownload) << _item->_file << propagator()->_activeJobList.count();
const auto rootPath = [=]() {
- const auto result = propagator()->_remoteFolder;
+ const auto result = propagator()->remotePath();
if (result.startsWith('/')) {
return result.mid(1);
} else {
// For virtual files just dehydrate or create the file and be done
if (_item->_type == ItemTypeVirtualFileDehydration) {
- QString fsPath = propagator()->getFilePath(_item->_file);
+ QString fsPath = propagator()->fullLocalPath(_item->_file);
if (!FileSystem::verifyFileUnchanged(fsPath, _item->_previousSize, _item->_previousModtime)) {
propagator()->_anotherSyncNeeded = true;
done(SyncFileItem::SoftError, tr("File has changed since discovery"));
connect(computeChecksum, &ComputeChecksum::done,
this, &PropagateDownloadFile::conflictChecksumComputed);
propagator()->_activeJobList.append(this);
- computeChecksum->start(propagator()->getFilePath(_item->_file));
+ computeChecksum->start(propagator()->fullLocalPath(_item->_file));
return;
}
// Apply the server mtime locally if necessary, ensuring the journal
// and local mtimes end up identical
- auto fn = propagator()->getFilePath(_item->_file);
+ auto fn = propagator()->fullLocalPath(_item->_file);
if (_item->_modtime != _item->_previousModtime) {
FileSystem::setModTime(fn, _item->_modtime);
emit propagator()->touchedFile(fn);
if (progressInfo._valid) {
// if the etag has changed meanwhile, remove the already downloaded part.
if (progressInfo._etag != _item->_etag) {
- FileSystem::remove(propagator()->getFilePath(progressInfo._tmpfile));
+ FileSystem::remove(propagator()->fullLocalPath(progressInfo._tmpfile));
propagator()->_journal->setDownloadInfo(_item->_file, SyncJournalDb::DownloadInfo());
} else {
tmpFileName = progressInfo._tmpfile;
if (tmpFileName.isEmpty()) {
tmpFileName = createDownloadTmpFileName(_item->_file);
}
- _tmpFile.setFileName(propagator()->getFilePath(tmpFileName));
+ _tmpFile.setFileName(propagator()->fullLocalPath(tmpFileName));
_resumeStart = _tmpFile.size();
if (_resumeStart > 0 && _resumeStart == _item->_size) {
if (_item->_directDownloadUrl.isEmpty()) {
// Normal job, download from oC instance
_job = new GETFileJob(propagator()->account(),
- propagator()->_remoteFolder + (_isEncrypted ? _item->_encryptedFileName : _item->_file),
+ propagator()->fullRemotePath(_isEncrypted ? _item->_encryptedFileName : _item->_file),
&_tmpFile, headers, expectedEtagForResume, _resumeStart, this);
} else {
// We were provided a direct URL, use that one
void PropagateDownloadFile::deleteExistingFolder()
{
- QString existingDir = propagator()->getFilePath(_item->_file);
+ QString existingDir = propagator()->fullLocalPath(_item->_file);
if (!QFileInfo(existingDir).isDir()) {
return;
}
void PropagateDownloadFile::downloadFinished()
{
- QString fn = propagator()->getFilePath(_item->_file);
+ ASSERT(!_tmpFile.isOpen());
+ QString fn = propagator()->fullLocalPath(_item->_file);
// In case of file name clash, report an error
// This can happen if another parallel download saved a clashing file.
// entry, remove it transfer its old pin state.
if (_item->_type == ItemTypeVirtualFileDownload) {
QString virtualFile = _item->_file + vfs->fileSuffix();
- auto fn = propagator()->getFilePath(virtualFile);
+ auto fn = propagator()->fullLocalPath(virtualFile);
qCDebug(lcPropagateDownload) << "Download of previous virtual file finished" << fn;
QFile::remove(fn);
propagator()->_journal->deleteFileRecord(virtualFile);
void PropagateDownloadFile::updateMetadata(bool isConflict)
{
- QString fn = propagator()->getFilePath(_item->_file);
+ QString fn = propagator()->fullLocalPath(_item->_file);
if (!propagator()->updateMetadata(*_item)) {
done(SyncFileItem::FatalError, tr("Error writing metadata to the database"));
// handle the special recall file
if (!_item->_remotePerm.hasPermission(RemotePermissions::IsShared)
&& (_item->_file == QLatin1String(".sys.admin#recall#")
- || _item->_file.endsWith("/.sys.admin#recall#"))) {
- handleRecallFile(fn, propagator()->_localDir, *propagator()->_journal);
+ || _item->_file.endsWith(QLatin1String("/.sys.admin#recall#")))) {
+ handleRecallFile(fn, propagator()->localPath(), *propagator()->_journal);
}
qint64 duration = _stopwatch.elapsed();
void PropagateDownloadEncrypted::checkFolderEncryptedStatus()
{
const auto rootPath = [=]() {
- const auto result = _propagator->_remoteFolder;
+ const auto result = _propagator->remotePath();
if (result.startsWith('/')) {
return result.mid(1);
} else {
qCDebug(lcPropagateDownloadEncrypted) << "Content Checksum Computed starting decryption" << tmpFileName;
tmpFile.close();
- QFile _tmpOutput(_propagator->getFilePath(tmpFileName), this);
+ QFile _tmpOutput(_propagator->fullLocalPath(tmpFileName), this);
EncryptionHelper::fileDecryption(_encryptedInfo.encryptionKey,
_encryptedInfo.initializationVector,
&tmpFile,
qCInfo(lcPropagateRemoteDelete) << "Deleting file, local" << _item->_file << "remote" << filename;
_job = new DeleteJob(propagator()->account(),
- propagator()->_remoteFolder + filename,
- this);
+ propagator()->fullRemotePath(_item->_file),
+ this);
if (_deleteEncryptedHelper && !_deleteEncryptedHelper->folderToken().isEmpty()) {
_job->setFolderToken(_deleteEncryptedHelper->folderToken());
}
// Encrypt File!
FolderMetadata metadata(_propagator->account(), json.toJson(QJsonDocument::Compact), statusCode);
- QFileInfo info(_propagator->_localDir + QDir::separator() + _item->_file);
+ QFileInfo info(_propagator->fullLocalPath(_item->_file));
const QString fileName = info.fileName();
// Find existing metadata for this file
, _parallelism(FullParallelism)
{
const auto rootPath = [=]() {
- const auto result = propagator->_remoteFolder;
+ const auto result = propagator->remotePath();
if (result.startsWith('/')) {
return result.mid(1);
} else {
}
_job = new DeleteJob(propagator()->account(),
- propagator()->_remoteFolder + _item->_file,
+ propagator()->fullRemotePath(_item->_file),
this);
connect(static_cast<DeleteJob*>(_job.data()), &DeleteJob::finishedSignal,
this, &PropagateRemoteMkdir::slotMkdir);
qCDebug(lcPropagateRemoteMkdir) << _item->_file;
_job = new MkColJob(propagator()->account(),
- propagator()->_remoteFolder + _item->_file,
+ propagator()->fullRemotePath(_item->_file),
this);
connect(_job, SIGNAL(finished(QNetworkReply::NetworkError)), this, SLOT(slotMkcolJobFinished()));
_job->start();
qCDebug(lcPropagateRemoteMkdir) << filename;
auto job = new MkColJob(propagator()->account(),
- propagator()->_remoteFolder + filename,
+ propagator()->fullRemotePath(filename),
{{"e2e-token", _uploadEncryptedHelper->_folderToken }},
this);
connect(job, qOverload<QNetworkReply::NetworkError>(&MkColJob::finished),
void PropagateRemoteMkdir::slotMkdir()
{
const auto rootPath = [=]() {
- const auto result = propagator()->_remoteFolder;
+ const auto result = propagator()->remotePath();
if (result.startsWith('/')) {
return result.mid(1);
} else {
QString origin = propagator()->adjustRenamedPath(_item->_file);
qCDebug(lcPropagateRemoteMove) << origin << _item->_renameTarget;
- QString targetFile(propagator()->getFilePath(_item->_renameTarget));
+ QString targetFile(propagator()->fullLocalPath(_item->_renameTarget));
if (origin == _item->_renameTarget) {
// The parent has been renamed already so there is nothing more to do.
return;
}
- QString remoteSource = propagator()->_remoteFolder + origin;
- QString remoteDestination = QDir::cleanPath(propagator()->account()->davUrl().path() + propagator()->_remoteFolder + _item->_renameTarget);
+ QString remoteSource = propagator()->fullRemotePath(origin);
+ QString remoteDestination = QDir::cleanPath(propagator()->account()->davUrl().path() + propagator()->fullRemotePath(_item->_renameTarget));
auto &vfs = propagator()->syncOptions()._vfs;
auto itype = _item->_type;
folderTargetAlt.chop(suffix.size());
}
- QString localTarget = propagator()->getFilePath(folderTarget);
- QString localTargetAlt = propagator()->getFilePath(folderTargetAlt);
+ QString localTarget = propagator()->fullLocalPath(folderTarget);
+ QString localTargetAlt = propagator()->fullLocalPath(folderTargetAlt);
// If the expected target doesn't exist but a file with different hydration
// state does, rename the local file to bring it in line with what the discovery
, _uploadingEncrypted(false)
{
const auto rootPath = [=]() {
- const auto result = propagator->_remoteFolder;
+ const auto result = propagator->remotePath();
if (result.startsWith('/')) {
return result.mid(1);
} else {
void PropagateUploadFileCommon::start()
{
const auto rootPath = [=]() {
- const auto result = propagator()->_remoteFolder;
+ const auto result = propagator()->remotePath();
if (result.startsWith('/')) {
return result.mid(1);
} else {
_uploadingEncrypted = false;
_fileToUpload._file = _item->_file;
_fileToUpload._size = _item->_size;
- _fileToUpload._path = propagator()->getFilePath(_fileToUpload._file);
+ _fileToUpload._path = propagator()->fullLocalPath(_fileToUpload._file);
startUploadFile();
}
qDebug() << "Deleting the current";
auto job = new DeleteJob(propagator()->account(),
- propagator()->_remoteFolder + _fileToUpload._file,
+ propagator()->fullRemotePath(_fileToUpload._file),
this);
_jobs.append(job);
connect(job, &DeleteJob::finishedSignal, this, &PropagateUploadFileCommon::slotComputeContentChecksum);
return;
}
- const QString filePath = propagator()->getFilePath(_item->_file);
+ const QString filePath = propagator()->fullLocalPath(_item->_file);
// remember the modtime before checksumming to be able to detect a file
// change during the checksum calculation - This goes inside of the _item->_file
this, &PropagateUploadFileCommon::slotStartUpload);
connect(computeChecksum, &ComputeChecksum::done,
computeChecksum, &QObject::deleteLater);
- const QString filePath = propagator()->getFilePath(_item->_file);
+ const QString filePath = propagator()->fullLocalPath(_item->_file);
computeChecksum->start(filePath);
}
_item->_checksumHeader = _transmissionChecksumHeader;
}
- const QString fullFilePath = _fileToUpload._path;
- const QString originalFilePath = propagator()->getFilePath(_item->_file);
+ const QString fullFilePath = propagator()->fullLocalPath(_fileToUpload._file);
+ const QString originalFilePath = propagator()->fullLocalPath(_item->_file);
if (!FileSystem::fileExists(fullFilePath)) {
if (_uploadingEncrypted) {
void PropagateUploadFileCommon::startPollJob(const QString &path)
{
auto *job = new PollJob(propagator()->account(), path, _item,
- propagator()->_journal, propagator()->_localDir, this);
+ propagator()->_journal, propagator()->localPath(), this);
connect(job, &PollJob::finishedSignal, this, &PropagateUploadFileCommon::slotPollFinished);
SyncJournalDb::PollInfo info;
info._file = _item->_file;
void PropagateUploadEncrypted::start()
{
const auto rootPath = [=]() {
- const auto result = _propagator->_remoteFolder;
+ const auto result = _propagator->remotePath();
if (result.startsWith('/')) {
return result.mid(1);
} else {
// Encrypt File!
_metadata = new FolderMetadata(_propagator->account(), json.toJson(QJsonDocument::Compact), statusCode);
- QFileInfo info(_propagator->_localDir + QDir::separator() + _item->_file);
+ QFileInfo info(_propagator->fullLocalPath(_item->_file));
const QString fileName = info.fileName();
// Find existing metadata for this file
// Finish with a MOVE
// If we changed the file name, we must store the changed filename in the remote folder, not the original one.
QString destination = QDir::cleanPath(propagator()->account()->davUrl().path()
- + propagator()->_remoteFolder + _fileToUpload._file);
+ + propagator()->fullRemotePath(_fileToUpload._file));
auto headers = PropagateUploadFileCommon::headers();
// "If-Match applies to the source, but we are interested in comparing the etag of the destination
return;
}
- const QString fileName = _fileToUpload._path;
+ const QString fileName = propagator()->fullLocalPath(_fileToUpload._file);
auto device = std::make_unique<UploadDevice>(
fileName, _currentChunk, _currentChunkSize, &propagator()->_bandwidthManager);
if (!device->open(QIODevice::ReadOnly)) {
_finished = _sent == _item->_size;
// Check if the file still exists
- const QString fullFilePath(propagator()->getFilePath(_item->_file));
+ const QString fullFilePath(propagator()->fullLocalPath(_item->_file));
if (!FileSystem::fileExists(fullFilePath)) {
if (!_finished) {
abortWithError(SyncFileItem::SoftError, tr("The local file was removed during sync."));
qCDebug(lcPropagateUploadV1) << _chunkCount << isFinalChunk << chunkStart << currentChunkSize;
if (isFinalChunk && !_transmissionChecksumHeader.isEmpty()) {
- qCInfo(lcPropagateUploadV1) << propagator()->_remoteFolder + path << _transmissionChecksumHeader;
+ qCInfo(lcPropagateUploadV1) << propagator()->fullRemotePath(path) << _transmissionChecksumHeader;
headers[checkSumHeaderC] = _transmissionChecksumHeader;
}
- const QString fileName = _fileToUpload._path;
+ const QString fileName = propagator()->fullLocalPath(_fileToUpload._file);
auto device = std::make_unique<UploadDevice>(
fileName, chunkStart, currentChunkSize, &propagator()->_bandwidthManager);
if (!device->open(QIODevice::ReadOnly)) {
// job takes ownership of device via a QScopedPointer. Job deletes itself when finishing
auto devicePtr = device.get(); // for connections later
- auto *job = new PUTFileJob(propagator()->account(), propagator()->_remoteFolder + path, std::move(device), headers, _currentChunk, this);
+ auto *job = new PUTFileJob(propagator()->account(), propagator()->fullRemotePath(path), std::move(device), headers, _currentChunk, this);
_jobs.append(job);
connect(job, &PUTFileJob::finishedSignal, this, &PropagateUploadFileV1::slotPutFinished);
connect(job, &PUTFileJob::uploadProgress, this, &PropagateUploadFileV1::slotUploadProgress);
QByteArray etag = getEtagFromReply(job->reply());
_finished = etag.length() > 0;
- /* Check if the file still exists,
- * but we could be operating in a temporary file, so check both if
- * the file to upload is different than the file on disk
- */
- const QString fullFilePath(propagator()->getFilePath(_item->_file));
+ // Check if the file still exists
+ const QString fullFilePath(propagator()->fullLocalPath(_item->_file));
if (!FileSystem::fileExists(fullFilePath)) {
if (!_finished) {
abortWithError(SyncFileItem::SoftError, tr("The local file was removed during sync."));
*/
bool PropagateLocalRemove::removeRecursively(const QString &path)
{
- auto folderDir = propagator()->_localDir;
- QString absolute = folderDir + _item->_file + path;
+ QString absolute = propagator()->fullLocalPath(_item->_file + path);
QStringList errors;
QList<QPair<QString, bool>> deleted;
bool success = FileSystem::removeRecursively(
// Do it while avoiding redundant delete calls to the journal.
QString deletedDir;
foreach (const auto &it, deleted) {
- if (!it.first.startsWith(folderDir))
+ if (!it.first.startsWith(propagator()->localPath()))
continue;
if (!deletedDir.isEmpty() && it.first.startsWith(deletedDir))
continue;
if (it.second) {
deletedDir = it.first;
}
- propagator()->_journal->deleteFileRecord(it.first.mid(folderDir.size()), it.second);
+ propagator()->_journal->deleteFileRecord(it.first.mid(propagator()->localPath().size()), it.second);
}
_error = errors.join(", ");
if (propagator()->_abortRequested)
return;
- QString filename = propagator()->_localDir + _item->_file;
+ const QString filename = propagator()->fullLocalPath(_item->_file);
qCDebug(lcPropagateLocalRemove) << filename;
if (propagator()->localFileNameClash(_item->_file)) {
return;
const auto rootPath = [=]() {
- const auto result = propagator()->_remoteFolder;
+ const auto result = propagator()->remotePath();
if (result.startsWith('/')) {
return result.mid(1);
} else {
void PropagateLocalMkdir::startLocalMkdir()
{
- QDir newDir(propagator()->getFilePath(_item->_file));
+ QDir newDir(propagator()->fullLocalPath(_item->_file));
QString newDirStr = QDir::toNativeSeparators(newDir.path());
// When turning something that used to be a file into a directory
return;
}
emit propagator()->touchedFile(newDirStr);
- QDir localDir(propagator()->_localDir);
+ QDir localDir(propagator()->localPath());
if (!localDir.mkpath(_item->_file)) {
done(SyncFileItem::NormalError, tr("could not create folder %1").arg(newDirStr));
return;
if (propagator()->_abortRequested)
return;
- QString existingFile = propagator()->getFilePath(propagator()->adjustRenamedPath(_item->_file));
- QString targetFile = propagator()->getFilePath(_item->_renameTarget);
+ QString existingFile = propagator()->fullLocalPath(propagator()->adjustRenamedPath(_item->_file));
+ QString targetFile = propagator()->fullLocalPath(_item->_renameTarget);
// if the file is a file underneath a moved dir, the _item->file is equal
// to _item->renameTarget and the file is not moved as a result.
const QVector<SyncJournalDb::DownloadInfo> deleted_infos =
_journal->getAndDeleteStaleDownloadInfos(download_file_paths);
foreach (const SyncJournalDb::DownloadInfo &deleted_info, deleted_infos) {
- const QString tmppath = _propagator->getFilePath(deleted_info._tmpfile);
+ const QString tmppath = _propagator->fullLocalPath(deleted_info._tmpfile);
qCInfo(lcEngine) << "Deleting stale temporary file: " << tmppath;
FileSystem::remove(tmppath);
}
// missing ones.
const auto conflictRecordPaths = _journal->conflictRecordPaths();
for (const auto &path : conflictRecordPaths) {
- auto fsPath = _propagator->getFilePath(QString::fromUtf8(path));
+ auto fsPath = _propagator->fullLocalPath(QString::fromUtf8(path));
if (!QFileInfo(fsPath).exists()) {
_journal->deleteConflictRecord(path);
}