From 4458f74f6c06fb9a2879bd530a20aaec61c06658 Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 15 May 2022 16:51:52 -0400 Subject: [PATCH] Use jsDelivr as fallback when GitHub can't be reached for extensions (closes #5517) Re-implementation of 24bb2f02dce135e0ceb2856618ecfc0e30dce875 (cherry picked from commit d61bfd7cafa09ff6c5f159c945984f2e8d9904b9) # Conflicts: # app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt --- .../presentation/extension/ExtensionScreen.kt | 5 +- .../extension/api/ExtensionGithubApi.kt | 51 ++++++++++++++++--- .../tachiyomi/extension/model/Extension.kt | 1 + 3 files changed, 46 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/extension/ExtensionScreen.kt b/app/src/main/java/eu/kanade/presentation/extension/ExtensionScreen.kt index ff29e00f1..4b0f12e63 100644 --- a/app/src/main/java/eu/kanade/presentation/extension/ExtensionScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/extension/ExtensionScreen.kt @@ -46,7 +46,6 @@ import eu.kanade.presentation.util.horizontalPadding import eu.kanade.presentation.util.plus import eu.kanade.presentation.util.topPaddingValues import eu.kanade.tachiyomi.R -import eu.kanade.tachiyomi.extension.api.REPO_URL_PREFIX import eu.kanade.tachiyomi.extension.model.Extension import eu.kanade.tachiyomi.extension.model.InstallStep import eu.kanade.tachiyomi.source.ConfigurableSource @@ -307,7 +306,7 @@ fun ExtensionItemContent( color = MaterialTheme.colorScheme.error, ), ) - } /* SY --> */ else if (extension is Extension.Available && extension.repoUrl != REPO_URL_PREFIX) { + } /* SY --> */ else if (extension is Extension.Available && extension.isRepoSource) { Text( text = stringResource(R.string.repo_source).uppercase(), style = MaterialTheme.typography.bodySmall.copy( @@ -324,7 +323,7 @@ fun ExtensionItemContent( private infix fun String.plusRepo(extension: Extension): String { val context = LocalContext.current return remember(this, extension, context) { - if (extension is Extension.Available && extension.repoUrl != REPO_URL_PREFIX) { + if (extension is Extension.Available && extension.isRepoSource) { if (isNullOrEmpty()) { "" } else { diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt index d24170239..e7b29e25e 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt @@ -12,7 +12,9 @@ import eu.kanade.tachiyomi.network.await import eu.kanade.tachiyomi.network.parseAs import eu.kanade.tachiyomi.util.lang.withIOContext import exh.source.BlacklistedSources +import eu.kanade.tachiyomi.util.system.logcat import kotlinx.serialization.Serializable +import logcat.LogPriority import uy.kohesive.injekt.injectLazy import java.util.Date import java.util.concurrent.TimeUnit @@ -22,21 +24,38 @@ internal class ExtensionGithubApi { private val networkService: NetworkHelper by injectLazy() private val preferences: PreferencesHelper by injectLazy() + private var requiresFallbackSource = false + suspend fun findExtensions(): List { return withIOContext { - val extensions = networkService.client - .newCall(GET("${REPO_URL_PREFIX}index.min.json")) - .await() + val response = try { + networkService.client + .newCall(GET("${REPO_URL_PREFIX}index.min.json")) + .await() + } catch (e: Throwable) { + logcat(LogPriority.ERROR, e) { "Failed to get extensions from GitHub" } + requiresFallbackSource = true + + networkService.client + .newCall(GET("${FALLBACK_REPO_URL_PREFIX}index.min.json")) + .await() + } + + val extensions = response .parseAs>() .toExtensions() /* SY --> */ + preferences.extensionRepos() .get() .flatMap { repoPath -> - val url = "$BASE_URL$repoPath/repo/" + val url = if (requiresFallbackSource) { + "$FALLBACK_BASE_URL$repoPath@repo/" + } else { + "$BASE_URL$repoPath/repo/" + } networkService.client .newCall(GET("${url}index.min.json")) .await() .parseAs>() - .toExtensions(url) + .toExtensions(url, repoSource = true) } // SY <-- @@ -85,7 +104,12 @@ internal class ExtensionGithubApi { return extensionsWithUpdate } - private fun List.toExtensions(/* SY --> */ repoUrl: String = REPO_URL_PREFIX /* SY <-- */): List { + private fun List.toExtensions( + // SY --> + repoUrl: String = getUrlPrefix(), + repoSource: Boolean = false + // SY <-- + ): List { return this .filter { val libVersion = it.version.substringBeforeLast('.').toDouble() @@ -106,6 +130,7 @@ internal class ExtensionGithubApi { iconUrl = "${/* SY --> */ repoUrl /* SY <-- */}icon/${it.apk.replace(".apk", ".png")}", // SY --> repoUrl = repoUrl, + isRepoSource = repoSource // SY <-- ) } @@ -125,6 +150,14 @@ internal class ExtensionGithubApi { return /* SY --> */ "${extension.repoUrl}/apk/${extension.apkName}" // SY <-- } + private fun getUrlPrefix(): String { + return if (requiresFallbackSource) { + FALLBACK_REPO_URL_PREFIX + } else { + REPO_URL_PREFIX + } + } + // SY --> private fun Extension.isBlacklisted( blacklistEnabled: Boolean = preferences.enableSourceBlacklist().get(), @@ -134,8 +167,10 @@ internal class ExtensionGithubApi { // SY <-- } -const val BASE_URL = "https://raw.githubusercontent.com/" -const val REPO_URL_PREFIX = "${BASE_URL}tachiyomiorg/tachiyomi-extensions/repo/" +private const val BASE_URL = "https://raw.githubusercontent.com/" +private const val REPO_URL_PREFIX = "${BASE_URL}tachiyomiorg/tachiyomi-extensions/repo/" +private const val FALLBACK_BASE_URL = "https://cdn.jsdelivr.net/gh/" +private const val FALLBACK_REPO_URL_PREFIX = "${FALLBACK_BASE_URL}tachiyomiorg/tachiyomi-extensions@repo/" @Serializable private data class ExtensionJsonObject( diff --git a/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt b/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt index c93bf8987..09830001f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/extension/model/Extension.kt @@ -48,6 +48,7 @@ sealed class Extension { val iconUrl: String, // SY --> val repoUrl: String, + val isRepoSource: Boolean, // SY <-- ) : Extension()