diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Extensions/Logger+Extensions.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Extensions/Logger+Extensions.swift index 960171034..64836328b 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Extensions/Logger+Extensions.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Extensions/Logger+Extensions.swift @@ -11,6 +11,7 @@ extension Logger { private static var subsystem = Bundle.main.bundleIdentifier! static let actionViewController = Logger(subsystem: subsystem, category: "actionViewController") + static let metadataProvider = Logger(subsystem: subsystem, category: "metadataProvider") static let shareCapabilities = Logger(subsystem: subsystem, category: "shareCapabilities") static let shareController = Logger(subsystem: subsystem, category: "shareController") static let shareeDataSource = Logger(subsystem: subsystem, category: "shareeDataSource") diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/MetadataProvider.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/MetadataProvider.swift new file mode 100644 index 000000000..890c32065 --- /dev/null +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/MetadataProvider.swift @@ -0,0 +1,45 @@ +// +// MetadataProvider.swift +// FileProviderUIExt +// +// Created by Claudio Cambra on 30/7/24. +// + +import Foundation +import NextcloudKit +import OSLog + +func fetchItemMetadata(itemRelativePath: String, kit: NextcloudKit) async -> NKFile? { + func slashlessPath(_ string: String) -> String { + var strCopy = string + if strCopy.hasPrefix("/") { + strCopy.removeFirst() + } + if strCopy.hasSuffix("/") { + strCopy.removeLast() + } + return strCopy + } + + let nkCommon = kit.nkCommonInstance + let urlBase = slashlessPath(nkCommon.urlBase) + let davSuffix = slashlessPath(nkCommon.dav) + let userId = nkCommon.userId + let itemRelPath = slashlessPath(itemRelativePath) + + let itemFullServerPath = "\(urlBase)/\(davSuffix)/files/\(userId)/\(itemRelPath)" + return await withCheckedContinuation { continuation in + kit.readFileOrFolder(serverUrlFileName: itemFullServerPath, depth: "0") { + account, files, data, error in + guard error == .success else { + Logger.metadataProvider.error( + "Error getting item metadata: \(error.errorDescription)" + ) + continuation.resume(returning: nil) + return + } + Logger.metadataProvider.info("Successfully retrieved item metadata") + continuation.resume(returning: files.first) + } + } +} diff --git a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift index f0d0baf99..826711f0c 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift +++ b/shell_integration/MacOSX/NextcloudIntegration/FileProviderUIExt/Sharing/ShareTableViewDataSource.swift @@ -66,7 +66,14 @@ class ShareTableViewDataSource: NSObject, NSTableViewDataSource, NSTableViewDele } func reload() async { - guard let itemURL = itemURL else { return } + guard let itemURL else { + presentError("No item URL, cannot reload data!") + return + } + guard let kit else { + presentError("NextcloudKit instance is unavailable, cannot reload data!") + return + } guard let itemIdentifier = await withCheckedContinuation({ (continuation: CheckedContinuation) -> Void in NSFileProviderManager.getIdentifierForUserVisibleFile( @@ -106,7 +113,7 @@ class ShareTableViewDataSource: NSObject, NSTableViewDataSource, NSTableViewDele presentError("Server does not support shares.") return } - itemMetadata = await fetchItemMetadata(itemRelativePath: serverPathString) + itemMetadata = await fetchItemMetadata(itemRelativePath: serverPathString, kit: kit) guard itemMetadata?.permissions.contains("R") == true else { presentError("This file cannot be shared.") return @@ -163,44 +170,6 @@ class ShareTableViewDataSource: NSObject, NSTableViewDataSource, NSTableViewDele } } - private func fetchItemMetadata(itemRelativePath: String) async -> NKFile? { - guard let kit = kit else { - presentError("Could not fetch item metadata as NextcloudKit instance is unavailable") - return nil - } - - func slashlessPath(_ string: String) -> String { - var strCopy = string - if strCopy.hasPrefix("/") { - strCopy.removeFirst() - } - if strCopy.hasSuffix("/") { - strCopy.removeLast() - } - return strCopy - } - - let nkCommon = kit.nkCommonInstance - let urlBase = slashlessPath(nkCommon.urlBase) - let davSuffix = slashlessPath(nkCommon.dav) - let userId = nkCommon.userId - let itemRelPath = slashlessPath(itemRelativePath) - - let itemFullServerPath = "\(urlBase)/\(davSuffix)/files/\(userId)/\(itemRelPath)" - return await withCheckedContinuation { continuation in - kit.readFileOrFolder(serverUrlFileName: itemFullServerPath, depth: "0") { - account, files, data, error in - guard error == .success else { - self.presentError("Error getting item metadata: \(error.errorDescription)") - continuation.resume(returning: nil) - return - } - Logger.sharesDataSource.info("Successfully retrieved item metadata") - continuation.resume(returning: files.first) - } - } - } - private func presentError(_ errorString: String) { Logger.sharesDataSource.error("\(errorString, privacy: .public)") Task { @MainActor in self.uiDelegate?.showError(errorString) } diff --git a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj index ff6aa0624..b2613dddd 100644 --- a/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj +++ b/shell_integration/MacOSX/NextcloudIntegration/NextcloudIntegration.xcodeproj/project.pbxproj @@ -28,6 +28,7 @@ 537BD67A2C58D67800446ED0 /* LockViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537BD6792C58D67800446ED0 /* LockViewController.swift */; }; 537BD67C2C58D7B700446ED0 /* LockViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 537BD67B2C58D7B700446ED0 /* LockViewController.xib */; }; 537BD6802C58F01B00446ED0 /* FileProviderCommunication.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537BD67F2C58F01B00446ED0 /* FileProviderCommunication.swift */; }; + 537BD6822C58F72E00446ED0 /* MetadataProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 537BD6812C58F72E00446ED0 /* MetadataProvider.swift */; }; 538E396A27F4765000FA63D5 /* UniformTypeIdentifiers.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 538E396927F4765000FA63D5 /* UniformTypeIdentifiers.framework */; }; 538E396D27F4765000FA63D5 /* FileProviderExtension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 538E396C27F4765000FA63D5 /* FileProviderExtension.swift */; }; 538E397627F4765000FA63D5 /* FileProviderExt.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 538E396727F4765000FA63D5 /* FileProviderExt.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; @@ -169,6 +170,7 @@ 537BD6792C58D67800446ED0 /* LockViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LockViewController.swift; sourceTree = ""; }; 537BD67B2C58D7B700446ED0 /* LockViewController.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = LockViewController.xib; sourceTree = ""; }; 537BD67F2C58F01B00446ED0 /* FileProviderCommunication.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderCommunication.swift; sourceTree = ""; }; + 537BD6812C58F72E00446ED0 /* MetadataProvider.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MetadataProvider.swift; sourceTree = ""; }; 538E396727F4765000FA63D5 /* FileProviderExt.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = FileProviderExt.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 538E396927F4765000FA63D5 /* UniformTypeIdentifiers.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UniformTypeIdentifiers.framework; path = System/Library/Frameworks/UniformTypeIdentifiers.framework; sourceTree = SDKROOT; }; 538E396C27F4765000FA63D5 /* FileProviderExtension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileProviderExtension.swift; sourceTree = ""; }; @@ -356,6 +358,7 @@ 537BD6772C58D0C400446ED0 /* Sharing */, 53B979802B84C81F002DA742 /* DocumentActionViewController.swift */, 537BD67F2C58F01B00446ED0 /* FileProviderCommunication.swift */, + 537BD6812C58F72E00446ED0 /* MetadataProvider.swift */, 53FE14572B8E3A7C006C4193 /* FileProviderUIExt.entitlements */, 53B979852B84C81F002DA742 /* Info.plist */, ); @@ -717,6 +720,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 537BD6822C58F72E00446ED0 /* MetadataProvider.swift in Sources */, 537630932B85F4B00026BFAB /* ShareViewController.swift in Sources */, 53FE14672B8F78B6006C4193 /* ShareOptionsView.swift in Sources */, 53651E462BBC0D9500ECAC29 /* ShareeSuggestionsDataSource.swift in Sources */,