From ebf076d9f69400a3919cda5d0605eaf65b49b264 Mon Sep 17 00:00:00 2001 From: Mitchell Syer Date: Sun, 25 Dec 2022 02:45:37 -0500 Subject: [PATCH] Use extension list fallback if extensions fail to fetch (#469) --- .../manga/impl/extension/ExtensionsList.kt | 16 +++++----- .../extension/github/ExtensionGithubApi.kt | 30 ++++++++++++++----- 2 files changed, 30 insertions(+), 16 deletions(-) diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/ExtensionsList.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/ExtensionsList.kt index 1c4a1cf4..17a46d72 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/ExtensionsList.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/ExtensionsList.kt @@ -22,6 +22,7 @@ import suwayomi.tachidesk.manga.impl.extension.github.OnlineExtension import suwayomi.tachidesk.manga.model.dataclass.ExtensionDataClass import suwayomi.tachidesk.manga.model.table.ExtensionTable import java.util.concurrent.ConcurrentHashMap +import kotlin.time.Duration.Companion.seconds object ExtensionsList { private val logger = KotlinLogging.logger {} @@ -29,12 +30,9 @@ object ExtensionsList { var lastUpdateCheck: Long = 0 var updateMap = ConcurrentHashMap() - /** 60,000 milliseconds = 60 seconds */ - private const val ExtensionUpdateDelayTime = 60 * 1000 - suspend fun getExtensionList(): List { - // update if {ExtensionUpdateDelayTime} seconds has passed or requested offline and database is empty - if (lastUpdateCheck + ExtensionUpdateDelayTime < System.currentTimeMillis()) { + // update if 60 seconds has passed or requested offline and database is empty + if (lastUpdateCheck + 60.seconds.inWholeMilliseconds < System.currentTimeMillis()) { logger.debug("Getting extensions list from the internet") lastUpdateCheck = System.currentTimeMillis() @@ -80,14 +78,14 @@ object ExtensionsList { updateMap.putIfAbsent(foundExtension.pkgName, foundExtension) } foundExtension.versionCode < extensionRecord[ExtensionTable.versionCode] -> { - // some how the user installed an invalid version + // somehow the user installed an invalid version ExtensionTable.update({ ExtensionTable.pkgName eq foundExtension.pkgName }) { it[isObsolete] = true } } } } else { - // extension is not installed so we can overwrite the data without a care + // extension is not installed, so we can overwrite the data without a care ExtensionTable.update({ ExtensionTable.pkgName eq foundExtension.pkgName }) { it[name] = foundExtension.name it[versionName] = foundExtension.versionName @@ -117,14 +115,14 @@ object ExtensionsList { ExtensionTable.selectAll().forEach { extensionRecord -> val foundExtension = foundExtensions.find { it.pkgName == extensionRecord[ExtensionTable.pkgName] } if (foundExtension == null) { - // not in the repo, so this extensions is obsolete + // not in the repo, so these extensions are obsolete if (extensionRecord[ExtensionTable.isInstalled]) { // is installed so we should mark it as obsolete ExtensionTable.update({ ExtensionTable.pkgName eq extensionRecord[ExtensionTable.pkgName] }) { it[isObsolete] = true } } else { - // is not installed so we can remove the record without a care + // is not installed, so we can remove the record without a care ExtensionTable.deleteWhere { ExtensionTable.pkgName eq extensionRecord[ExtensionTable.pkgName] } } } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/ExtensionGithubApi.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/ExtensionGithubApi.kt index 45c8c720..cbaf29bd 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/ExtensionGithubApi.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/github/ExtensionGithubApi.kt @@ -7,11 +7,12 @@ package suwayomi.tachidesk.manga.impl.extension.github * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at https://mozilla.org/MPL/2.0/. */ +import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.NetworkHelper import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.parseAs import kotlinx.serialization.Serializable -import okhttp3.Request +import mu.KotlinLogging import suwayomi.tachidesk.manga.impl.util.PackageTools.LIB_VERSION_MAX import suwayomi.tachidesk.manga.impl.util.PackageTools.LIB_VERSION_MIN import suwayomi.tachidesk.manga.model.dataclass.ExtensionDataClass @@ -19,6 +20,8 @@ import uy.kohesive.injekt.injectLazy object ExtensionGithubApi { private const val REPO_URL_PREFIX = "https://raw.githubusercontent.com/tachiyomiorg/tachiyomi-extensions/repo/" + private const val FALLBACK_REPO_URL_PREFIX = "https://gcore.jsdelivr.net/gh/tachiyomiorg/tachiyomi-extensions@repo/" + private val logger = KotlinLogging.logger {} @Serializable private data class ExtensionJsonObject( @@ -42,13 +45,26 @@ object ExtensionGithubApi { val baseUrl: String ) - suspend fun findExtensions(): List { - val request = Request.Builder() - .url("$REPO_URL_PREFIX/index.min.json") - .build() + private var requiresFallbackSource = false - return client.newCall(request) - .await() + suspend fun findExtensions(): List { + val githubResponse = if (requiresFallbackSource) { + null + } else { + try { + client.newCall(GET("${REPO_URL_PREFIX}index.min.json")).await() + } catch (e: Throwable) { + logger.error(e) { "Failed to get extensions from GitHub" } + requiresFallbackSource = true + null + } + } + + val response = githubResponse ?: run { + client.newCall(GET("${FALLBACK_REPO_URL_PREFIX}index.min.json")).await() + } + + return response .parseAs>() .toExtensions() }