refactor(extension/repo): Refactor the ExtensionRepoService to use DTOs

Co-authored-by: MajorTanya <39014446+MajorTanya@users.noreply.github.com>
This commit is contained in:
Ahmad Ansori Palembani 2024-08-26 14:10:20 +07:00
parent c7405e0b33
commit da99cf5cfa
Signed by: null2264
GPG key ID: BA64F8B60AF3EFB6
10 changed files with 43 additions and 61 deletions

View file

@ -9,5 +9,11 @@
## Other ?? Technical stuff, what happened behind the scene
-->
## Additions
- Sync DoH provider list with upstream (added Mullvad, Control D, Njalla, and Shecan)
## Fixes
- Fixed NPE crash on tablets
- Fixed only few DoH provider is actually being used (Cloudflare, Google, AdGuard, and Quad9)
## Other
- Simplify network helper code

View file

@ -1,6 +0,0 @@
package yokai.domain.extension.repo.exception
import java.io.IOException
class FetchExtensionRepoException(throwable: Throwable) :
IOException("Failed to retrieve Extension Repo Details", throwable)

View file

@ -5,7 +5,6 @@ import eu.kanade.tachiyomi.network.NetworkHelper
import okhttp3.OkHttpClient
import uy.kohesive.injekt.injectLazy
import yokai.domain.extension.repo.ExtensionRepoRepository
import yokai.domain.extension.repo.exception.FetchExtensionRepoException
import yokai.domain.extension.repo.exception.SaveExtensionRepoException
import yokai.domain.extension.repo.model.ExtensionRepo
import yokai.domain.extension.repo.service.ExtensionRepoService
@ -28,11 +27,7 @@ class CreateExtensionRepo(
}
val baseUrl = repoUrl.removeSuffix("/index.min.json")
return try {
extensionRepoService.fetchRepoDetails(baseUrl)?.let { insert(it) } ?: Result.InvalidUrl
} catch (e: FetchExtensionRepoException) {
Result.RepoFetchFailed
}
return extensionRepoService.fetchRepoDetails(baseUrl)?.let { insert(it) } ?: Result.InvalidUrl
}
private suspend fun insert(repo: ExtensionRepo): Result {
@ -79,7 +74,6 @@ class CreateExtensionRepo(
data class DuplicateFingerprint(val oldRepo: ExtensionRepo, val newRepo: ExtensionRepo) : Result
data object InvalidUrl : Result
data object RepoAlreadyExists : Result
data object RepoFetchFailed : Result
data object Success : Result
data object Error : Result
}

View file

@ -1,12 +1,10 @@
package yokai.domain.extension.repo.interactor
import co.touchlab.kermit.Logger
import eu.kanade.tachiyomi.network.NetworkHelper
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import yokai.domain.extension.repo.ExtensionRepoRepository
import yokai.domain.extension.repo.exception.FetchExtensionRepoException
import yokai.domain.extension.repo.model.ExtensionRepo
import yokai.domain.extension.repo.service.ExtensionRepoService
@ -23,18 +21,7 @@ class UpdateExtensionRepo(
}
suspend fun await(repo: ExtensionRepo) {
val newRepo = try {
extensionRepoService.fetchRepoDetails(repo.baseUrl) ?: return
} catch (e: Exception) {
when (e) {
is FetchExtensionRepoException -> {
// TODO: A way to show user that a repo failed to update
Logger.e(e) { "Failed to fetch repo details" }
return
}
else -> throw e
}
}
val newRepo = extensionRepoService.fetchRepoDetails(repo.baseUrl) ?: return
if (
repo.signingKeyFingerprint.startsWith("NOFINGERPRINT") ||
repo.signingKeyFingerprint == newRepo.signingKeyFingerprint

View file

@ -1,20 +1,15 @@
package yokai.domain.extension.repo.service
import androidx.core.net.toUri
import co.touchlab.kermit.Logger
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.HttpException
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.system.withIOContext
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import okhttp3.OkHttpClient
import uy.kohesive.injekt.injectLazy
import yokai.domain.extension.repo.exception.FetchExtensionRepoException
import yokai.domain.extension.repo.model.ExtensionRepo
import java.net.UnknownHostException
class ExtensionRepoService(
private val client: OkHttpClient,
@ -29,35 +24,16 @@ class ExtensionRepoService(
val url = "$repo/repo.json".toUri()
try {
val response = with(json) {
with(json) {
client.newCall(GET(url.toString()))
.awaitSuccess()
.parseAs<JsonObject>()
.parseAs<ExtensionRepoMetaDto>()
.toExtensionRepo(baseUrl = repo)
}
response["meta"]
?.jsonObject
?.let { jsonToExtensionRepo(baseUrl = repo, it) }
} catch (e: Exception) {
when (e) {
is HttpException -> null
is UnknownHostException -> throw FetchExtensionRepoException(e)
else -> throw e
}
}
}
}
private fun jsonToExtensionRepo(baseUrl: String, obj: JsonObject): ExtensionRepo? {
return try {
ExtensionRepo(
baseUrl = baseUrl,
name = obj["name"]!!.jsonPrimitive.content,
shortName = obj["shortName"]?.jsonPrimitive?.content,
website = obj["website"]!!.jsonPrimitive.content,
signingKeyFingerprint = obj["signingKeyFingerprint"]!!.jsonPrimitive.content,
)
} catch (_: NullPointerException) {
Logger.e(e) { "Failed to fetch repo details" }
null
}
}
}
}

View file

@ -54,7 +54,6 @@ class ExtensionRepoViewModel :
is CreateExtensionRepo.Result.Success -> internalEvent.value = ExtensionRepoEvent.Success
is CreateExtensionRepo.Result.Error -> internalEvent.value = ExtensionRepoEvent.InvalidUrl
is CreateExtensionRepo.Result.RepoAlreadyExists -> internalEvent.value = ExtensionRepoEvent.RepoAlreadyExists
is CreateExtensionRepo.Result.RepoFetchFailed -> internalEvent.value = ExtensionRepoEvent.RepoFetchFailed
is CreateExtensionRepo.Result.DuplicateFingerprint -> {
internalEvent.value = ExtensionRepoEvent.ShowDialog(RepoDialog.Conflict(result.oldRepo, result.newRepo))
}
@ -94,7 +93,6 @@ sealed class ExtensionRepoEvent {
sealed class LocalizedMessage(val stringRes: StringResource) : ExtensionRepoEvent()
data object InvalidUrl : LocalizedMessage(MR.strings.invalid_repo_url)
data object RepoAlreadyExists : LocalizedMessage(MR.strings.repo_already_exists)
data object RepoFetchFailed : LocalizedMessage(MR.strings.repo_fetch_failed)
data class ShowDialog(val dialog: RepoDialog) : ExtensionRepoEvent()
data object NoOp : ExtensionRepoEvent()
data object Success : ExtensionRepoEvent()

View file

@ -5,6 +5,7 @@ import java.util.Locale
import yokai.domain.manga.models.MangaUpdate
// TODO: Transform into data class
@Deprecated("Use data class version", ReplaceWith("yokai.domain.manga.models.Manga"))
interface Manga : SManga {
var id: Long?

View file

@ -0,0 +1,27 @@
package yokai.domain.extension.repo.service
import kotlinx.serialization.Serializable
import yokai.domain.extension.repo.model.ExtensionRepo
@Serializable
data class ExtensionRepoMetaDto(
val meta: ExtensionRepoDto,
)
@Serializable
data class ExtensionRepoDto(
val name: String,
val shortName: String?,
val website: String,
val signingKeyFingerprint: String,
)
fun ExtensionRepoMetaDto.toExtensionRepo(baseUrl: String): ExtensionRepo {
return ExtensionRepo(
baseUrl = baseUrl,
name = meta.name,
shortName = meta.shortName,
website = meta.website,
signingKeyFingerprint = meta.signingKeyFingerprint,
)
}

View file

@ -883,7 +883,6 @@
<string name="action_add_repo">Add repo</string>
<string name="invalid_repo_url">Invalid repo url</string>
<string name="repo_already_exists">Repo already exists!</string>
<string name="repo_fetch_failed">Failed to retrieve repo details. Please try again later</string>
<string name="information_empty_repos">You haven\'t added any repos yet.</string>
<string name="confirm_delete_repo_title">Delete repo?</string>
<string name="confirm_delete_repo">Are you sure you wish to delete the repo \"%s\"?</string>