Skip to content

Commit 254388d

Browse files
authored
Merge pull request #4437 from owncloud/feature/improve_removed_from_original_folder_option_auto_upload
[FEATURE REQUEST] Improve the `removed from original folder` option in Auto Uploads
2 parents dd25e8b + 048fd74 commit 254388d

File tree

21 files changed

+1311
-38
lines changed

21 files changed

+1311
-38
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ ownCloud admins and users.
3333
## Summary
3434

3535
* Bugfix - Shares in non-root are updated correctly: [#4432](https://github.com/owncloud/android/issues/4432)
36+
* Enhancement - Improved "Remove from original folder" option in auto-upload: [#4357](https://github.com/owncloud/android/issues/4357)
3637
* Enhancement - Improved accessibility of information and relationships: [#4362](https://github.com/owncloud/android/issues/4362)
3738
* Enhancement - Changed the color of some elements to improve accessibility: [#4364](https://github.com/owncloud/android/issues/4364)
3839
* Enhancement - Improved SearchView accessibility: [#4365](https://github.com/owncloud/android/issues/4365)
@@ -48,6 +49,14 @@ ownCloud admins and users.
4849
https://github.com/owncloud/android/issues/4432
4950
https://github.com/owncloud/android/pull/4435
5051

52+
* Enhancement - Improved "Remove from original folder" option in auto-upload: [#4357](https://github.com/owncloud/android/issues/4357)
53+
54+
The file will be deleted locally after it has been uploaded to the server,
55+
avoiding the loss of the file if an error happens during the upload.
56+
57+
https://github.com/owncloud/android/issues/4357
58+
https://github.com/owncloud/android/pull/4437
59+
5160
* Enhancement - Improved accessibility of information and relationships: [#4362](https://github.com/owncloud/android/issues/4362)
5261

5362
Headings have been added to the following views: Share, Edit/Create Share Link,

changelog/unreleased/4437

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
Enhancement: Improved "Remove from original folder" option in auto-upload
2+
3+
The file will be deleted locally after it has been uploaded to the server, avoiding the loss of the file if an error happens during the upload.
4+
5+
https://github.com/owncloud/android/issues/4357
6+
https://github.com/owncloud/android/pull/4437

owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/RetryUploadFromSystemUseCase.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ package com.owncloud.android.usecases.transfers.uploads
2525
import androidx.work.WorkInfo
2626
import androidx.work.WorkManager
2727
import com.owncloud.android.domain.BaseUseCase
28-
import com.owncloud.android.domain.camerauploads.model.UploadBehavior
2928
import com.owncloud.android.domain.transfers.TransferRepository
3029
import com.owncloud.android.extensions.getWorkInfoByTags
3130
import com.owncloud.android.workers.UploadFileFromFileSystemWorker
@@ -58,8 +57,9 @@ class RetryUploadFromSystemUseCase(
5857
accountName = uploadToRetry.accountName,
5958
localPath = uploadToRetry.localPath,
6059
lastModifiedInSeconds = (uploadToRetry.transferEndTimestamp?.div(1000)).toString(),
61-
behavior = UploadBehavior.MOVE.name,
60+
behavior = uploadToRetry.localBehaviour.name,
6261
uploadPath = uploadToRetry.remotePath,
62+
sourcePath = uploadToRetry.sourcePath,
6363
uploadIdInStorageManager = params.uploadIdInStorageManager
6464
)
6565
)

owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/UploadFileFromContentUriUseCase.kt

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
*
44
* @author Abel García de Prada
55
* @author Juan Carlos Garrote Gascón
6+
* @author Aitor Ballesteros Pavón
67
*
7-
* Copyright (C) 2022 ownCloud GmbH.
8+
* Copyright (C) 2024 ownCloud GmbH.
89
* <p>
910
* This program is free software: you can redistribute it and/or modify
1011
* it under the terms of the GNU General Public License version 2,
@@ -28,6 +29,8 @@ import androidx.work.OneTimeWorkRequestBuilder
2829
import androidx.work.WorkManager
2930
import androidx.work.workDataOf
3031
import com.owncloud.android.domain.BaseUseCase
32+
import com.owncloud.android.domain.camerauploads.model.UploadBehavior
33+
import com.owncloud.android.workers.RemoveSourceFileWorker
3134
import com.owncloud.android.workers.UploadFileFromContentUriWorker
3235
import timber.log.Timber
3336

@@ -36,14 +39,17 @@ class UploadFileFromContentUriUseCase(
3639
) : BaseUseCase<Unit, UploadFileFromContentUriUseCase.Params>() {
3740

3841
override fun run(params: Params) {
39-
val inputData = workDataOf(
42+
val inputDataUploadFileFromContentUriWorker = workDataOf(
4043
UploadFileFromContentUriWorker.KEY_PARAM_ACCOUNT_NAME to params.accountName,
4144
UploadFileFromContentUriWorker.KEY_PARAM_BEHAVIOR to params.behavior,
4245
UploadFileFromContentUriWorker.KEY_PARAM_CONTENT_URI to params.contentUri.toString(),
4346
UploadFileFromContentUriWorker.KEY_PARAM_LAST_MODIFIED to params.lastModifiedInSeconds,
4447
UploadFileFromContentUriWorker.KEY_PARAM_UPLOAD_PATH to params.uploadPath,
4548
UploadFileFromContentUriWorker.KEY_PARAM_UPLOAD_ID to params.uploadIdInStorageManager
4649
)
50+
val inputDataRemoveSourceFileWorker = workDataOf(
51+
UploadFileFromContentUriWorker.KEY_PARAM_CONTENT_URI to params.contentUri.toString(),
52+
)
4753

4854
val networkRequired = if (params.wifiOnly) NetworkType.UNMETERED else NetworkType.CONNECTED
4955
val constraints = Constraints.Builder()
@@ -52,13 +58,24 @@ class UploadFileFromContentUriUseCase(
5258
.build()
5359

5460
val uploadFileFromContentUriWorker = OneTimeWorkRequestBuilder<UploadFileFromContentUriWorker>()
55-
.setInputData(inputData)
61+
.setInputData(inputDataUploadFileFromContentUriWorker)
5662
.setConstraints(constraints)
5763
.addTag(params.accountName)
5864
.addTag(params.uploadIdInStorageManager.toString())
5965
.build()
6066

61-
workManager.enqueue(uploadFileFromContentUriWorker)
67+
val behavior = UploadBehavior.fromString(params.behavior)
68+
if (behavior == UploadBehavior.MOVE) {
69+
val removeSourceFileWorker = OneTimeWorkRequestBuilder<RemoveSourceFileWorker>()
70+
.setInputData(inputDataRemoveSourceFileWorker)
71+
.build()
72+
workManager.beginWith(uploadFileFromContentUriWorker)
73+
.then(removeSourceFileWorker) // File is already uploaded, so the original one can be removed if the behaviour is MOVE
74+
.enqueue()
75+
} else {
76+
workManager.enqueue(uploadFileFromContentUriWorker)
77+
}
78+
6279
Timber.i("Plain upload of ${params.contentUri.path} has been enqueued.")
6380
}
6481

owncloudApp/src/main/java/com/owncloud/android/usecases/transfers/uploads/UploadFileFromSystemUseCase.kt

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,9 @@
22
* ownCloud Android client application
33
*
44
* @author Juan Carlos Garrote Gascón
5+
* @author Aitor Ballesteros Pavón
56
*
6-
* Copyright (C) 2022 ownCloud GmbH.
7+
* Copyright (C) 2024 ownCloud GmbH.
78
* <p>
89
* This program is free software: you can redistribute it and/or modify
910
* it under the terms of the GNU General Public License version 2,
@@ -26,6 +27,9 @@ import androidx.work.OneTimeWorkRequestBuilder
2627
import androidx.work.WorkManager
2728
import androidx.work.workDataOf
2829
import com.owncloud.android.domain.BaseUseCase
30+
import com.owncloud.android.domain.camerauploads.model.UploadBehavior
31+
import com.owncloud.android.workers.RemoveSourceFileWorker
32+
import com.owncloud.android.workers.UploadFileFromContentUriWorker
2933
import com.owncloud.android.workers.UploadFileFromFileSystemWorker
3034
import timber.log.Timber
3135

@@ -34,27 +38,41 @@ class UploadFileFromSystemUseCase(
3438
) : BaseUseCase<Unit, UploadFileFromSystemUseCase.Params>() {
3539

3640
override fun run(params: Params) {
37-
val inputData = workDataOf(
41+
val inputDataUploadFileFromFileSystemWorker = workDataOf(
3842
UploadFileFromFileSystemWorker.KEY_PARAM_ACCOUNT_NAME to params.accountName,
3943
UploadFileFromFileSystemWorker.KEY_PARAM_BEHAVIOR to params.behavior,
4044
UploadFileFromFileSystemWorker.KEY_PARAM_LOCAL_PATH to params.localPath,
4145
UploadFileFromFileSystemWorker.KEY_PARAM_LAST_MODIFIED to params.lastModifiedInSeconds,
4246
UploadFileFromFileSystemWorker.KEY_PARAM_UPLOAD_PATH to params.uploadPath,
4347
UploadFileFromFileSystemWorker.KEY_PARAM_UPLOAD_ID to params.uploadIdInStorageManager
4448
)
49+
val inputDataRemoveSourceFileWorker = workDataOf(
50+
UploadFileFromContentUriWorker.KEY_PARAM_CONTENT_URI to params.sourcePath,
51+
)
4552

4653
val constraints = Constraints.Builder()
4754
.setRequiredNetworkType(NetworkType.CONNECTED)
4855
.build()
4956

5057
val uploadFileFromSystemWorker = OneTimeWorkRequestBuilder<UploadFileFromFileSystemWorker>()
51-
.setInputData(inputData)
58+
.setInputData(inputDataUploadFileFromFileSystemWorker)
5259
.setConstraints(constraints)
5360
.addTag(params.accountName)
5461
.addTag(params.uploadIdInStorageManager.toString())
5562
.build()
5663

57-
workManager.enqueue(uploadFileFromSystemWorker)
64+
val behavior = UploadBehavior.fromString(params.behavior)
65+
if (behavior == UploadBehavior.MOVE) {
66+
val removeSourceFileWorker = OneTimeWorkRequestBuilder<RemoveSourceFileWorker>()
67+
.setInputData(inputDataRemoveSourceFileWorker)
68+
.build()
69+
workManager.beginWith(uploadFileFromSystemWorker)
70+
.then(removeSourceFileWorker) // File is already uploaded, so the original one can be removed if the behaviour is MOVE
71+
.enqueue()
72+
} else {
73+
workManager.enqueue(uploadFileFromSystemWorker)
74+
}
75+
5876
Timber.i("Plain upload of ${params.localPath} has been enqueued.")
5977
}
6078

@@ -65,5 +83,6 @@ class UploadFileFromSystemUseCase(
6583
val behavior: String,
6684
val uploadPath: String,
6785
val uploadIdInStorageManager: Long,
86+
val sourcePath: String? = null,
6887
)
6988
}

owncloudApp/src/main/java/com/owncloud/android/workers/DownloadFileWorker.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ class DownloadFileWorker(
7676
private val workerParameters: WorkerParameters
7777
) : CoroutineWorker(
7878
appContext,
79-
workerParameters
79+
workerParameters,
8080
), KoinComponent, OnDatatransferProgressListener {
8181

8282
private val getFileByIdUseCase: GetFileByIdUseCase by inject()
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/**
2+
* ownCloud Android client application
3+
*
4+
* @author Aitor Ballesteros Pavón
5+
*
6+
* Copyright (C) 2024 ownCloud GmbH.
7+
*
8+
* This program is free software: you can redistribute it and/or modify
9+
* it under the terms of the GNU General Public License version 2,
10+
* as published by the Free Software Foundation.
11+
*
12+
* This program is distributed in the hope that it will be useful,
13+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15+
* GNU General Public License for more details.
16+
*
17+
* You should have received a copy of the GNU General Public License
18+
* along with this program. If not, see <http://www.gnu.org/licenses/>.
19+
*/
20+
21+
package com.owncloud.android.workers
22+
23+
import android.content.Context
24+
import android.net.Uri
25+
import androidx.core.net.toUri
26+
import androidx.documentfile.provider.DocumentFile
27+
import androidx.work.CoroutineWorker
28+
import androidx.work.WorkerParameters
29+
import com.owncloud.android.workers.UploadFileFromContentUriWorker.Companion.KEY_PARAM_CONTENT_URI
30+
import org.koin.core.component.KoinComponent
31+
import timber.log.Timber
32+
33+
class RemoveSourceFileWorker(
34+
private val appContext: Context,
35+
private val workerParameters: WorkerParameters
36+
) : CoroutineWorker(
37+
appContext,
38+
workerParameters
39+
), KoinComponent {
40+
41+
private lateinit var contentUri: Uri
42+
43+
override suspend fun doWork(): Result {
44+
if (!areParametersValid()) return Result.failure()
45+
return try {
46+
val documentFile = DocumentFile.fromSingleUri(appContext, contentUri)
47+
documentFile?.delete()
48+
Result.success()
49+
} catch (throwable: Throwable) {
50+
Timber.e(throwable)
51+
Result.failure()
52+
}
53+
}
54+
55+
private fun areParametersValid(): Boolean {
56+
val paramContentUri = workerParameters.inputData.getString(KEY_PARAM_CONTENT_URI)
57+
58+
contentUri = paramContentUri?.toUri() ?: return false
59+
60+
return true
61+
}
62+
}

owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromContentUriWorker.kt

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@
33
*
44
* @author Abel García de Prada
55
* @author Juan Carlos Garrote Gascón
6+
* @author Aitor Ballesteros Pavón
67
*
7-
* Copyright (C) 2023 ownCloud GmbH.
8+
* Copyright (C) 2024 ownCloud GmbH.
89
*
910
* This program is free software: you can redistribute it and/or modify
1011
* it under the terms of the GNU General Public License version 2,
@@ -30,7 +31,6 @@ import androidx.work.CoroutineWorker
3031
import androidx.work.WorkerParameters
3132
import androidx.work.workDataOf
3233
import com.owncloud.android.R
33-
import com.owncloud.android.presentation.authentication.AccountUtils
3434
import com.owncloud.android.data.executeRemoteOperation
3535
import com.owncloud.android.data.providers.LocalStorageProvider
3636
import com.owncloud.android.domain.camerauploads.model.UploadBehavior
@@ -57,6 +57,7 @@ import com.owncloud.android.lib.resources.files.UploadFileFromFileSystemOperatio
5757
import com.owncloud.android.lib.resources.files.chunks.ChunkedUploadFromFileSystemOperation
5858
import com.owncloud.android.lib.resources.files.chunks.ChunkedUploadFromFileSystemOperation.Companion.CHUNK_SIZE
5959
import com.owncloud.android.lib.resources.files.services.implementation.OCChunkService
60+
import com.owncloud.android.presentation.authentication.AccountUtils
6061
import com.owncloud.android.utils.NotificationUtils
6162
import com.owncloud.android.utils.RemoteFileUtils.Companion.getAvailableRemotePath
6263
import com.owncloud.android.utils.SecurityUtils
@@ -194,17 +195,8 @@ class UploadFileFromContentUriWorker(
194195
inputStream?.close()
195196
outputStream.close()
196197

198+
transferRepository.updateTransferSourcePath(uploadIdInStorageManager, contentUri.toString())
197199
transferRepository.updateTransferLocalPath(uploadIdInStorageManager, cachePath)
198-
199-
// File is already in cache, so the original one can be removed if the behaviour is MOVE
200-
if (behavior == UploadBehavior.MOVE) {
201-
removeLocalFile()
202-
}
203-
}
204-
205-
private fun removeLocalFile() {
206-
val documentFile = DocumentFile.fromSingleUri(appContext, contentUri)
207-
documentFile?.delete()
208200
}
209201

210202
private fun getClientForThisUpload(): OwnCloudClient =

owncloudApp/src/main/java/com/owncloud/android/workers/UploadFileFromFileSystemWorker.kt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import androidx.work.CoroutineWorker
2727
import androidx.work.WorkerParameters
2828
import androidx.work.workDataOf
2929
import com.owncloud.android.R
30-
import com.owncloud.android.presentation.authentication.AccountUtils
3130
import com.owncloud.android.data.executeRemoteOperation
3231
import com.owncloud.android.domain.camerauploads.model.UploadBehavior
3332
import com.owncloud.android.domain.capabilities.usecases.GetStoredCapabilitiesUseCase
@@ -55,6 +54,7 @@ import com.owncloud.android.lib.resources.files.UploadFileFromFileSystemOperatio
5554
import com.owncloud.android.lib.resources.files.chunks.ChunkedUploadFromFileSystemOperation
5655
import com.owncloud.android.lib.resources.files.chunks.ChunkedUploadFromFileSystemOperation.Companion.CHUNK_SIZE
5756
import com.owncloud.android.lib.resources.files.services.implementation.OCChunkService
57+
import com.owncloud.android.presentation.authentication.AccountUtils
5858
import com.owncloud.android.utils.NotificationUtils
5959
import com.owncloud.android.utils.RemoteFileUtils.Companion.getAvailableRemotePath
6060
import com.owncloud.android.utils.SecurityUtils
@@ -250,8 +250,8 @@ class UploadFileFromFileSystemWorker(
250250

251251
val result = executeRemoteOperation { uploadFileOperation.execute(client) }
252252

253-
if (result == Unit && behavior == UploadBehavior.MOVE) {
254-
removeLocalFile()
253+
if (result == Unit) {
254+
removeLocalFile() // Removed file from tmp folder
255255
}
256256
}
257257

@@ -288,8 +288,8 @@ class UploadFileFromFileSystemWorker(
288288
fileLength = fileSize
289289
)
290290

291-
// Step 4: Remove local file after uploading
292-
if (result == Unit && behavior == UploadBehavior.MOVE) {
291+
// Step 4: Remove tmp file folder after uploading
292+
if (result == Unit) {
293293
removeLocalFile()
294294
}
295295
}

0 commit comments

Comments
 (0)