Skip to content

Commit

Permalink
Merge pull request #84 from Infomaniak/feat-create-transfer-locally
Browse files Browse the repository at this point in the history
feat: Create transfer locally after upload
  • Loading branch information
tevincent authored Nov 12, 2024
2 parents 31598b2 + 0a59b39 commit 3705bd6
Show file tree
Hide file tree
Showing 9 changed files with 126 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
package com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers

import com.infomaniak.multiplatform_swisstransfer.common.models.TransferDirection
import com.infomaniak.multiplatform_swisstransfer.common.models.TransferStatus

interface Transfer {
val linkUUID: String
Expand All @@ -30,5 +31,6 @@ interface Transfer {
val downloadHost: String
val container: Container?

fun transferDirection(): TransferDirection? = null
val transferDirection: TransferDirection? get() = null
val transferStatus: TransferStatus? get() = null
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Infomaniak SwissTransfer - Multiplatform
* Copyright (C) 2024 Infomaniak Network SA
*
* 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 3 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.infomaniak.multiplatform_swisstransfer.common.models

enum class TransferStatus {
UNKNOWN, WAIT_VIRUS_CHECK, READY
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import com.infomaniak.multiplatform_swisstransfer.common.exceptions.RealmExcepti
import com.infomaniak.multiplatform_swisstransfer.common.exceptions.UnknownException
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.Transfer
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.ui.TransferUi
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.upload.UploadSession
import com.infomaniak.multiplatform_swisstransfer.common.models.TransferDirection
import com.infomaniak.multiplatform_swisstransfer.common.models.TransferStatus
import com.infomaniak.multiplatform_swisstransfer.common.utils.mapToList
import com.infomaniak.multiplatform_swisstransfer.database.controllers.TransferController
import com.infomaniak.multiplatform_swisstransfer.network.ApiClientProvider
Expand Down Expand Up @@ -107,8 +109,17 @@ class TransferManager internal constructor(
UnknownException::class,
RealmException::class,
)
suspend fun addTransferByLinkUUID(linkUUID: String): Unit = withContext(Dispatchers.IO) {
addTransfer(transferRepository.getTransferByLinkUUID(linkUUID).data, TransferDirection.SENT)
suspend fun addTransferByLinkUUID(linkUUID: String, uploadSession: UploadSession): Unit = withContext(Dispatchers.IO) {
runCatching {
addTransfer(transferRepository.getTransferByLinkUUID(linkUUID).data, TransferDirection.SENT)
}.onFailure { exception ->
when {
exception is UnexpectedApiErrorFormatException && exception.bodyResponse.contains("wait_virus_check") -> {
createTransferLocally(linkUUID, uploadSession)
}
else -> throw exception
}
}
}

/**
Expand Down Expand Up @@ -151,4 +162,12 @@ class TransferManager internal constructor(
throw UnknownException(it)
}
}

private suspend fun createTransferLocally(linkUUID: String, uploadSession: UploadSession) {
runCatching {
transferController.generateAndInsert(linkUUID, uploadSession, TransferStatus.WAIT_VIRUS_CHECK)
}.onFailure {
throw UnknownException(it)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -245,9 +245,8 @@ class UploadManager(
uploadRepository.finishUpload(finishUploadBody).first()
}.getOrElse { throw UnknownException(it) }

transferManager.addTransferByLinkUUID(finishUploadResponse.linkUUID, uploadSession)
uploadController.removeUploadSession(uuid)
transferManager.addTransferByLinkUUID(finishUploadResponse.linkUUID)
// TODO: If we can't retrieve the transfer cause of the Internet, we should put it in Realm and try again later.

return@withContext finishUploadResponse.linkUUID // Here the linkUUID correspond to the transferUUID of a transferUI
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ package com.infomaniak.multiplatform_swisstransfer.database.controllers

import com.infomaniak.multiplatform_swisstransfer.common.exceptions.RealmException
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.Transfer
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.upload.UploadSession
import com.infomaniak.multiplatform_swisstransfer.common.models.TransferDirection
import com.infomaniak.multiplatform_swisstransfer.common.models.TransferStatus
import com.infomaniak.multiplatform_swisstransfer.database.RealmProvider
import com.infomaniak.multiplatform_swisstransfer.database.models.transfers.TransferDB
import com.infomaniak.multiplatform_swisstransfer.database.utils.RealmUtils.runThrowingRealm
Expand Down Expand Up @@ -67,6 +69,17 @@ class TransferController(private val realmProvider: RealmProvider) {
this.copyToRealm(TransferDB(transfer, transferDirection), UpdatePolicy.ALL)
}
}

@Throws(RealmException::class, CancellationException::class)
suspend fun generateAndInsert(
linkUUID: String,
uploadSession: UploadSession,
transferStatus: TransferStatus,
) = runThrowingRealm {
realm?.write {
this.copyToRealm(TransferDB(linkUUID, uploadSession, transferStatus), UpdatePolicy.ALL)
}
}
//endregion

//region Update data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
package com.infomaniak.multiplatform_swisstransfer.database.models.transfers

import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.Container
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.upload.UploadContainer
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.upload.UploadFileSession
import io.realm.kotlin.ext.realmListOf
import io.realm.kotlin.types.RealmList
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.PrimaryKey
import kotlinx.datetime.Clock

class ContainerDB() : Container, RealmObject {
@PrimaryKey
Expand Down Expand Up @@ -58,4 +61,21 @@ class ContainerDB() : Container, RealmObject {
this.source = container.source
this.files = container.files.mapTo(realmListOf(), ::FileDB)
}

constructor(uploadContainer: UploadContainer, uploadFileSessionList: List<UploadFileSession>) : this() {
this.uuid = uploadContainer.uuid
this.duration = uploadContainer.duration.toLong()
this.createdDateTimestamp = Clock.System.now().epochSeconds
this.expiredDateTimestamp = uploadContainer.expiredDateTimestamp
this.numberOfFiles = uploadContainer.numberOfFiles
this.message = uploadContainer.message
this.needPassword = uploadContainer.needPassword
this.language = uploadContainer.language
this.sizeUploaded = 0
this.deletedDateTimestamp = null
this.swiftVersion = uploadContainer.swiftVersion.toInt()
this.downloadLimit = uploadContainer.downloadLimit
this.source = uploadContainer.source
this.files = uploadFileSessionList.mapTo(realmListOf()) { FileDB(uploadContainer, it) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@
package com.infomaniak.multiplatform_swisstransfer.database.models.transfers

import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.File
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.upload.UploadContainer
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.upload.UploadFileSession
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.PrimaryKey
import kotlinx.datetime.Clock

class FileDB() : File, RealmObject {
@PrimaryKey
Expand Down Expand Up @@ -52,4 +55,20 @@ class FileDB() : File, RealmObject {
this.path = file.path
this.thumbnailPath = file.thumbnailPath
}

constructor(uploadContainer: UploadContainer, uploadFileSession: UploadFileSession) : this() {
this.containerUUID = uploadContainer.uuid
this.uuid = uploadFileSession.remoteUploadFile!!.uuid
this.fileName = uploadFileSession.name
this.fileSizeInBytes = uploadFileSession.size
this.downloadCounter = 0
this.createdDateTimestamp = Clock.System.now().epochSeconds
this.expiredDateTimestamp = uploadContainer.expiredDateTimestamp
this.eVirus = "NOT_VIRUS_CHECKED"
this.deletedDate = null
this.mimeType = uploadFileSession.mimeType
this.receivedSizeInBytes = uploadFileSession.size
this.path = null
this.thumbnailPath = ""
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,13 @@
package com.infomaniak.multiplatform_swisstransfer.database.models.transfers

import com.infomaniak.multiplatform_swisstransfer.common.interfaces.transfers.Transfer
import com.infomaniak.multiplatform_swisstransfer.common.interfaces.upload.UploadSession
import com.infomaniak.multiplatform_swisstransfer.common.models.TransferDirection
import com.infomaniak.multiplatform_swisstransfer.common.models.TransferStatus
import io.realm.kotlin.types.RealmObject
import io.realm.kotlin.types.annotations.Ignore
import io.realm.kotlin.types.annotations.PrimaryKey
import kotlinx.datetime.Clock

class TransferDB() : Transfer, RealmObject {
@PrimaryKey
Expand All @@ -35,6 +39,12 @@ class TransferDB() : Transfer, RealmObject {
override var container: ContainerDB? = null

private var transferDirectionValue: String = ""
private var transferStatusValue: String = TransferStatus.UNKNOWN.name

@Ignore
override val transferDirection: TransferDirection get() = TransferDirection.valueOf(transferDirectionValue)
@Ignore
override val transferStatus: TransferStatus get() = TransferStatus.valueOf(transferStatusValue)

constructor(transfer: Transfer, transferDirection: TransferDirection) : this() {
this.linkUUID = transfer.linkUUID
Expand All @@ -48,9 +58,23 @@ class TransferDB() : Transfer, RealmObject {
this.container = transfer.container?.let(::ContainerDB)

this.transferDirectionValue = transferDirection.name
this.transferStatusValue = TransferStatus.READY.name
}

override fun transferDirection(): TransferDirection = TransferDirection.valueOf(transferDirectionValue)
constructor(linkUUID: String, uploadSession: UploadSession, transferStatus: TransferStatus) : this() {
this.linkUUID = linkUUID
this.containerUUID = uploadSession.remoteContainer!!.uuid
this.downloadCounterCredit = uploadSession.remoteContainer!!.downloadLimit
this.createdDateTimestamp = Clock.System.now().epochSeconds
this.expiredDateTimestamp = uploadSession.remoteContainer!!.expiredDateTimestamp
this.hasBeenDownloadedOneTime = false
this.isMailSent = false
this.downloadHost = ""
this.container = ContainerDB(uploadSession.remoteContainer!!, uploadSession.files)

this.transferDirectionValue = TransferDirection.SENT.name
this.transferStatusValue = transferStatus.name
}

internal companion object {
val transferDirectionPropertyName = TransferDB::transferDirectionValue.name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ class TransferControllerTest {
transferController.upsert(transfer, sent)
val realmTransfer = transferController.getTransfer(transfer.linkUUID)
assertNotNull(realmTransfer, "The transfer cannot be null")
assertEquals(sent, realmTransfer.transferDirection())
assertEquals(sent, realmTransfer.transferDirection)
assertEquals(transfer.container?.uuid, realmTransfer.container?.uuid, "The container is missing")
}

Expand All @@ -115,6 +115,6 @@ class TransferControllerTest {
val transfers = transferController.getTransfers(transferDirection)
assertNotNull(transfers)
assertEquals(1, transfers.count(), "The transfer list must contain 1 item")
assertEquals(transferDirection, transfers.first().transferDirection())
assertEquals(transferDirection, transfers.first().transferDirection)
}
}

0 comments on commit 3705bd6

Please sign in to comment.