Vfs: Enable propagating attributes on download
authorChristian Kamm <mail@ckamm.de>
Fri, 25 Jan 2019 10:11:28 +0000 (11:11 +0100)
committerKevin Ottens <kevin.ottens@nextcloud.com>
Tue, 15 Dec 2020 09:58:38 +0000 (10:58 +0100)
src/common/vfs.h
src/libsync/propagatedownload.cpp
src/libsync/vfs/suffix/vfs_suffix.cpp
src/libsync/vfs/suffix/vfs_suffix.h

index 35e7b86ace6af7cf2f6ef76d368936255612124a..179f0174d38deb0d7bcd268f9ec69c047f24a7bf 100644 (file)
@@ -146,8 +146,15 @@ public:
      *
      * Implementations must make sure that calling this function on a file that already
      * is a placeholder is acceptable.
+     *
+     * replacesFile can optionally contain a filesystem path to a placeholder that this
+     * new placeholder shall supersede, for rename-replace actions with new downloads,
+     * for example.
      */
-    virtual void convertToPlaceholder(const QString &filename, const SyncFileItem &item) = 0;
+    virtual void convertToPlaceholder(
+        const QString &filename,
+        const SyncFileItem &item,
+        const QString &replacesFile = QString()) = 0;
 
     /// Determine whether the file at the given absolute path is a dehydrated placeholder.
     virtual bool isDehydratedPlaceholder(const QString &filePath) = 0;
@@ -234,7 +241,7 @@ public:
 
     bool updateMetadata(const QString &, time_t, quint64, const QByteArray &, QString *) override { return true; }
     void createPlaceholder(const QString &, const SyncFileItem &) override {}
-    void convertToPlaceholder(const QString &, const SyncFileItem &) override {}
+    void convertToPlaceholder(const QString &, const SyncFileItem &, const QString &) override {}
 
     bool isDehydratedPlaceholder(const QString &) override { return false; }
     bool statTypeVirtualFile(csync_file_stat_t *, void *) override { return false; }
index fe0cceac72c2b61bb281ea145ba8ddd844fa8096..7ae067797d6a3f7527d043bd8e59325a692404a1 100644 (file)
@@ -421,6 +421,7 @@ void PropagateDownloadFile::startAfterIsEncryptedIsChecked()
     if (_item->_type == ItemTypeVirtualFileDehydration) {
         _item->_type = ItemTypeVirtualFile;
         // TODO: Could dehydrate without wiping the file entirely
+        // TODO: That would be useful as it could preserve file attributes (pins)
         auto fn = propagator()->getFilePath(_item->_file);
         qCDebug(lcPropagateDownload) << "dehydration: wiping base file" << fn;
         propagator()->_journal->deleteFileRecord(_item->_file);
@@ -987,6 +988,9 @@ void PropagateDownloadFile::downloadFinished()
     // Apply the remote permissions
     FileSystem::setFileReadOnlyWeak(_tmpFile.fileName(), !_item->_remotePerm.isNull() && !_item->_remotePerm.hasPermission(RemotePermissions::CanWrite));
 
+    // Make the file a hydrated placeholder if possible
+    propagator()->syncOptions()._vfs->convertToPlaceholder(_tmpFile.fileName(), *_item, fn);
+
     QString error;
     emit propagator()->touchedFile(fn);
     // The fileChanged() check is done above to generate better error messages.
@@ -1004,9 +1008,6 @@ void PropagateDownloadFile::downloadFinished()
         return;
     }
 
-    // Make the file a hydrated placeholder if possible
-    propagator()->syncOptions()._vfs->convertToPlaceholder(fn, *_item);
-
     FileSystem::setFileHidden(fn, false);
 
     // Maybe we downloaded a newer version of the file than we thought we would...
index 518decf70a938879f319a8d904d6cd89e6d15e00..711ee14ea2521ae07150fdf15777479316684bab 100644 (file)
@@ -70,7 +70,7 @@ void VfsSuffix::createPlaceholder(const QString &syncFolder, const SyncFileItem
     FileSystem::setModTime(fn, item._modtime);
 }
 
-void VfsSuffix::convertToPlaceholder(const QString &, const SyncFileItem &)
+void VfsSuffix::convertToPlaceholder(const QString &, const SyncFileItem &, const QString &)
 {
     // Nothing necessary
 }
index 9c2a2cc08b36134e87bf1cbd4f448d85f3e09d10..97d444ffc3d2f9048101b47926c9b21d5356a4ee 100644 (file)
@@ -40,7 +40,7 @@ public:
     bool updateMetadata(const QString &filePath, time_t modtime, quint64 size, const QByteArray &fileId, QString *error) override;
 
     void createPlaceholder(const QString &syncFolder, const SyncFileItem &item) override;
-    void convertToPlaceholder(const QString &filename, const SyncFileItem &item) override;
+    void convertToPlaceholder(const QString &filename, const SyncFileItem &item, const QString &) override;
 
     bool isDehydratedPlaceholder(const QString &filePath) override;
     bool statTypeVirtualFile(csync_file_stat_t *stat, void *stat_data) override;