From 16264db974b1f5d479163302219cd81671551b55 Mon Sep 17 00:00:00 2001 From: Jonas Mayer Date: Mon, 29 Jan 2024 14:54:23 +0100 Subject: [PATCH] Redo changes, manuel rebase Signed-off-by: Jonas Mayer --- .../client/jobs/upload/FileUploadHelper.kt | 23 +++++++++++++++++++ .../client/jobs/upload/FileUploadWorker.kt | 8 +++++++ .../datamodel/UploadsStorageManager.java | 21 +++++++++++++++++ .../com/owncloud/android/db/UploadResult.java | 5 +++- .../android/ui/adapter/UploadListAdapter.java | 20 +++++++++++++++- app/src/main/res/values/strings.xml | 1 + 6 files changed, 76 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadHelper.kt b/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadHelper.kt index 9c343e640c71..8c71a8b6677e 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadHelper.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadHelper.kt @@ -39,7 +39,11 @@ import com.owncloud.android.db.OCUpload import com.owncloud.android.db.UploadResult import com.owncloud.android.files.services.NameCollisionPolicy import com.owncloud.android.lib.common.network.OnDatatransferProgressListener +import com.owncloud.android.lib.common.operations.RemoteOperationResult import com.owncloud.android.lib.common.utils.Log_OC +import com.owncloud.android.lib.resources.files.ReadFileRemoteOperation +import com.owncloud.android.lib.resources.files.model.RemoteFile +import com.owncloud.android.utils.FileUtil import java.io.File import javax.inject.Inject @@ -255,6 +259,25 @@ class FileUploadHelper { } } + @Suppress("MagicNumber") + fun isSameFileOnRemote(user: User, localFile: File, remotePath: String, context: Context): Boolean { + // Compare remote file to local file + val localLastModifiedTimestamp = localFile.lastModified() / 1000 // remote file timestamp in milli not micro sec + val localCreationTimestamp = FileUtil.getCreationTimestamp(localFile) + val localSize: Long = localFile.length() + + val operation = ReadFileRemoteOperation(remotePath) + val result: RemoteOperationResult<*> = operation.execute(user, context) + if (result.isSuccess) { + val remoteFile = result.data[0] as RemoteFile + return remoteFile.size == localSize && + localCreationTimestamp != null && + localCreationTimestamp == remoteFile.creationTimestamp && + remoteFile.modifiedTimestamp == localLastModifiedTimestamp * 1000 + } + return false + } + class UploadNotificationActionReceiver : BroadcastReceiver() { override fun onReceive(context: Context, intent: Intent) { val accountName = intent.getStringExtra(FileUploadWorker.EXTRA_ACCOUNT_NAME) diff --git a/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt b/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt index 2397e3bed7bb..b00d3a37354f 100644 --- a/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt +++ b/app/src/main/java/com/nextcloud/client/jobs/upload/FileUploadWorker.kt @@ -259,6 +259,14 @@ class FileUploadWorker( return } + // Only notify if it is not same file on remote that causes conflict + if (uploadResult.code == ResultCode.SYNC_CONFLICT && FileUploadHelper().isSameFileOnRemote( + uploadFileOperation.user, File(uploadFileOperation.storagePath), uploadFileOperation.remotePath, context + ) + ) { + return + } + val notDelayed = uploadResult.code !in setOf( ResultCode.DELAYED_FOR_WIFI, ResultCode.DELAYED_FOR_CHARGING, diff --git a/app/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java b/app/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java index acc9dc9cd79a..be3fdf15e1dc 100644 --- a/app/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java +++ b/app/src/main/java/com/owncloud/android/datamodel/UploadsStorageManager.java @@ -34,6 +34,7 @@ import com.nextcloud.client.account.CurrentAccountProvider; import com.nextcloud.client.account.User; +import com.nextcloud.client.jobs.upload.FileUploadHelper; import com.nextcloud.client.jobs.upload.FileUploadWorker; import com.owncloud.android.MainApp; import com.owncloud.android.db.OCUpload; @@ -44,6 +45,7 @@ import com.owncloud.android.lib.common.utils.Log_OC; import com.owncloud.android.operations.UploadFileOperation; +import java.io.File; import java.util.ArrayList; import java.util.Arrays; import java.util.Calendar; @@ -737,6 +739,25 @@ public void updateDatabaseUploadResult(RemoteOperationResult uploadResult, Uploa upload.getRemotePath(), localPath ); + } else if (uploadResult.getCode() == RemoteOperationResult.ResultCode.SYNC_CONFLICT && + new FileUploadHelper().isSameFileOnRemote( + upload.getUser(), new File(upload.getStoragePath()), upload.getRemotePath(), upload.getContext())) { + + updateUploadStatus( + upload.getOCUploadId(), + UploadStatus.UPLOAD_SUCCEEDED, + UploadResult.SAME_FILE_CONFLICT, + upload.getRemotePath(), + localPath + ); + } else if (uploadResult.getCode() == RemoteOperationResult.ResultCode.LOCAL_FILE_NOT_FOUND) { + updateUploadStatus( + upload.getOCUploadId(), + UploadStatus.UPLOAD_SUCCEEDED, + UploadResult.FILE_NOT_FOUND, + upload.getRemotePath(), + localPath + ); } else { updateUploadStatus( upload.getOCUploadId(), diff --git a/app/src/main/java/com/owncloud/android/db/UploadResult.java b/app/src/main/java/com/owncloud/android/db/UploadResult.java index 17533f0413be..919be585cb19 100644 --- a/app/src/main/java/com/owncloud/android/db/UploadResult.java +++ b/app/src/main/java/com/owncloud/android/db/UploadResult.java @@ -45,7 +45,8 @@ public enum UploadResult { SYNC_CONFLICT(19), CANNOT_CREATE_FILE(20), LOCAL_STORAGE_NOT_COPIED(21), - QUOTA_EXCEEDED(22); + QUOTA_EXCEEDED(22), + SAME_FILE_CONFLICT(23); private final int value; @@ -107,6 +108,8 @@ public static UploadResult fromValue(int value) { return LOCAL_STORAGE_NOT_COPIED; case 22: return QUOTA_EXCEEDED; + case 23: + return SAME_FILE_CONFLICT; } return UNKNOWN; } diff --git a/app/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java b/app/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java index 5012cd15f5d1..304892e74a4e 100755 --- a/app/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java +++ b/app/src/main/java/com/owncloud/android/ui/adapter/UploadListAdapter.java @@ -29,6 +29,7 @@ import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; +import android.graphics.Typeface; import android.graphics.drawable.Drawable; import android.net.Uri; import android.text.format.DateUtils; @@ -259,6 +260,7 @@ public void onBindViewHolder(SectionedViewHolder holder, int section, int relati itemViewHolder.binding.uploadRemotePath.setVisibility(View.VISIBLE); itemViewHolder.binding.uploadFileSize.setVisibility(View.VISIBLE); itemViewHolder.binding.uploadStatus.setVisibility(View.VISIBLE); + itemViewHolder.binding.uploadStatus.setTypeface(null, Typeface.NORMAL); itemViewHolder.binding.uploadProgressBar.setVisibility(View.GONE); // Update information depending of upload details @@ -300,6 +302,16 @@ public void onBindViewHolder(SectionedViewHolder holder, int section, int relati case UPLOAD_FAILED -> itemViewHolder.binding.uploadDate.setVisibility(View.GONE); case UPLOAD_SUCCEEDED -> itemViewHolder.binding.uploadStatus.setVisibility(View.GONE); } + + // show status if same file conflict or local file deleted + if (item.getUploadStatus() == UploadStatus.UPLOAD_SUCCEEDED && + item.getLastResult() != UploadResult.UPLOADED){ + itemViewHolder.binding.uploadStatus.setVisibility(View.VISIBLE); + itemViewHolder.binding.uploadStatus.setTypeface(null, Typeface.BOLD); + itemViewHolder.binding.uploadDate.setVisibility(View.GONE); + itemViewHolder.binding.uploadFileSize.setVisibility(View.GONE); + } + itemViewHolder.binding.uploadStatus.setText(status); // bind listeners to perform actions @@ -612,7 +624,13 @@ private String getStatusText(OCUpload upload) { break; case UPLOAD_SUCCEEDED: - status = parentActivity.getString(R.string.uploads_view_upload_status_succeeded); + if (upload.getLastResult() == UploadResult.SAME_FILE_CONFLICT){ + status = parentActivity.getString(R.string.uploads_view_upload_status_succeeded_same_file); + }else if (upload.getLastResult() == UploadResult.FILE_NOT_FOUND) { + status = getUploadFailedStatusText(upload.getLastResult()); + } else { + status = parentActivity.getString(R.string.uploads_view_upload_status_succeeded); + } break; case UPLOAD_FAILED: diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 8ba77bc10d47..28509ebd0180 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -153,6 +153,7 @@ Failed/pending restart Uploaded Completed + Same file found on remote, skipping upload Cancelled Connection error Credentials error