From 623461793c8e3fa6af56af60b732ec09133e7b4c Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 8 Jan 2025 14:54:39 +0800 Subject: [PATCH 1/2] Allow setting a different destination file name from local file name in chunked upload Using macOS File Provider APIs we rely on the system to provide us with a URL pointing the an item's local modified contents. This URL last path component is a UUID and does not represent the expected file name of the item. The current API of uploadChunk presents a problem because it assumes the local content file's filename is the same as what will eventually be uploaded to the server. This commit addresses the issue by allowing users of this function to provide a destination file name which will replace the provided local filename, if used. Signed-off-by: Claudio Cambra --- Sources/NextcloudKit/NextcloudKit+Upload.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Sources/NextcloudKit/NextcloudKit+Upload.swift b/Sources/NextcloudKit/NextcloudKit+Upload.swift index a8d3ffa7..d88659c2 100644 --- a/Sources/NextcloudKit/NextcloudKit+Upload.swift +++ b/Sources/NextcloudKit/NextcloudKit+Upload.swift @@ -97,6 +97,7 @@ public extension NextcloudKit { func uploadChunk(directory: String, fileName: String, + destinationFileName: String? = nil, date: Date?, creationDate: Date?, serverUrl: String, @@ -119,7 +120,7 @@ public extension NextcloudKit { } let fileNameLocalSize = self.nkCommonInstance.getFileSize(filePath: directory + "/" + fileName) let serverUrlChunkFolder = nkSession.urlBase + "/" + nkSession.dav + "/uploads/" + nkSession.userId + "/" + chunkFolder - let serverUrlFileName = nkSession.urlBase + "/" + nkSession.dav + "/files/" + nkSession.userId + self.nkCommonInstance.returnPathfromServerUrl(serverUrl, urlBase: nkSession.urlBase, userId: nkSession.userId) + "/" + fileName + let serverUrlFileName = nkSession.urlBase + "/" + nkSession.dav + "/files/" + nkSession.userId + self.nkCommonInstance.returnPathfromServerUrl(serverUrl, urlBase: nkSession.urlBase, userId: nkSession.userId) + "/" + (destinationFileName ?? fileName) if options.customHeader == nil { options.customHeader = [:] } From 8ee2799c6b12ced03ec308378e0299abab89d428 Mon Sep 17 00:00:00 2001 From: Claudio Cambra Date: Wed, 8 Jan 2025 18:47:53 +0800 Subject: [PATCH 2/2] Make file chunks output directory customisable Currently the chunking procedure produces file chunks within the directory of the input file. However, this fails in cases where the directory is read-only. This can be fixed by allowing the chunked files output directory to be changed Signed-off-by: Claudio Cambra --- Sources/NextcloudKit/NextcloudKit+Upload.swift | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/Sources/NextcloudKit/NextcloudKit+Upload.swift b/Sources/NextcloudKit/NextcloudKit+Upload.swift index d88659c2..6438f082 100644 --- a/Sources/NextcloudKit/NextcloudKit+Upload.swift +++ b/Sources/NextcloudKit/NextcloudKit+Upload.swift @@ -96,6 +96,7 @@ public extension NextcloudKit { /// - chunkSizeInMB: Size in MB of chunk func uploadChunk(directory: String, + fileChunksOutputDirectory: String? = nil, fileName: String, destinationFileName: String? = nil, date: Date?, @@ -176,7 +177,8 @@ public extension NextcloudKit { var uploadNKError = NKError() var uploadAFError: AFError? - self.nkCommonInstance.chunkedFile(inputDirectory: directory, outputDirectory: directory, fileName: fileName, chunkSize: chunkSize, filesChunk: filesChunk) { num in + let outputDirectory = fileChunksOutputDirectory ?? directory + self.nkCommonInstance.chunkedFile(inputDirectory: directory, outputDirectory: outputDirectory, fileName: fileName, chunkSize: chunkSize, filesChunk: filesChunk) { num in numChunks(num) } counterChunk: { counter in counterChunk(counter) @@ -191,7 +193,7 @@ public extension NextcloudKit { for fileChunk in filesChunk { let serverUrlFileName = serverUrlChunkFolder + "/" + fileChunk.fileName - let fileNameLocalPath = directory + "/" + fileChunk.fileName + let fileNameLocalPath = outputDirectory + "/" + fileChunk.fileName let fileSize = self.nkCommonInstance.getFileSize(filePath: fileNameLocalPath) if fileSize == 0 { // The file could not be sent