Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement non-gms upload #43

Merged
merged 5 commits into from
Jun 21, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.omh.android.storage.api.drive.gms.data.repository

import com.omh.android.storage.api.data.source.OmhFileRemoteDataSource
import com.omh.android.storage.api.domain.repository.OmhFileRepository
import java.io.File

internal class GmsFileRepositoryImpl(private val dataSource: OmhFileRemoteDataSource) : OmhFileRepository {

Expand All @@ -12,11 +13,12 @@ internal class GmsFileRepositoryImpl(private val dataSource: OmhFileRemoteDataSo

override fun deleteFile(fileId: String) = dataSource.deleteFile(fileId)

override fun uploadFile(localFileToUpload: File, fileName: String, parentId: String?) =
dataSource.uploadFile(localFileToUpload, fileName, parentId)

override fun open() = Unit

override fun update() = Unit

override fun upload() = Unit

override fun download() = Unit
}
Original file line number Diff line number Diff line change
@@ -1,31 +1,32 @@
package com.omh.android.storage.api.drive.gms.data.source

import com.google.api.services.drive.model.File
import com.google.api.services.drive.model.FileList
import com.omh.android.storage.api.data.source.OmhFileRemoteDataSource
import com.omh.android.storage.api.domain.model.OmhFile
import com.omh.android.storage.api.drive.gms.data.GoogleDriveApiService
import com.omh.android.storage.api.drive.gms.data.source.mapper.toOmhFile
import java.io.File
import com.google.api.services.drive.model.File as GoogleApiFile

internal class GmsFileRemoteDataSourceImpl(private val apiService: GoogleDriveApiService) :
OmhFileRemoteDataSource {

override fun getFilesList(parentId: String): List<OmhFile> {
val googleJsonFileList: FileList = apiService.getFilesList(parentId).execute()
val googleFileList: List<File> = googleJsonFileList.files.toList()
val googleFileList: List<GoogleApiFile> = googleJsonFileList.files.toList()
return googleFileList.mapNotNull { googleFile -> googleFile.toOmhFile() }
}

override fun createFile(name: String, mimeType: String, parentId: String?): OmhFile? {
val fileToBeCreated = File().apply {
val fileToBeCreated = GoogleApiFile().apply {
this.name = name
this.mimeType = mimeType
if (parentId != null) {
this.parents = listOf(parentId)
}
}

val responseFile: File = apiService.createFile(fileToBeCreated).execute()
val responseFile: GoogleApiFile = apiService.createFile(fileToBeCreated).execute()

return responseFile.toOmhFile()
}
Expand All @@ -39,4 +40,6 @@ internal class GmsFileRemoteDataSourceImpl(private val apiService: GoogleDriveAp
false
}
}

override fun uploadFile(localFileToUpload: File, fileName: String, parentId: String?) = null
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import com.omh.android.auth.api.OmhCredentials
import com.omh.android.storage.api.drive.nongms.BuildConfig
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.jackson.JacksonConverterFactory

Expand Down Expand Up @@ -43,27 +42,14 @@ internal class GoogleRetrofitImpl(private val omhCredentials: OmhCredentials) {
}

private fun createOkHttpClient(): OkHttpClient {
val loggingInterceptor = setupLoggingInterceptor()

return OkHttpClient.Builder()
.addInterceptor(loggingInterceptor)
.addInterceptor { chain ->
val request = setupRequestInterceptor(chain)
chain.proceed(request)
}
.build()
}

private fun setupLoggingInterceptor() = HttpLoggingInterceptor().apply {
HectorNarvaez marked this conversation as resolved.
Show resolved Hide resolved
setLevel(
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor.Level.BODY
} else {
HttpLoggingInterceptor.Level.NONE
}
)
}

private fun setupRequestInterceptor(chain: Interceptor.Chain) = chain
.request()
.newBuilder()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,24 @@ package com.omh.android.storage.api.drive.nongms.data
import com.omh.android.storage.api.drive.nongms.data.source.body.CreateFileRequestBody
import com.omh.android.storage.api.drive.nongms.data.source.response.FileListRemoteResponse
import com.omh.android.storage.api.drive.nongms.data.source.response.FileRemoteResponse
import okhttp3.MultipartBody
import okhttp3.RequestBody
import okhttp3.ResponseBody
import retrofit2.Call
import retrofit2.http.Body
import retrofit2.http.DELETE
import retrofit2.http.GET
import retrofit2.http.Multipart
import retrofit2.http.POST
import retrofit2.http.Part
import retrofit2.http.Path
import retrofit2.http.Query

internal interface GoogleStorageApiService {

companion object {
private const val FILES_PARTICLE = "drive/v3/files"
private const val UPLOAD_FILES_PARTICLE = "upload/drive/v3/files"

private const val QUERY_Q = "q"
private const val QUERY_FIELDS = "fields"
Expand All @@ -28,6 +33,7 @@ internal interface GoogleStorageApiService {
private const val FIELDS_VALUE = "files($QUERY_REQUESTED_FIELDS)"

private const val FILE_ID = "fileId"
private const val META_DATA = "metadata"
}

@GET(FILES_PARTICLE)
Expand All @@ -46,4 +52,11 @@ internal interface GoogleStorageApiService {
fun deleteFile(
@Path(FILE_ID) fileId: String
): Call<ResponseBody>

@Multipart
@POST(UPLOAD_FILES_PARTICLE)
fun uploadFile(
@Part(META_DATA) metadata: RequestBody,
@Part filePart: MultipartBody.Part
): Call<FileRemoteResponse>
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package com.omh.android.storage.api.drive.nongms.data.repository

import com.omh.android.storage.api.data.source.OmhFileRemoteDataSource
import com.omh.android.storage.api.domain.repository.OmhFileRepository
import java.io.File

internal class NonGmsFileRepositoryImpl(
private val dataSource: OmhFileRemoteDataSource
Expand All @@ -15,11 +16,12 @@ internal class NonGmsFileRepositoryImpl(

override fun deleteFile(fileId: String) = dataSource.deleteFile(fileId)

override fun uploadFile(localFileToUpload: File, fileName: String, parentId: String?) =
dataSource.uploadFile(localFileToUpload, fileName, parentId)

override fun open() = Unit

override fun update() = Unit

override fun upload() = Unit

override fun download() = Unit
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,32 @@
package com.omh.android.storage.api.drive.nongms.data.source

import android.webkit.MimeTypeMap
import com.omh.android.storage.api.data.source.OmhFileRemoteDataSource
import com.omh.android.storage.api.domain.model.OmhFile
import com.omh.android.storage.api.drive.nongms.data.GoogleRetrofitImpl
import com.omh.android.storage.api.drive.nongms.data.GoogleStorageApiService
import com.omh.android.storage.api.drive.nongms.data.source.body.CreateFileRequestBody
import com.omh.android.storage.api.drive.nongms.data.source.mapper.toFile
import com.omh.android.storage.api.drive.nongms.data.source.mapper.toFileList
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.MultipartBody
import okhttp3.RequestBody.Companion.asRequestBody
import okhttp3.RequestBody.Companion.toRequestBody
import org.json.JSONArray
import org.json.JSONObject
import java.io.File

internal class NonGmsFileRemoteDataSourceImpl(private val retrofitImpl: GoogleRetrofitImpl) :
OmhFileRemoteDataSource {

companion object {
private const val FILE_NAME_KEY = "name"
private const val FILE_PARENTS_KEY = "parents"
private const val ANY_MIME_TYPE = "*/*"

private val JSON_MIME_TYPE = "application/json".toMediaTypeOrNull()
}

override fun getFilesList(parentId: String): List<OmhFile> {
val response = retrofitImpl
.getGoogleStorageApiService()
Expand Down Expand Up @@ -55,4 +71,43 @@ internal class NonGmsFileRemoteDataSourceImpl(private val retrofitImpl: GoogleRe

return response.isSuccessful
}

override fun uploadFile(
localFileToUpload: File,
fileName: String,
parentId: String?
): OmhFile? {
val stringMimeType = MimeTypeMap
.getSingleton()
.getMimeTypeFromExtension(localFileToUpload.extension)
?: ANY_MIME_TYPE

val mimeType = stringMimeType.toMediaTypeOrNull()
val requestFile = localFileToUpload.asRequestBody(mimeType)
val parentsList = if (parentId.isNullOrBlank()) {
emptyList()
HectorNarvaez marked this conversation as resolved.
Show resolved Hide resolved
} else {
listOf(parentId)
}

val parentsListAsJson = JSONArray(parentsList)
val jsonMetaData = JSONObject().apply {
put(FILE_NAME_KEY, fileName)
put(FILE_PARENTS_KEY, parentsListAsJson)
}

val jsonRequestBody = jsonMetaData.toString().toRequestBody(JSON_MIME_TYPE)
val filePart = MultipartBody.Part.createFormData(FILE_NAME_KEY, fileName, requestFile)

val response = retrofitImpl
.getGoogleStorageApiService()
.uploadFile(jsonRequestBody, filePart)
.execute()

return if (response.isSuccessful) {
response.body()?.toFile()
} else {
null
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import com.omh.android.storage.api.domain.usecase.GetFilesListUseCase
import com.omh.android.storage.api.domain.usecase.GetFilesListUseCaseParams
import com.omh.android.storage.api.domain.usecase.GetFilesListUseCaseResult
import com.omh.android.storage.api.domain.usecase.OmhResult
import com.omh.android.storage.api.domain.usecase.UploadFileUseCase
import com.omh.android.storage.api.domain.usecase.UploadFileUseCaseParams
import com.omh.android.storage.api.domain.usecase.UploadFileUseCaseResult
import java.io.File

abstract class OmhStorageClient protected constructor(
protected val authClient: OmhAuthClient
Expand Down Expand Up @@ -56,4 +60,17 @@ abstract class OmhStorageClient protected constructor(
result
}
}

fun uploadFile(
localFileToUpload: File,
fileName: String,
parentId: String?
): OmhTask<UploadFileUseCaseResult> {
val uploadFileUseCase = UploadFileUseCase(getRepository())
return OmhStorageTaskImpl {
val parameters = UploadFileUseCaseParams(localFileToUpload, fileName, parentId)
val result = uploadFileUseCase(parameters)
result
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.omh.android.storage.api.data.source

import com.omh.android.storage.api.domain.model.OmhFile
import java.io.File

interface OmhFileRemoteDataSource {

Expand All @@ -12,4 +13,6 @@ interface OmhFileRemoteDataSource {
* @return true if the file was deleted, false otherwise
*/
fun deleteFile(fileId: String): Boolean

fun uploadFile(localFileToUpload: File, fileName: String, parentId: String?): OmhFile?
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package com.omh.android.storage.api.domain.repository

import com.omh.android.storage.api.domain.model.OmhFile
import java.io.File

interface OmhFileRepository {

Expand All @@ -10,11 +11,11 @@ interface OmhFileRepository {

fun deleteFile(fileId: String): Boolean

fun uploadFile(localFileToUpload: File, fileName: String, parentId: String?): OmhFile?

fun open()

fun update()

fun upload()

fun download()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.omh.android.storage.api.domain.usecase

import com.omh.android.storage.api.domain.model.OmhFile
import com.omh.android.storage.api.domain.repository.OmhFileRepository
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import java.io.File

class UploadFileUseCase(
private val repository: OmhFileRepository,
dispatcher: CoroutineDispatcher = Dispatchers.Default
) : OmhSuspendUseCase<UploadFileUseCaseParams, UploadFileUseCaseResult>(dispatcher) {

override suspend fun execute(parameters: UploadFileUseCaseParams): UploadFileUseCaseResult {
return UploadFileUseCaseResult(
repository.uploadFile(parameters.localFileToUpload, parameters.fileName, parameters.parentId)
)
}
}

data class UploadFileUseCaseParams(val localFileToUpload: File, val fileName: String, val parentId: String?)

data class UploadFileUseCaseResult(val file: OmhFile?)