Move remote sync stuff in FileProviderEnumerator to own file
authorClaudio Cambra <claudio.cambra@nextcloud.com>
Sat, 18 Mar 2023 12:41:31 +0000 (13:41 +0100)
committerClaudio Cambra <claudio.cambra@nextcloud.com>
Fri, 12 May 2023 05:29:55 +0000 (13:29 +0800)
Signed-off-by: Claudio Cambra <claudio.cambra@nextcloud.com>
shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator+RemoteSync.swift [new file with mode: 0644]
shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator.swift
shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj

diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator+RemoteSync.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderExt/FileProviderEnumerator+RemoteSync.swift
new file mode 100644 (file)
index 0000000..498882f
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * Copyright (C) 2023 by Claudio Cambra <claudio.cambra@nextcloud.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * for more details.
+ */
+
+import FileProvider
+import NextcloudKit
+import OSLog
+
+extension FileProviderEnumerator {
+    static func fullRecursiveScan(ncAccount: NextcloudAccount, ncKit: NextcloudKit, scanChangesOnly: Bool, completionHandler: @escaping(_ newMetadatas: [NextcloudItemMetadataTable], _ updatedMetadatas: [NextcloudItemMetadataTable], _ deletedMetadatas: [NextcloudItemMetadataTable]) -> Void) {
+
+        let rootContainerDirectoryMetadata = NextcloudItemMetadataTable()
+        rootContainerDirectoryMetadata.directory = true
+        rootContainerDirectoryMetadata.ocId = NSFileProviderItemIdentifier.rootContainer.rawValue
+
+        // Create a serial dispatch queue
+        let dispatchQueue = DispatchQueue(label: "recursiveChangeEnumerationQueue", qos: .background)
+
+        dispatchQueue.async {
+            let results = scanRecursively(rootContainerDirectoryMetadata, ncAccount: ncAccount, ncKit: ncKit, scanChangesOnly: scanChangesOnly)
+
+            DispatchQueue.main.async {
+                completionHandler(results.newMetadatas, results.updatedMetadatas, results.deletedMetadatas)
+            }
+        }
+    }
+
+    static func scanRecursively(_ directoryMetadata: NextcloudItemMetadataTable, ncAccount: NextcloudAccount, ncKit: NextcloudKit, scanChangesOnly: Bool) -> (metadatas: [NextcloudItemMetadataTable], newMetadatas: [NextcloudItemMetadataTable], updatedMetadatas: [NextcloudItemMetadataTable], deletedMetadatas: [NextcloudItemMetadataTable]) {
+
+        assert(directoryMetadata.directory, "Can only recursively scan a directory.")
+
+        var allMetadatas: [NextcloudItemMetadataTable] = []
+        var allNewMetadatas: [NextcloudItemMetadataTable] = []
+        var allUpdatedMetadatas: [NextcloudItemMetadataTable] = []
+        var allDeletedMetadatas: [NextcloudItemMetadataTable] = []
+
+        let dbManager = NextcloudFilesDatabaseManager.shared
+        let dispatchGroup = DispatchGroup() // TODO: Maybe own thread?
+
+        dispatchGroup.enter()
+
+        let itemServerUrl = directoryMetadata.ocId == NSFileProviderItemIdentifier.rootContainer.rawValue ?
+            ncAccount.davFilesUrl : directoryMetadata.serverUrl + "/" + directoryMetadata.fileName
+
+        Logger.enumeration.debug("About to read: \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash))")
+
+        FileProviderEnumerator.readServerUrl(itemServerUrl, ncAccount: ncAccount, ncKit: ncKit, stopAtMatchingEtags: scanChangesOnly) { metadatas, newMetadatas, updatedMetadatas, deletedMetadatas, readError in
+
+            if readError != nil {
+                let nkReadError = NKError(error: readError!)
+
+                // Is the error is that we have found matching etags on this item, then ignore it
+                // if we are doing a full rescan
+                guard nkReadError.isNoChangesError && scanChangesOnly else {
+                    Logger.enumeration.error("Finishing enumeration of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) with \(readError!.localizedDescription, privacy: .public)")
+
+                    if nkReadError.isNotFoundError {
+                        Logger.enumeration.info("404 error means item no longer exists. Deleting metadata and reporting as deletion without error")
+
+                        if let deletedMetadatas = dbManager.deleteDirectoryAndSubdirectoriesMetadata(ocId: directoryMetadata.ocId) {
+                            allDeletedMetadatas += deletedMetadatas
+                        } else {
+                            Logger.enumeration.error("An error occurred while trying to delete directory and children not found in recursive scan")
+                        }
+                    } else if nkReadError.isNoChangesError { // All is well, just no changed etags
+                        Logger.enumeration.info("Error was to say no changed files -- not bad error. No need to check children.")
+                    }
+
+                    dispatchGroup.leave()
+                    return
+                }
+            }
+
+            Logger.enumeration.info("Finished reading serverUrl: \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
+
+            if let metadatas = metadatas {
+                allMetadatas += metadatas
+            } else {
+                Logger.enumeration.warning("WARNING: Nil metadatas received for reading of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
+            }
+
+            if let newMetadatas = newMetadatas {
+                allNewMetadatas += newMetadatas
+            } else {
+                Logger.enumeration.warning("WARNING: Nil new metadatas received for reading of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
+            }
+
+            if let updatedMetadatas = updatedMetadatas {
+                allUpdatedMetadatas += updatedMetadatas
+            } else {
+                Logger.enumeration.warning("WARNING: Nil updated metadatas received for reading of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
+            }
+
+            if let deletedMetadatas = deletedMetadatas {
+                allDeletedMetadatas += deletedMetadatas
+            } else {
+                Logger.enumeration.warning("WARNING: Nil deleted metadatas received for reading of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
+            }
+
+            dispatchGroup.leave()
+        }
+
+        dispatchGroup.wait()
+
+        var updatedDirectories: [NextcloudItemMetadataTable] = []
+        for updatedMetadata in allUpdatedMetadatas {
+            if updatedMetadata.directory {
+                updatedDirectories.append(updatedMetadata)
+            }
+        }
+
+        if updatedDirectories.isEmpty {
+            return (metadatas: allMetadatas, newMetadatas: allNewMetadatas, updatedMetadatas: allUpdatedMetadatas, deletedMetadatas: allDeletedMetadatas)
+        }
+
+        for childDirectory in updatedDirectories {
+            let childScanResult = scanRecursively(childDirectory, ncAccount: ncAccount, ncKit: ncKit, scanChangesOnly: scanChangesOnly)
+
+            allMetadatas += childScanResult.metadatas
+            allNewMetadatas += childScanResult.newMetadatas
+            allUpdatedMetadatas += childScanResult.updatedMetadatas
+            allDeletedMetadatas += childScanResult.deletedMetadatas
+        }
+
+        return (metadatas: allMetadatas, newMetadatas: allNewMetadatas, updatedMetadatas: allUpdatedMetadatas, deletedMetadatas: allDeletedMetadatas)
+    }
+
+    static func readServerUrl(_ serverUrl: String, ncAccount: NextcloudAccount, ncKit: NextcloudKit, stopAtMatchingEtags: Bool = false, completionHandler: @escaping (_ metadatas: [NextcloudItemMetadataTable]?, _ newMetadatas: [NextcloudItemMetadataTable]?, _ updatedMetadatas: [NextcloudItemMetadataTable]?, _ deletedMetadatas: [NextcloudItemMetadataTable]?, _ readError: Error?) -> Void) {
+        let dbManager = NextcloudFilesDatabaseManager.shared
+        let ncKitAccount = ncAccount.ncKitAccount
+
+        Logger.enumeration.debug("Starting to read serverUrl: \(serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash)) at depth 0. NCKit info: userId: \(ncKit.nkCommonInstance.user), password: \(ncKit.nkCommonInstance.password == "" ? "EMPTY PASSWORD" : "NOT EMPTY PASSWORD"), urlBase: \(ncKit.nkCommonInstance.urlBase), ncVersion: \(ncKit.nkCommonInstance.nextcloudVersion)")
+
+        ncKit.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", showHiddenFiles: true) { account, files, _, error in
+            guard error == .success else {
+                Logger.enumeration.error("0 depth readFileOrFolder of url: \(serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) did not complete successfully, received error: \(error.errorDescription, privacy: .public)")
+                completionHandler(nil, nil, nil, nil, error.error)
+                return
+            }
+
+            guard let receivedItem = files.first else {
+                Logger.enumeration.error("Received no items from readFileOrFolder of \(serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)), not much we can do...")
+                completionHandler(nil, nil, nil, nil, error.error)
+                return
+            }
+
+            guard receivedItem.directory else {
+                Logger.enumeration.debug("Read item is a file. Converting NKfile for serverUrl: \(serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
+                let itemMetadata = dbManager.convertNKFileToItemMetadata(receivedItem, account: ncKitAccount)
+                dbManager.addItemMetadata(itemMetadata) // TODO: Return some value when it is an update
+                completionHandler([itemMetadata], nil, nil, nil, error.error)
+                return
+            }
+
+            if stopAtMatchingEtags,
+               let directoryMetadata = dbManager.directoryMetadata(account: ncKitAccount, serverUrl: serverUrl) {
+
+                let directoryEtag = directoryMetadata.etag
+
+                guard directoryEtag == "" || directoryEtag != receivedItem.etag else {
+                    Logger.enumeration.debug("Read server url called with flag to stop enumerating at matching etags. Returning and providing soft error.")
+
+                    let description = "Fetched directory etag is same as that stored locally. Not fetching child items."
+                    let nkError = NKError(errorCode: NKError.noChangesErrorCode, errorDescription: description)
+
+                    let metadatas = dbManager.itemMetadatas(account: account, serverUrl: serverUrl)
+
+                    completionHandler(metadatas, nil, nil, nil, nkError.error)
+                    return
+                }
+            }
+
+            Logger.enumeration.debug("Starting to read serverUrl: \(serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash)) at depth 1")
+
+            ncKit.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: true) { account, files, _, error in
+                guard error == .success else {
+                    Logger.enumeration.error("1 depth readFileOrFolder of url: \(serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) did not complete successfully, received error: \(error.errorDescription, privacy: .public)")
+                    completionHandler(nil, nil, nil, nil, error.error)
+                    return
+                }
+
+                Logger.enumeration.debug("Starting async conversion of NKFiles for serverUrl: \(serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
+                DispatchQueue.main.async {
+                    dbManager.convertNKFilesFromDirectoryReadToItemMetadatas(files, account: ncKitAccount) { directoryMetadata, childDirectoriesMetadata, metadatas in
+
+                        // STORE DATA FOR CURRENTLY SCANNED DIRECTORY
+                        // We have now scanned this directory's contents, so update with etag in order to not check again if not needed
+                        // unless it's the root container
+                        if serverUrl != ncAccount.davFilesUrl {
+                            dbManager.addItemMetadata(directoryMetadata)
+                        }
+
+                        // Don't update the etags for folders as we haven't checked their contents.
+                        // When we do a recursive check, if we update the etags now, we will think
+                        // that our local copies are up to date -- instead, leave them as the old.
+                        // They will get updated when they are the subject of a readServerUrl call.
+                        // (See above)
+                        let changedMetadatas = dbManager.updateItemMetadatas(account: ncKitAccount, serverUrl: serverUrl, updatedMetadatas: metadatas, updateDirectoryEtags: false)
+
+                        completionHandler(metadatas, changedMetadatas.newMetadatas, changedMetadatas.updatedMetadatas, changedMetadatas.deletedMetadatas, nil)
+                    }
+                }
+            }
+        }
+    }
+}
index 49b83c07998a99f00b450a1d5336d61be07a96c6..f1d0507abb71e48c76076632215da2cfd92a82e6 100644 (file)
@@ -429,201 +429,4 @@ class FileProviderEnumerator: NSObject, NSFileProviderEnumerator {
         Logger.enumeration.info("Processed \(allUpdatedMetadatas.count) new or updated metadatas, \(allDeletedMetadatas.count) deleted metadatas.")
         observer.finishEnumeratingChanges(upTo: anchor, moreComing: false)
     }
-
-    private static func fullRecursiveScan(ncAccount: NextcloudAccount, ncKit: NextcloudKit, scanChangesOnly: Bool, completionHandler: @escaping(_ newMetadatas: [NextcloudItemMetadataTable], _ updatedMetadatas: [NextcloudItemMetadataTable], _ deletedMetadatas: [NextcloudItemMetadataTable]) -> Void) {
-
-        let rootContainerDirectoryMetadata = NextcloudItemMetadataTable()
-        rootContainerDirectoryMetadata.directory = true
-        rootContainerDirectoryMetadata.ocId = NSFileProviderItemIdentifier.rootContainer.rawValue
-
-        // Create a serial dispatch queue
-        let dispatchQueue = DispatchQueue(label: "recursiveChangeEnumerationQueue", qos: .background)
-
-        dispatchQueue.async {
-            let results = scanRecursively(rootContainerDirectoryMetadata, ncAccount: ncAccount, ncKit: ncKit, scanChangesOnly: scanChangesOnly)
-
-            DispatchQueue.main.async {
-                completionHandler(results.newMetadatas, results.updatedMetadatas, results.deletedMetadatas)
-            }
-        }
-    }
-
-    private static func scanRecursively(_ directoryMetadata: NextcloudItemMetadataTable, ncAccount: NextcloudAccount, ncKit: NextcloudKit, scanChangesOnly: Bool) -> (metadatas: [NextcloudItemMetadataTable], newMetadatas: [NextcloudItemMetadataTable], updatedMetadatas: [NextcloudItemMetadataTable], deletedMetadatas: [NextcloudItemMetadataTable]) {
-
-        assert(directoryMetadata.directory, "Can only recursively scan a directory.")
-
-        var allMetadatas: [NextcloudItemMetadataTable] = []
-        var allNewMetadatas: [NextcloudItemMetadataTable] = []
-        var allUpdatedMetadatas: [NextcloudItemMetadataTable] = []
-        var allDeletedMetadatas: [NextcloudItemMetadataTable] = []
-
-        let dbManager = NextcloudFilesDatabaseManager.shared
-        let dispatchGroup = DispatchGroup() // TODO: Maybe own thread?
-
-        dispatchGroup.enter()
-
-        let itemServerUrl = directoryMetadata.ocId == NSFileProviderItemIdentifier.rootContainer.rawValue ?
-            ncAccount.davFilesUrl : directoryMetadata.serverUrl + "/" + directoryMetadata.fileName
-
-        Logger.enumeration.debug("About to read: \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash))")
-
-        FileProviderEnumerator.readServerUrl(itemServerUrl, ncAccount: ncAccount, ncKit: ncKit, stopAtMatchingEtags: scanChangesOnly) { metadatas, newMetadatas, updatedMetadatas, deletedMetadatas, readError in
-
-            if readError != nil {
-                let nkReadError = NKError(error: readError!)
-
-                // Is the error is that we have found matching etags on this item, then ignore it
-                // if we are doing a full rescan
-                guard nkReadError.isNoChangesError && scanChangesOnly else {
-                    Logger.enumeration.error("Finishing enumeration of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) with \(readError!.localizedDescription, privacy: .public)")
-
-                    if nkReadError.isNotFoundError {
-                        Logger.enumeration.info("404 error means item no longer exists. Deleting metadata and reporting as deletion without error")
-
-                        if let deletedMetadatas = dbManager.deleteDirectoryAndSubdirectoriesMetadata(ocId: directoryMetadata.ocId) {
-                            allDeletedMetadatas += deletedMetadatas
-                        } else {
-                            Logger.enumeration.error("An error occurred while trying to delete directory and children not found in recursive scan")
-                        }
-                    } else if nkReadError.isNoChangesError { // All is well, just no changed etags
-                        Logger.enumeration.info("Error was to say no changed files -- not bad error. No need to check children.")
-                    }
-
-                    dispatchGroup.leave()
-                    return
-                }
-            }
-
-            Logger.enumeration.info("Finished reading serverUrl: \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
-
-            if let metadatas = metadatas {
-                allMetadatas += metadatas
-            } else {
-                Logger.enumeration.warning("WARNING: Nil metadatas received for reading of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
-            }
-
-            if let newMetadatas = newMetadatas {
-                allNewMetadatas += newMetadatas
-            } else {
-                Logger.enumeration.warning("WARNING: Nil new metadatas received for reading of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
-            }
-
-            if let updatedMetadatas = updatedMetadatas {
-                allUpdatedMetadatas += updatedMetadatas
-            } else {
-                Logger.enumeration.warning("WARNING: Nil updated metadatas received for reading of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
-            }
-
-            if let deletedMetadatas = deletedMetadatas {
-                allDeletedMetadatas += deletedMetadatas
-            } else {
-                Logger.enumeration.warning("WARNING: Nil deleted metadatas received for reading of changes at \(itemServerUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
-            }
-
-            dispatchGroup.leave()
-        }
-
-        dispatchGroup.wait()
-
-        var updatedDirectories: [NextcloudItemMetadataTable] = []
-        for updatedMetadata in allUpdatedMetadatas {
-            if updatedMetadata.directory {
-                updatedDirectories.append(updatedMetadata)
-            }
-        }
-
-        if updatedDirectories.isEmpty {
-            return (metadatas: allMetadatas, newMetadatas: allNewMetadatas, updatedMetadatas: allUpdatedMetadatas, deletedMetadatas: allDeletedMetadatas)
-        }
-
-        for childDirectory in updatedDirectories {
-            let childScanResult = scanRecursively(childDirectory, ncAccount: ncAccount, ncKit: ncKit, scanChangesOnly: scanChangesOnly)
-
-            allMetadatas += childScanResult.metadatas
-            allNewMetadatas += childScanResult.newMetadatas
-            allUpdatedMetadatas += childScanResult.updatedMetadatas
-            allDeletedMetadatas += childScanResult.deletedMetadatas
-        }
-
-        return (metadatas: allMetadatas, newMetadatas: allNewMetadatas, updatedMetadatas: allUpdatedMetadatas, deletedMetadatas: allDeletedMetadatas)
-    }
-
-    private static func readServerUrl(_ serverUrl: String, ncAccount: NextcloudAccount, ncKit: NextcloudKit, stopAtMatchingEtags: Bool = false, completionHandler: @escaping (_ metadatas: [NextcloudItemMetadataTable]?, _ newMetadatas: [NextcloudItemMetadataTable]?, _ updatedMetadatas: [NextcloudItemMetadataTable]?, _ deletedMetadatas: [NextcloudItemMetadataTable]?, _ readError: Error?) -> Void) {
-        let dbManager = NextcloudFilesDatabaseManager.shared
-        let ncKitAccount = ncAccount.ncKitAccount
-
-        Logger.enumeration.debug("Starting to read serverUrl: \(serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash)) at depth 0. NCKit info: userId: \(ncKit.nkCommonInstance.user), password: \(ncKit.nkCommonInstance.password == "" ? "EMPTY PASSWORD" : "NOT EMPTY PASSWORD"), urlBase: \(ncKit.nkCommonInstance.urlBase), ncVersion: \(ncKit.nkCommonInstance.nextcloudVersion)")
-
-        ncKit.readFileOrFolder(serverUrlFileName: serverUrl, depth: "0", showHiddenFiles: true) { account, files, _, error in
-            guard error == .success else {
-                Logger.enumeration.error("0 depth readFileOrFolder of url: \(serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) did not complete successfully, received error: \(error.errorDescription, privacy: .public)")
-                completionHandler(nil, nil, nil, nil, error.error)
-                return
-            }
-
-            guard let receivedItem = files.first else {
-                Logger.enumeration.error("Received no items from readFileOrFolder of \(serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)), not much we can do...")
-                completionHandler(nil, nil, nil, nil, error.error)
-                return
-            }
-
-            guard receivedItem.directory else {
-                Logger.enumeration.debug("Read item is a file. Converting NKfile for serverUrl: \(serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
-                let itemMetadata = dbManager.convertNKFileToItemMetadata(receivedItem, account: ncKitAccount)
-                dbManager.addItemMetadata(itemMetadata) // TODO: Return some value when it is an update
-                completionHandler([itemMetadata], nil, nil, nil, error.error)
-                return
-            }
-
-            if stopAtMatchingEtags,
-               let directoryMetadata = dbManager.directoryMetadata(account: ncKitAccount, serverUrl: serverUrl) {
-                
-                let directoryEtag = directoryMetadata.etag
-
-                guard directoryEtag == "" || directoryEtag != receivedItem.etag else {
-                    Logger.enumeration.debug("Read server url called with flag to stop enumerating at matching etags. Returning and providing soft error.")
-
-                    let description = "Fetched directory etag is same as that stored locally. Not fetching child items."
-                    let nkError = NKError(errorCode: NKError.noChangesErrorCode, errorDescription: description)
-
-                    let metadatas = dbManager.itemMetadatas(account: account, serverUrl: serverUrl)
-
-                    completionHandler(metadatas, nil, nil, nil, nkError.error)
-                    return
-                }
-            }
-
-            Logger.enumeration.debug("Starting to read serverUrl: \(serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash)) at depth 1")
-
-            ncKit.readFileOrFolder(serverUrlFileName: serverUrl, depth: "1", showHiddenFiles: true) { account, files, _, error in
-                guard error == .success else {
-                    Logger.enumeration.error("1 depth readFileOrFolder of url: \(serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) did not complete successfully, received error: \(error.errorDescription, privacy: .public)")
-                    completionHandler(nil, nil, nil, nil, error.error)
-                    return
-                }
-
-                Logger.enumeration.debug("Starting async conversion of NKFiles for serverUrl: \(serverUrl, privacy: OSLogPrivacy.auto(mask: .hash)) for user: \(ncAccount.ncKitAccount, privacy: OSLogPrivacy.auto(mask: .hash))")
-                DispatchQueue.main.async {
-                    dbManager.convertNKFilesFromDirectoryReadToItemMetadatas(files, account: ncKitAccount) { directoryMetadata, childDirectoriesMetadata, metadatas in
-
-                        // STORE DATA FOR CURRENTLY SCANNED DIRECTORY
-                        // We have now scanned this directory's contents, so update with etag in order to not check again if not needed
-                        // unless it's the root container
-                        if serverUrl != ncAccount.davFilesUrl {
-                            dbManager.addItemMetadata(directoryMetadata)
-                        }
-
-                        // Don't update the etags for folders as we haven't checked their contents.
-                        // When we do a recursive check, if we update the etags now, we will think
-                        // that our local copies are up to date -- instead, leave them as the old.
-                        // They will get updated when they are the subject of a readServerUrl call.
-                        // (See above)
-                        let changedMetadatas = dbManager.updateItemMetadatas(account: ncKitAccount, serverUrl: serverUrl, updatedMetadatas: metadatas, updateDirectoryEtags: false)
-
-                        completionHandler(metadatas, changedMetadatas.newMetadatas, changedMetadatas.updatedMetadatas, changedMetadatas.deletedMetadatas, nil)
-                    }
-                }
-            }
-        }
-    }
 }
index 93502d4bde6c590774065692be30cc7df1b6503b..17c5d351ad00d405b6208bc08693e1a0f67fca7e 100644 (file)
@@ -36,6 +36,7 @@
                53903D37295618A400D0B308 /* LineProcessor.h in Headers */ = {isa = PBXBuildFile; fileRef = 53903D36295618A400D0B308 /* LineProcessor.h */; settings = {ATTRIBUTES = (Public, ); }; };
                539158AC27BE71A900816F56 /* FinderSyncSocketLineProcessor.m in Sources */ = {isa = PBXBuildFile; fileRef = 539158AB27BE71A900816F56 /* FinderSyncSocketLineProcessor.m */; };
                53D056312970594F00988392 /* LocalFilesUtils.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53D056302970594F00988392 /* LocalFilesUtils.swift */; };
+               53ED472029C5E64200795DB1 /* FileProviderEnumerator+RemoteSync.swift in Sources */ = {isa = PBXBuildFile; fileRef = 53ED471F29C5E64200795DB1 /* FileProviderEnumerator+RemoteSync.swift */; };
                C2B573BA1B1CD91E00303B36 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = C2B573B91B1CD91E00303B36 /* main.m */; };
                C2B573D21B1CD94B00303B36 /* main.m in Resources */ = {isa = PBXBuildFile; fileRef = C2B573B91B1CD91E00303B36 /* main.m */; };
                C2B573DE1B1CD9CE00303B36 /* FinderSync.m in Sources */ = {isa = PBXBuildFile; fileRef = C2B573DD1B1CD9CE00303B36 /* FinderSync.m */; };
                539158B127BE891500816F56 /* LocalSocketClient.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LocalSocketClient.h; sourceTree = "<group>"; };
                539158B227BEC98A00816F56 /* LocalSocketClient.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = LocalSocketClient.m; sourceTree = "<group>"; };
                53D056302970594F00988392 /* LocalFilesUtils.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LocalFilesUtils.swift; sourceTree = "<group>"; };
+               53ED471F29C5E64200795DB1 /* FileProviderEnumerator+RemoteSync.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "FileProviderEnumerator+RemoteSync.swift"; sourceTree = "<group>"; };
                C2B573B11B1CD91E00303B36 /* desktopclient.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = desktopclient.app; sourceTree = BUILT_PRODUCTS_DIR; };
                C2B573B51B1CD91E00303B36 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
                C2B573B91B1CD91E00303B36 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
                                5318AD8F29BF406500CBB71C /* Database */,
                                5352E85929B7BFB4002CE85C /* Extensions */,
                                538E397027F4765000FA63D5 /* FileProviderEnumerator.swift */,
+                               53ED471F29C5E64200795DB1 /* FileProviderEnumerator+RemoteSync.swift */,
                                538E396C27F4765000FA63D5 /* FileProviderExtension.swift */,
                                538E396E27F4765000FA63D5 /* FileProviderItem.swift */,
                                5318AD9629BF493600CBB71C /* FileProviderMaterialisedEnumerationObserver.swift */,
                                536EFC36295E3C1100F4CB13 /* NextcloudAccount.swift in Sources */,
                                538E396D27F4765000FA63D5 /* FileProviderExtension.swift in Sources */,
                                536EFBF7295CF58100F4CB13 /* FileProviderSocketLineProcessor.swift in Sources */,
+                               53ED472029C5E64200795DB1 /* FileProviderEnumerator+RemoteSync.swift in Sources */,
                                5318AD9929BF58D000CBB71C /* NKError+Extensions.swift in Sources */,
                                5318AD9529BF438F00CBB71C /* NextcloudLocalFileMetadataTable.swift in Sources */,
                                535AE30E29C0A2CC0042A9BA /* Logger+Extensions.swift in Sources */,