Browse Source

Use jsDelivr as fallback when GitHub can't be reached for extensions (closes #5517)

Re-implementation of 24bb2f02dce135e0ceb2856618ecfc0e30dce875
arkon 2 years ago
parent
commit
d61bfd7caf

+ 29 - 5
app/src/main/java/eu/kanade/tachiyomi/extension/api/ExtensionGithubApi.kt

@@ -11,7 +11,9 @@ import eu.kanade.tachiyomi.network.NetworkHelper
 import eu.kanade.tachiyomi.network.await
 import eu.kanade.tachiyomi.network.parseAs
 import eu.kanade.tachiyomi.util.lang.withIOContext
+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
@@ -21,11 +23,24 @@ internal class ExtensionGithubApi {
     private val networkService: NetworkHelper by injectLazy()
     private val preferences: PreferencesHelper by injectLazy()
 
+    private var requiresFallbackSource = false
+
     suspend fun findExtensions(): List<Extension.Available> {
         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<List<ExtensionJsonObject>>()
                 .toExtensions()
 
@@ -85,7 +100,7 @@ internal class ExtensionGithubApi {
                     hasChangelog = it.hasChangelog == 1,
                     sources = it.sources?.toExtensionSources() ?: emptyList(),
                     apkName = it.apk,
-                    iconUrl = "${REPO_URL_PREFIX}icon/${it.apk.replace(".apk", ".png")}",
+                    iconUrl = "${getUrlPrefix()}icon/${it.apk.replace(".apk", ".png")}",
                 )
             }
     }
@@ -101,11 +116,20 @@ internal class ExtensionGithubApi {
     }
 
     fun getApkUrl(extension: Extension.Available): String {
-        return "${REPO_URL_PREFIX}apk/${extension.apkName}"
+        return "${getUrlPrefix()}apk/${extension.apkName}"
+    }
+
+    private fun getUrlPrefix(): String {
+        return if (requiresFallbackSource) {
+            FALLBACK_REPO_URL_PREFIX
+        } else {
+            REPO_URL_PREFIX
+        }
     }
 }
 
 private const val REPO_URL_PREFIX = "https://raw.githubusercontent.com/tachiyomiorg/tachiyomi-extensions/repo/"
+private const val FALLBACK_REPO_URL_PREFIX = "https://cdn.jsdelivr.net/gh/tachiyomiorg/tachiyomi-extensions@repo/"
 
 @Serializable
 private data class ExtensionJsonObject(