mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-07-03 19:04:39 -05:00
Extension repo fixes and improvements (#811)
This commit is contained in:
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@@ -11,7 +11,7 @@ I acknowledge that:
|
|||||||
|
|
||||||
- I have updated to the latest version of the app.
|
- I have updated to the latest version of the app.
|
||||||
- I have tried the troubleshooting guide described in `README.md`
|
- I have tried the troubleshooting guide described in `README.md`
|
||||||
- If this is a request for adding/changing an extension it should be brought up to Tachiyomi: https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose
|
- If this is a request for adding/changing an extension it should be brought up to your extension repo.
|
||||||
- If this is an issue with some extension not working properly, It does work inside Tachiyomi as intended.
|
- If this is an issue with some extension not working properly, It does work inside Tachiyomi as intended.
|
||||||
- I have searched the existing issues and this is a new ticket **NOT** a duplicate or related to another open issue
|
- I have searched the existing issues and this is a new ticket **NOT** a duplicate or related to another open issue
|
||||||
- I will fill out the title and the information in this template
|
- I will fill out the title and the information in this template
|
||||||
|
|||||||
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
2
.github/ISSUE_TEMPLATE/feature_request.md
vendored
@@ -11,7 +11,7 @@ I acknowledge that:
|
|||||||
|
|
||||||
- I have updated to the latest version of the app.
|
- I have updated to the latest version of the app.
|
||||||
- I have tried the troubleshooting guide described in `README.md`
|
- I have tried the troubleshooting guide described in `README.md`
|
||||||
- If this is a request for adding/changing an extension it should be brought up to Tachiyomi: https://github.com/tachiyomiorg/tachiyomi-extensions/issues/new/choose
|
- If this is a request for adding/changing an extension it should be brought up to your extension repo.
|
||||||
- If this is an issue with some extension not working properly, It does work in Tachiyomi application as intended.
|
- If this is an issue with some extension not working properly, It does work in Tachiyomi application as intended.
|
||||||
- I have searched the existing issues and this is a new ticket **NOT** a duplicate or related to another open issue
|
- I have searched the existing issues and this is a new ticket **NOT** a duplicate or related to another open issue
|
||||||
- I will fill out the title and the information in this template
|
- I will fill out the title and the information in this template
|
||||||
|
|||||||
@@ -61,7 +61,11 @@ object Extension {
|
|||||||
val extensionRecord = extensionTableAsDataClass().first { it.pkgName == pkgName }
|
val extensionRecord = extensionTableAsDataClass().first { it.pkgName == pkgName }
|
||||||
|
|
||||||
return installAPK {
|
return installAPK {
|
||||||
val apkURL = ExtensionGithubApi.getApkUrl(extensionRecord)
|
val apkURL =
|
||||||
|
ExtensionGithubApi.getApkUrl(
|
||||||
|
extensionRecord.repo ?: throw NullPointerException("Could not find extension repo"),
|
||||||
|
extensionRecord.apkName,
|
||||||
|
)
|
||||||
val apkName = Uri.parse(apkURL).lastPathSegment!!
|
val apkName = Uri.parse(apkURL).lastPathSegment!!
|
||||||
val apkSavePath = "${applicationDirs.extensionsRoot}/$apkName"
|
val apkSavePath = "${applicationDirs.extensionsRoot}/$apkName"
|
||||||
// download apk file
|
// download apk file
|
||||||
|
|||||||
@@ -36,9 +36,9 @@ object ExtensionsList {
|
|||||||
suspend fun fetchExtensions() {
|
suspend fun fetchExtensions() {
|
||||||
// update if 60 seconds has passed or requested offline and database is empty
|
// update if 60 seconds has passed or requested offline and database is empty
|
||||||
val extensions =
|
val extensions =
|
||||||
(listOf(ExtensionGithubApi.REPO_URL_PREFIX) + serverConfig.extensionRepos.value).map { repo ->
|
serverConfig.extensionRepos.value.map { repo ->
|
||||||
kotlin.runCatching {
|
kotlin.runCatching {
|
||||||
ExtensionGithubApi.findExtensions(repo)
|
ExtensionGithubApi.findExtensions(repo.repoUrlReplace())
|
||||||
}.onFailure {
|
}.onFailure {
|
||||||
logger.warn(it) {
|
logger.warn(it) {
|
||||||
"Failed to fetch extensions for repo: $repo"
|
"Failed to fetch extensions for repo: $repo"
|
||||||
@@ -119,8 +119,9 @@ object ExtensionsList {
|
|||||||
BatchUpdateStatement(ExtensionTable).apply {
|
BatchUpdateStatement(ExtensionTable).apply {
|
||||||
installedExtensionsToUpdate.forEach { (foundExtension, extensionRecord) ->
|
installedExtensionsToUpdate.forEach { (foundExtension, extensionRecord) ->
|
||||||
addBatch(EntityID(extensionRecord[ExtensionTable.id].value, ExtensionTable))
|
addBatch(EntityID(extensionRecord[ExtensionTable.id].value, ExtensionTable))
|
||||||
// Always update icon url
|
// Always update icon url and repo
|
||||||
this[ExtensionTable.iconUrl] = foundExtension.iconUrl
|
this[ExtensionTable.iconUrl] = foundExtension.iconUrl
|
||||||
|
this[ExtensionTable.repo] = foundExtension.repo
|
||||||
|
|
||||||
// add these because batch updates need matching columns
|
// add these because batch updates need matching columns
|
||||||
this[ExtensionTable.hasUpdate] = extensionRecord[ExtensionTable.hasUpdate]
|
this[ExtensionTable.hasUpdate] = extensionRecord[ExtensionTable.hasUpdate]
|
||||||
@@ -199,4 +200,23 @@ object ExtensionsList {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun String.repoUrlReplace(): String {
|
||||||
|
return if (contains("github")) {
|
||||||
|
replace(repoMatchRegex) {
|
||||||
|
"https://raw.githubusercontent.com/${it.groupValues[2]}/${it.groupValues[3]}/" +
|
||||||
|
(it.groupValues.getOrNull(4)?.ifBlank { null } ?: "repo") +
|
||||||
|
"/" +
|
||||||
|
(it.groupValues.getOrNull(5)?.ifBlank { null } ?: "index.min.json")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val repoMatchRegex =
|
||||||
|
(
|
||||||
|
"https:\\/\\/(?>www\\.|raw\\.)?(github|githubusercontent)\\.com" +
|
||||||
|
"\\/([^\\/]+)\\/([^\\/]+)(?>(?>\\/tree|\\/blob)?\\/([^\\/\\n]*))?(?>\\/([^\\/\\n]*\\.json)?)?"
|
||||||
|
).toRegex()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,12 +16,9 @@ import kotlinx.serialization.json.Json
|
|||||||
import mu.KotlinLogging
|
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 uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
|
|
||||||
object ExtensionGithubApi {
|
object ExtensionGithubApi {
|
||||||
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 {}
|
private val logger = KotlinLogging.logger {}
|
||||||
private val json: Json by injectLazy()
|
private val json: Json by injectLazy()
|
||||||
|
|
||||||
@@ -47,36 +44,22 @@ object ExtensionGithubApi {
|
|||||||
val baseUrl: String,
|
val baseUrl: String,
|
||||||
)
|
)
|
||||||
|
|
||||||
private var requiresFallbackSource = false
|
|
||||||
|
|
||||||
suspend fun findExtensions(repo: String): List<OnlineExtension> {
|
suspend fun findExtensions(repo: String): List<OnlineExtension> {
|
||||||
val githubResponse =
|
|
||||||
if (requiresFallbackSource) {
|
|
||||||
null
|
|
||||||
} else {
|
|
||||||
try {
|
|
||||||
client.newCall(GET("${repo.repoUrlReplace()}index.min.json")).awaitSuccess()
|
|
||||||
} catch (e: Throwable) {
|
|
||||||
logger.error(e) { "Failed to get extensions from GitHub" }
|
|
||||||
requiresFallbackSource = true
|
|
||||||
null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val response =
|
val response =
|
||||||
githubResponse ?: run {
|
client.newCall(GET(repo)).awaitSuccess()
|
||||||
client.newCall(GET("${repo.fallbackRepoUrlReplace()}index.min.json")).awaitSuccess()
|
|
||||||
}
|
|
||||||
|
|
||||||
return with(json) {
|
return with(json) {
|
||||||
response
|
response
|
||||||
.parseAs<List<ExtensionJsonObject>>()
|
.parseAs<List<ExtensionJsonObject>>()
|
||||||
.toExtensions(repo.repoUrlReplace())
|
.toExtensions(repo.substringBeforeLast('/') + '/')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getApkUrl(extension: ExtensionDataClass): String {
|
fun getApkUrl(
|
||||||
return "${extension.repo!!.repoUrlReplace()}/apk/${extension.apkName}"
|
repo: String,
|
||||||
|
apkName: String,
|
||||||
|
): String {
|
||||||
|
return "${repo}apk/$apkName"
|
||||||
}
|
}
|
||||||
|
|
||||||
private val client by lazy {
|
private val client by lazy {
|
||||||
@@ -125,22 +108,4 @@ object ExtensionGithubApi {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun String.repoUrlReplace() =
|
|
||||||
replace(repoMatchRegex) {
|
|
||||||
"https://raw.githubusercontent.com/${it.groupValues[1]}/${it.groupValues[2]}/" +
|
|
||||||
"${it.groupValues.getOrNull(3)?.ifBlank { null } ?: "repo"}/"
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun String.fallbackRepoUrlReplace() =
|
|
||||||
replace(repoMatchRegex) {
|
|
||||||
"https://gcore.jsdelivr.net/gh/${it.groupValues[1]}/${it.groupValues[2]}@" +
|
|
||||||
"${it.groupValues.getOrNull(3)?.ifBlank { null } ?: "repo"}/"
|
|
||||||
}
|
|
||||||
|
|
||||||
private val repoMatchRegex =
|
|
||||||
(
|
|
||||||
"https:\\/\\/(?:www|raw)?(?:github|githubusercontent)\\.com" +
|
|
||||||
"\\/([^\\/]+)\\/([^\\/]+)(?:\\/(?:tree|blob)\\/(.*))?\\/?"
|
|
||||||
).toRegex()
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,9 +43,6 @@ object PackageTools {
|
|||||||
const val LIB_VERSION_MIN = 1.3
|
const val LIB_VERSION_MIN = 1.3
|
||||||
const val LIB_VERSION_MAX = 1.5
|
const val LIB_VERSION_MAX = 1.5
|
||||||
|
|
||||||
private const val OFFICIAL_SIGNATURE = "7ce04da7773d41b489f4693a366c36bcd0a11fc39b547168553c285bd7348e23" // inorichi's key
|
|
||||||
val trustedSignatures = setOf(OFFICIAL_SIGNATURE)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert dex to jar, a wrapper for the dex2jar library
|
* Convert dex to jar, a wrapper for the dex2jar library
|
||||||
*/
|
*/
|
||||||
|
|||||||
Reference in New Issue
Block a user