mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-07-01 01:44:34 -05:00
Use extension list fallback if extensions fail to fetch (#469)
This commit is contained in:
@@ -22,6 +22,7 @@ import suwayomi.tachidesk.manga.impl.extension.github.OnlineExtension
|
|||||||
import suwayomi.tachidesk.manga.model.dataclass.ExtensionDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.ExtensionDataClass
|
||||||
import suwayomi.tachidesk.manga.model.table.ExtensionTable
|
import suwayomi.tachidesk.manga.model.table.ExtensionTable
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
|
import kotlin.time.Duration.Companion.seconds
|
||||||
|
|
||||||
object ExtensionsList {
|
object ExtensionsList {
|
||||||
private val logger = KotlinLogging.logger {}
|
private val logger = KotlinLogging.logger {}
|
||||||
@@ -29,12 +30,9 @@ object ExtensionsList {
|
|||||||
var lastUpdateCheck: Long = 0
|
var lastUpdateCheck: Long = 0
|
||||||
var updateMap = ConcurrentHashMap<String, OnlineExtension>()
|
var updateMap = ConcurrentHashMap<String, OnlineExtension>()
|
||||||
|
|
||||||
/** 60,000 milliseconds = 60 seconds */
|
|
||||||
private const val ExtensionUpdateDelayTime = 60 * 1000
|
|
||||||
|
|
||||||
suspend fun getExtensionList(): List<ExtensionDataClass> {
|
suspend fun getExtensionList(): List<ExtensionDataClass> {
|
||||||
// update if {ExtensionUpdateDelayTime} seconds has passed or requested offline and database is empty
|
// update if 60 seconds has passed or requested offline and database is empty
|
||||||
if (lastUpdateCheck + ExtensionUpdateDelayTime < System.currentTimeMillis()) {
|
if (lastUpdateCheck + 60.seconds.inWholeMilliseconds < System.currentTimeMillis()) {
|
||||||
logger.debug("Getting extensions list from the internet")
|
logger.debug("Getting extensions list from the internet")
|
||||||
lastUpdateCheck = System.currentTimeMillis()
|
lastUpdateCheck = System.currentTimeMillis()
|
||||||
|
|
||||||
@@ -80,14 +78,14 @@ object ExtensionsList {
|
|||||||
updateMap.putIfAbsent(foundExtension.pkgName, foundExtension)
|
updateMap.putIfAbsent(foundExtension.pkgName, foundExtension)
|
||||||
}
|
}
|
||||||
foundExtension.versionCode < extensionRecord[ExtensionTable.versionCode] -> {
|
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 }) {
|
ExtensionTable.update({ ExtensionTable.pkgName eq foundExtension.pkgName }) {
|
||||||
it[isObsolete] = true
|
it[isObsolete] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} 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 }) {
|
ExtensionTable.update({ ExtensionTable.pkgName eq foundExtension.pkgName }) {
|
||||||
it[name] = foundExtension.name
|
it[name] = foundExtension.name
|
||||||
it[versionName] = foundExtension.versionName
|
it[versionName] = foundExtension.versionName
|
||||||
@@ -117,14 +115,14 @@ object ExtensionsList {
|
|||||||
ExtensionTable.selectAll().forEach { extensionRecord ->
|
ExtensionTable.selectAll().forEach { extensionRecord ->
|
||||||
val foundExtension = foundExtensions.find { it.pkgName == extensionRecord[ExtensionTable.pkgName] }
|
val foundExtension = foundExtensions.find { it.pkgName == extensionRecord[ExtensionTable.pkgName] }
|
||||||
if (foundExtension == null) {
|
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]) {
|
if (extensionRecord[ExtensionTable.isInstalled]) {
|
||||||
// is installed so we should mark it as obsolete
|
// is installed so we should mark it as obsolete
|
||||||
ExtensionTable.update({ ExtensionTable.pkgName eq extensionRecord[ExtensionTable.pkgName] }) {
|
ExtensionTable.update({ ExtensionTable.pkgName eq extensionRecord[ExtensionTable.pkgName] }) {
|
||||||
it[isObsolete] = true
|
it[isObsolete] = true
|
||||||
}
|
}
|
||||||
} else {
|
} 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] }
|
ExtensionTable.deleteWhere { ExtensionTable.pkgName eq extensionRecord[ExtensionTable.pkgName] }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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
|
* 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/. */
|
* 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.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.network.await
|
import eu.kanade.tachiyomi.network.await
|
||||||
import eu.kanade.tachiyomi.network.parseAs
|
import eu.kanade.tachiyomi.network.parseAs
|
||||||
import kotlinx.serialization.Serializable
|
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_MAX
|
||||||
import suwayomi.tachidesk.manga.impl.util.PackageTools.LIB_VERSION_MIN
|
import suwayomi.tachidesk.manga.impl.util.PackageTools.LIB_VERSION_MIN
|
||||||
import suwayomi.tachidesk.manga.model.dataclass.ExtensionDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.ExtensionDataClass
|
||||||
@@ -19,6 +20,8 @@ import uy.kohesive.injekt.injectLazy
|
|||||||
|
|
||||||
object ExtensionGithubApi {
|
object ExtensionGithubApi {
|
||||||
private const val REPO_URL_PREFIX = "https://raw.githubusercontent.com/tachiyomiorg/tachiyomi-extensions/repo/"
|
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
|
@Serializable
|
||||||
private data class ExtensionJsonObject(
|
private data class ExtensionJsonObject(
|
||||||
@@ -42,13 +45,26 @@ object ExtensionGithubApi {
|
|||||||
val baseUrl: String
|
val baseUrl: String
|
||||||
)
|
)
|
||||||
|
|
||||||
suspend fun findExtensions(): List<OnlineExtension> {
|
private var requiresFallbackSource = false
|
||||||
val request = Request.Builder()
|
|
||||||
.url("$REPO_URL_PREFIX/index.min.json")
|
|
||||||
.build()
|
|
||||||
|
|
||||||
return client.newCall(request)
|
suspend fun findExtensions(): List<OnlineExtension> {
|
||||||
.await()
|
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<List<ExtensionJsonObject>>()
|
.parseAs<List<ExtensionJsonObject>>()
|
||||||
.toExtensions()
|
.toExtensions()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user