Introduce AppUpdater
This commit is contained in:
1 parent
5570933be4
commit
a8c96fa7df
4 files changed
+96
-81
No files matched your search
@@ -29,34 +29,21 @@ import com.hippo.ehviewer.AppConfig
|
||||
import com.hippo.ehviewer.BuildConfig
|
||||
import com.hippo.ehviewer.R
|
||||
import com.hippo.ehviewer.Settings
|
||||
import com.hippo.ehviewer.client.execute
|
||||
import com.hippo.ehviewer.client.executeAndParseAs
|
||||
import com.hippo.ehviewer.ui.LICENSE_SCREEN
|
||||
import com.hippo.ehviewer.ui.LocalNavController
|
||||
import com.hippo.ehviewer.ui.tools.DialogState
|
||||
import com.hippo.ehviewer.ui.tools.rememberDialogState
|
||||
import com.hippo.ehviewer.ui.tools.toAnnotatedString
|
||||
import com.hippo.ehviewer.updater.AppUpdater
|
||||
import com.hippo.ehviewer.util.ExceptionUtils
|
||||
import com.hippo.ehviewer.util.installPackage
|
||||
import eu.kanade.tachiyomi.util.lang.withUIContext
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import io.ktor.util.encodeBase64
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.launch
|
||||
import moe.tarsin.coroutines.runSuspendCatching
|
||||
import okhttp3.Request
|
||||
import okio.sink
|
||||
import org.json.JSONObject
|
||||
import tachiyomi.data.release.GithubArtifacts
|
||||
import tachiyomi.data.release.GithubCommitComparison
|
||||
import tachiyomi.data.release.GithubRelease
|
||||
import tachiyomi.data.release.GithubWorkflowRuns
|
||||
import java.io.File
|
||||
import java.util.zip.ZipInputStream
|
||||
|
||||
private const val REPO_NAME = BuildConfig.REPO_NAME
|
||||
private const val REPO_URL = "https://github.com/$REPO_NAME"
|
||||
private const val API_URL = "https://api.github.com/repos/$REPO_NAME"
|
||||
private const val REPO_URL = "https://github.com/${BuildConfig.REPO_NAME}"
|
||||
private const val RELEASE_URL = "$REPO_URL/releases"
|
||||
|
||||
@Composable
|
||||
@@ -97,7 +84,7 @@ fun AboutScreen() {
|
||||
}
|
||||
}
|
||||
if (download) {
|
||||
val file = File(AppConfig.tempDir, "tmp.apk").apply { delete() }
|
||||
val file = File(AppConfig.tempDir, "update.apk").apply { delete() }
|
||||
downloadTo(file)
|
||||
withUIContext { context.installPackage(file) }
|
||||
}
|
||||
@@ -146,58 +133,11 @@ fun AboutScreen() {
|
||||
)
|
||||
WorkPreference(title = stringResource(id = R.string.settings_about_check_for_updates)) {
|
||||
runSuspendCatching {
|
||||
if (Settings.useCIUpdateChannel) {
|
||||
val curSha = BuildConfig.COMMIT_SHA
|
||||
val branch = ghRequest(API_URL).execute {
|
||||
JSONObject(body.string()).getString("default_branch")
|
||||
AppUpdater.checkForUpdate(true)?.run {
|
||||
dialogState.showNewVersion(version, changelog) { file ->
|
||||
AppUpdater.downloadUpdate(downloadLink, file)
|
||||
}
|
||||
val workflowRunsUrl = "$API_URL/actions/workflows/ci.yml/runs?branch=$branch&per_page=1"
|
||||
val workflowRun = ghRequest(workflowRunsUrl).executeAndParseAs<GithubWorkflowRuns>().workflowRuns[0]
|
||||
val shortSha = workflowRun.headSha.take(7)
|
||||
if (shortSha != curSha) {
|
||||
val artifacts = ghRequest(workflowRun.artifactsUrl).executeAndParseAs<GithubArtifacts>()
|
||||
if (artifacts.artifacts.isNotEmpty()) {
|
||||
val archiveUrl = artifacts.getDownloadLink()
|
||||
val changelog = runSuspendCatching {
|
||||
val commitComparisonUrl = "$API_URL/compare/$curSha...$shortSha"
|
||||
val result = ghRequest(commitComparisonUrl).executeAndParseAs<GithubCommitComparison>()
|
||||
result.commits.joinToString("\n") { "${it.commit.message} (@${it.author.name})" }
|
||||
}.getOrDefault(workflowRun.title)
|
||||
dialogState.showNewVersion(shortSha, changelog) { file ->
|
||||
ghRequest(archiveUrl).execute {
|
||||
ZipInputStream(body.byteStream()).use { zip ->
|
||||
zip.nextEntry
|
||||
file.outputStream().use {
|
||||
zip.copyTo(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
launchSnackBar(context.getString(R.string.ci_is_running))
|
||||
}
|
||||
} else {
|
||||
launchSnackBar(context.getString(R.string.already_latest_ci_build))
|
||||
}
|
||||
} else {
|
||||
val curVersion = BuildConfig.VERSION_NAME
|
||||
val releaseUrl = "$API_URL/releases/latest"
|
||||
val release = ghRequest(releaseUrl).executeAndParseAs<GithubRelease>()
|
||||
val latestVersion = release.version
|
||||
val description = release.info
|
||||
val downloadUrl = release.getDownloadLink()
|
||||
if (latestVersion != curVersion) {
|
||||
dialogState.showNewVersion(latestVersion, description) { file ->
|
||||
ghRequest(downloadUrl).execute {
|
||||
file.sink().use {
|
||||
body.source().readAll(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
launchSnackBar(context.getString(R.string.already_latest_release, latestVersion))
|
||||
}
|
||||
}
|
||||
} ?: launchSnackBar(context.getString(R.string.already_latest_version))
|
||||
}.onFailure {
|
||||
launchSnackBar(ExceptionUtils.getReadableString(it))
|
||||
}
|
||||
@@ -205,11 +145,3 @@ fun AboutScreen() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun ghRequest(url: String, builder: Request.Builder.() -> Unit = {}) = Request.Builder().url(url).apply {
|
||||
logcat { url }
|
||||
val token = "github_" + "pat_11AXZS" + "T4A0k3TArCGakP3t_7DzUE5S" + "mr1zw8rmmzVtCeRq62" + "A4qkuDMw6YQm5ZUtHSLZ2MLI3J4VSifLXZ"
|
||||
val user = "nullArrayList"
|
||||
val base64 = "$user:$token".encodeBase64()
|
||||
addHeader("Authorization", "Basic $base64")
|
||||
}.apply(builder).build()
|
||||
@@ -0,0 +1,87 @@
|
||||
package com.hippo.ehviewer.updater
|
||||
|
||||
import com.hippo.ehviewer.BuildConfig
|
||||
import com.hippo.ehviewer.Settings
|
||||
import com.hippo.ehviewer.client.execute
|
||||
import com.hippo.ehviewer.client.executeAndParseAs
|
||||
import eu.kanade.tachiyomi.util.system.logcat
|
||||
import io.ktor.util.encodeBase64
|
||||
import moe.tarsin.coroutines.runSuspendCatching
|
||||
import okhttp3.Request
|
||||
import okio.sink
|
||||
import org.json.JSONObject
|
||||
import tachiyomi.data.release.GithubArtifacts
|
||||
import tachiyomi.data.release.GithubCommitComparison
|
||||
import tachiyomi.data.release.GithubRelease
|
||||
import tachiyomi.data.release.GithubWorkflowRuns
|
||||
import java.io.File
|
||||
import java.util.zip.ZipInputStream
|
||||
|
||||
private const val API_URL = "https://api.github.com/repos/${BuildConfig.REPO_NAME}"
|
||||
private const val LATEST_RELEASE_URL = "$API_URL/releases/latest"
|
||||
|
||||
object AppUpdater {
|
||||
suspend fun checkForUpdate(forceCheck: Boolean = false): Release? {
|
||||
if (forceCheck) {
|
||||
if (Settings.useCIUpdateChannel) {
|
||||
val curSha = BuildConfig.COMMIT_SHA
|
||||
val branch = ghRequest(API_URL).execute {
|
||||
JSONObject(body.string()).getString("default_branch")
|
||||
}
|
||||
val workflowRunsUrl = "$API_URL/actions/workflows/ci.yml/runs?branch=$branch&status=success&per_page=1"
|
||||
val workflowRun = ghRequest(workflowRunsUrl).executeAndParseAs<GithubWorkflowRuns>().workflowRuns[0]
|
||||
val shortSha = workflowRun.headSha.take(7)
|
||||
if (shortSha != curSha) {
|
||||
val artifacts = ghRequest(workflowRun.artifactsUrl).executeAndParseAs<GithubArtifacts>()
|
||||
val archiveUrl = artifacts.getDownloadLink()
|
||||
val changelog = runSuspendCatching {
|
||||
val commitComparisonUrl = "$API_URL/compare/$curSha...$shortSha"
|
||||
val result = ghRequest(commitComparisonUrl).executeAndParseAs<GithubCommitComparison>()
|
||||
result.commits.joinToString("\n") { "${it.commit.message} (@${it.author.name})" }
|
||||
}.getOrDefault(workflowRun.title)
|
||||
return Release(shortSha, changelog, archiveUrl)
|
||||
}
|
||||
} else {
|
||||
val curVersion = BuildConfig.VERSION_NAME
|
||||
val release = ghRequest(LATEST_RELEASE_URL).executeAndParseAs<GithubRelease>()
|
||||
val latestVersion = release.version
|
||||
val description = release.info
|
||||
val downloadUrl = release.getDownloadLink()
|
||||
if (latestVersion != curVersion) {
|
||||
return Release(latestVersion, description, downloadUrl)
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
suspend fun downloadUpdate(url: String, file: File) =
|
||||
ghRequest(url).execute {
|
||||
if (url.endsWith("zip")) {
|
||||
ZipInputStream(body.byteStream()).use { zip ->
|
||||
zip.nextEntry
|
||||
file.outputStream().use {
|
||||
zip.copyTo(it)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
file.sink().use {
|
||||
body.source().readAll(it)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private inline fun ghRequest(url: String, builder: Request.Builder.() -> Unit = {}) = Request.Builder().url(url).apply {
|
||||
logcat { url }
|
||||
val token = "github_" + "pat_11AXZS" + "T4A0k3TArCGakP3t_7DzUE5S" + "mr1zw8rmmzVtCeRq62" + "A4qkuDMw6YQm5ZUtHSLZ2MLI3J4VSifLXZ"
|
||||
val user = "nullArrayList"
|
||||
val base64 = "$user:$token".encodeBase64()
|
||||
addHeader("Authorization", "Basic $base64")
|
||||
}.apply(builder).build()
|
||||
|
||||
data class Release(
|
||||
val version: String,
|
||||
val changelog: String,
|
||||
val downloadLink: String,
|
||||
)
|
||||
@@ -511,9 +511,7 @@
|
||||
<string name="account_name">账户</string>
|
||||
<string name="preload_thumb_aggressively">激进地预载缩略图</string>
|
||||
<string name="new_version_available">有新版本!</string>
|
||||
<string name="ci_is_running">CI 正在运行,请稍候</string>
|
||||
<string name="already_latest_ci_build">已是最新 CI 构建</string>
|
||||
<string name="already_latest_release">已是最新版本 %s</string>
|
||||
<string name="already_latest_version">已是最新版本</string>
|
||||
<!-- Tachiyomi Reader Start-->
|
||||
<string name="action_settings">设置</string>
|
||||
<string name="action_retry">重试</string>
|
||||
|
||||
@@ -574,9 +574,7 @@
|
||||
<string name="account_name">Account</string>
|
||||
<string name="preload_thumb_aggressively">Preload thumbs aggressively</string>
|
||||
<string name="new_version_available">New version available!</string>
|
||||
<string name="ci_is_running">CI is still running, please wait</string>
|
||||
<string name="already_latest_ci_build">Already latest CI build</string>
|
||||
<string name="already_latest_release">Already latest Release %s</string>
|
||||
<string name="already_latest_version">Already the latest version</string>
|
||||
<!-- Tachiyomi Reader Start-->
|
||||
<string name="action_settings">Settings</string>
|
||||
<string name="pref_rotation_type">Default rotation type</string>
|
||||
|
||||
Reference in new issue
Block a user