Move GitHub Release/App Update logic to data (#9422)

* Move GitHub Release/App Update logic to data

* Add tests for GetApplicationRelease

* Review changes
This commit is contained in:
Andreas
2023-04-30 04:14:49 +02:00
committed by GitHub
parent eed91f6360
commit 02864ebd60
18 changed files with 425 additions and 157 deletions

View File

@@ -0,0 +1,79 @@
package tachiyomi.domain.release.interactor
import tachiyomi.core.preference.Preference
import tachiyomi.core.preference.PreferenceStore
import tachiyomi.domain.release.model.Release
import tachiyomi.domain.release.service.ReleaseService
import java.time.Instant
import java.time.temporal.ChronoUnit
class GetApplicationRelease(
private val service: ReleaseService,
private val preferenceStore: PreferenceStore,
) {
private val lastChecked: Preference<Long> by lazy {
preferenceStore.getLong("last_app_check", 0)
}
suspend fun await(arguments: Arguments): Result {
val now = Instant.now()
// Limit checks to once every 3 days at most
if (arguments.forceCheck.not() && now.isBefore(Instant.ofEpochMilli(lastChecked.get()).plus(3, ChronoUnit.DAYS))) {
return Result.NoNewUpdate
}
val release = service.latest(arguments.repository)
lastChecked.set(now.toEpochMilli())
// Check if latest version is different from current version
val isNewVersion = isNewVersion(arguments.isPreview, arguments.commitCount, arguments.versionName, release.version)
return when {
isNewVersion && arguments.isThirdParty -> Result.ThirdPartyInstallation
isNewVersion -> Result.NewUpdate(release)
else -> Result.NoNewUpdate
}
}
private fun isNewVersion(isPreview: Boolean, commitCount: Int, versionName: String, versionTag: String): Boolean {
// Removes prefixes like "r" or "v"
val newVersion = versionTag.replace("[^\\d.]".toRegex(), "")
return if (isPreview) {
// Preview builds: based on releases in "tachiyomiorg/tachiyomi-preview" repo
// tagged as something like "r1234"
newVersion.toInt() > commitCount
} else {
// Release builds: based on releases in "tachiyomiorg/tachiyomi" repo
// tagged as something like "v0.1.2"
val oldVersion = versionName.replace("[^\\d.]".toRegex(), "")
val newSemVer = newVersion.split(".").map { it.toInt() }
val oldSemVer = oldVersion.split(".").map { it.toInt() }
oldSemVer.mapIndexed { index, i ->
if (newSemVer[index] > i) {
return true
}
}
false
}
}
data class Arguments(
val isPreview: Boolean,
val isThirdParty: Boolean,
val commitCount: Int,
val versionName: String,
val repository: String,
val forceCheck: Boolean = false,
)
sealed class Result {
class NewUpdate(val release: Release) : Result()
object NoNewUpdate : Result()
object ThirdPartyInstallation : Result()
}
}

View File

@@ -0,0 +1,35 @@
package tachiyomi.domain.release.model
import android.os.Build
/**
* Contains information about the latest release.
*/
data class Release(
val version: String,
val info: String,
val releaseLink: String,
private val assets: List<String>,
) {
/**
* Get download link of latest release from the assets.
* @return download link of latest release.
*/
fun getDownloadLink(): String {
val apkVariant = when (Build.SUPPORTED_ABIS[0]) {
"arm64-v8a" -> "-arm64-v8a"
"armeabi-v7a" -> "-armeabi-v7a"
"x86" -> "-x86"
"x86_64" -> "-x86_64"
else -> ""
}
return assets.find { it.contains("tachiyomi$apkVariant-") } ?: assets[0]
}
/**
* Assets class containing download url.
*/
data class Assets(val downloadLink: String)
}

View File

@@ -0,0 +1,8 @@
package tachiyomi.domain.release.service
import tachiyomi.domain.release.model.Release
interface ReleaseService {
suspend fun latest(repository: String): Release
}