Skip to content

Commit

Permalink
Refactoring ShareViewModel.
Browse files Browse the repository at this point in the history
Upping versionCode to 58
  • Loading branch information
Dima-Android committed Apr 23, 2024
1 parent e8f8acf commit ea829d1
Show file tree
Hide file tree
Showing 7 changed files with 722 additions and 589 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
package org.zotero.android.screens.share

import android.content.Context
import org.zotero.android.BuildConfig
import org.zotero.android.api.network.CustomResult
import org.zotero.android.database.DbWrapper
import org.zotero.android.database.requests.ReadGroupDbRequest
import org.zotero.android.sync.LibraryIdentifier
import org.zotero.android.sync.Parsing
import org.zotero.android.sync.SchemaError
import org.zotero.android.translator.data.AttachmentState
import org.zotero.android.translator.data.TranslationWebViewError
import org.zotero.android.uicomponents.Strings
import timber.log.Timber
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class ShareErrorProcessor @Inject constructor(
private val context: Context,
private val dbWrapper: DbWrapper
) {
fun errorMessage(error: AttachmentState.Error): String? {
return when (error) {
AttachmentState.Error.apiFailure -> {
context.getString(Strings.errors_shareext_api_error)
}

AttachmentState.Error.cantLoadSchema -> {
context.getString(Strings.errors_shareext_cant_load_schema)
}

AttachmentState.Error.cantLoadWebData -> {
context.getString(Strings.errors_shareext_cant_load_data)
}

AttachmentState.Error.downloadFailed -> {
context.getString(Strings.errors_shareext_download_failed)
}

AttachmentState.Error.downloadedFileNotPdf -> {
null
}

AttachmentState.Error.expired -> {
context.getString(Strings.errors_shareext_unknown)
}

AttachmentState.Error.fileMissing -> {
context.getString(Strings.errors_shareext_missing_file)
}

AttachmentState.Error.itemsNotFound -> {
context.getString(Strings.errors_shareext_items_not_found)
}

AttachmentState.Error.md5Missing -> {
null
}

AttachmentState.Error.mtimeMissing -> {
null
}

is AttachmentState.Error.parseError -> {
context.getString(Strings.errors_shareext_parsing_error)
}

is AttachmentState.Error.quotaLimit -> {
when (error.libraryIdentifier) {
is LibraryIdentifier.custom -> {
context.getString(Strings.errors_shareext_personal_quota_reached)
}

is LibraryIdentifier.group -> {
val groupId = error.libraryIdentifier.groupId
val group =
dbWrapper.realmDbStorage.perform(ReadGroupDbRequest(identifier = groupId))
val groupName = group?.name ?: "$groupId"
return context.getString(
Strings.errors_shareext_group_quota_reached,
groupName
)
}
}
}

is AttachmentState.Error.schemaError -> {
context.getString(Strings.errors_shareext_schema_error)
}

AttachmentState.Error.unknown -> {
context.getString(Strings.errors_shareext_unknown)
}

AttachmentState.Error.webDavFailure -> {
context.getString(Strings.errors_shareext_webdav_error)
}

AttachmentState.Error.webDavNotVerified -> {
context.getString(Strings.errors_shareext_webdav_not_verified)
}

is AttachmentState.Error.webViewError -> {
return when (error.error) {
TranslationWebViewError.cantFindFile -> {
context.getString(Strings.errors_shareext_missing_base_files)
}

TranslationWebViewError.incompatibleItem -> {
context.getString(Strings.errors_shareext_incompatible_item)
}

TranslationWebViewError.javascriptCallMissingResult -> {
context.getString(Strings.errors_shareext_javascript_failed)
}

TranslationWebViewError.noSuccessfulTranslators -> {
null
}

TranslationWebViewError.webExtractionMissingData -> {
context.getString(Strings.errors_shareext_response_missing_data)
}

TranslationWebViewError.webExtractionMissingJs -> {
context.getString(Strings.errors_shareext_missing_base_files)
}
}
}
}
}

fun attachmentError(
generalError: CustomResult.GeneralError,
libraryId: LibraryIdentifier?
): AttachmentState.Error {
when (generalError) {
is CustomResult.GeneralError.CodeError -> {
val error = generalError.throwable
if (error is AttachmentState.Error) {
return error
}
if (error is Parsing.Error) {
Timber.e(error, "ExtensionViewModel: could not parse item")
return AttachmentState.Error.parseError(error)
}

if (error is SchemaError) {
Timber.e(error, "ExtensionViewModel: schema failed")
return AttachmentState.Error.schemaError(error)
}
if (error is TranslationWebViewError) {
return AttachmentState.Error.webViewError(error)
}
}

is CustomResult.GeneralError.NetworkError -> {
return networkErrorRequiresAbort(
error = generalError,
url = BuildConfig.BASE_API_URL,
libraryId = libraryId
)
}
}
return AttachmentState.Error.unknown
}

private fun networkErrorRequiresAbort(
error: CustomResult.GeneralError.NetworkError,
url: String?,
libraryId: LibraryIdentifier?
): AttachmentState.Error {
val defaultError = if ((url ?: "").contains(BuildConfig.BASE_API_URL)) {
AttachmentState.Error.apiFailure
} else {
AttachmentState.Error.webDavFailure
}

val code = error.httpCode
if (code == 413 && libraryId != null) {
return AttachmentState.Error.quotaLimit(libraryId)
}
return defaultError
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
package org.zotero.android.screens.share

import com.google.common.io.ByteProcessor
import com.google.common.io.ByteStreams
import com.google.common.io.Closeables
import org.zotero.android.api.NoAuthenticationApi
import org.zotero.android.api.network.CustomResult
import org.zotero.android.api.network.safeApiCall
import timber.log.Timber
import java.io.File
import java.io.FileOutputStream
import java.io.IOException
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class ShareFileDownloader @Inject constructor(
private val noAuthenticationApi: NoAuthenticationApi
) {

suspend fun download(
url: String,
file: File,
cookies: String?,
userAgent: String?,
referrer: String?,
updateProgressBar: (progress: Int) -> Unit,
) {
val headers: MutableMap<String, String> = LinkedHashMap()
if (userAgent != null) {
headers["User-Agent"] = userAgent
}
if (referrer != null) {
headers["Referer"] = referrer
}
if (cookies != null) {
headers["Cookie"] = cookies
}
val networkResult = safeApiCall {
noAuthenticationApi.downloadFileStreaming(url = url, headers = headers)
}
when (networkResult) {
is CustomResult.GeneralSuccess -> {
val byteStream = networkResult.value!!.byteStream()
val total = networkResult.value!!.contentLength()
var progress = 0L
val out = FileOutputStream(file);
try {
ByteStreams.readBytes(byteStream,
object : ByteProcessor<Void?> {
@Throws(IOException::class)
override fun processBytes(
buffer: ByteArray,
offset: Int,
length: Int
): Boolean {
out.write(buffer, offset, length)
progress += length
val progressResult = (progress / total.toDouble() * 100).toInt()
if (progressResult > 0) {
println()
}
updateProgressBar(progressResult)
return true
}

override fun getResult(): Void? {
return null
}
})
} catch (e: Exception) {
Timber.e(e, "Could not download $url")
throw e
} finally {
Closeables.close(out, true)
}
}

is CustomResult.GeneralError.CodeError -> {
throw networkResult.throwable
}

is CustomResult.GeneralError.NetworkError -> {
throw Exception(networkResult.stringResponse)
}
}
}

}
Loading

0 comments on commit ea829d1

Please sign in to comment.