Remove gson use for github updates + refactoring from up

Co-Authored-By: arkon <4098258+arkon@users.noreply.github.com>
This commit is contained in:
Jays2Kings 2022-04-19 20:01:54 -04:00
parent 06b2db1f60
commit 329d027995
10 changed files with 103 additions and 118 deletions

View file

@ -1,15 +1,72 @@
package eu.kanade.tachiyomi.data.updater
import eu.kanade.tachiyomi.data.updater.github.GithubAppUpdateChecker
import android.content.Context
import android.os.Build
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.NetworkHelper
import eu.kanade.tachiyomi.network.await
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.util.system.withIOContext
import uy.kohesive.injekt.injectLazy
import java.util.Date
import java.util.concurrent.TimeUnit
abstract class AppUpdateChecker {
class AppUpdateChecker {
companion object {
fun getUpdateChecker(): AppUpdateChecker = GithubAppUpdateChecker()
private val networkService: NetworkHelper by injectLazy()
private val preferences: PreferencesHelper by injectLazy()
suspend fun checkForUpdate(context: Context, isUserPrompt: Boolean = false, doExtrasAfterNewUpdate: Boolean = true): AppUpdateResult {
// Limit checks to once a day at most
if (!isUserPrompt && Date().time < preferences.lastAppCheck().get() + TimeUnit.DAYS.toMillis(1)) {
return AppUpdateResult.NoNewUpdate
}
return withIOContext {
val result = networkService.client
.newCall(GET("https://api.github.com/repos/$GITHUB_REPO/releases/latest"))
.await()
.parseAs<GithubRelease>()
.let {
preferences.lastAppCheck().set(Date().time)
// Check if latest version is different from current version
if (isNewVersion(it.version)) {
AppUpdateResult.NewUpdate(it)
} else {
AppUpdateResult.NoNewUpdate
}
}
if (doExtrasAfterNewUpdate && result is AppUpdateResult.NewUpdate) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
preferences.appShouldAutoUpdate() != AutoAppUpdaterJob.NEVER
) {
AutoAppUpdaterJob.setupTask(context)
}
AppUpdateNotifier(context).promptUpdate(
result.release.info,
result.release.downloadLink,
result.release.releaseLink
)
}
result
}
}
/**
* Returns suspended result containing release information
*/
abstract suspend fun checkForUpdate(): AppUpdateResult
private fun isNewVersion(versionTag: String): Boolean {
// Removes prefixes like "r" or "v"
val newVersion = versionTag.replace("[^\\d.]".toRegex(), "")
return newVersion != BuildConfig.VERSION_NAME
}
}
val RELEASE_TAG: String by lazy {
"v${BuildConfig.VERSION_NAME}"
}
const val GITHUB_REPO: String = "Jays2Kings/tachiyomiJ2K"
val RELEASE_URL = "https://github.com/$GITHUB_REPO/releases/tag/$RELEASE_TAG"

View file

@ -1,7 +1,6 @@
package eu.kanade.tachiyomi.data.updater
import android.content.Context
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.work.Constraints
import androidx.work.CoroutineWorker
@ -11,10 +10,9 @@ import androidx.work.PeriodicWorkRequestBuilder
import androidx.work.WorkManager
import androidx.work.WorkerParameters
import eu.kanade.tachiyomi.data.notification.Notifications
import eu.kanade.tachiyomi.data.preference.PreferencesHelper
import eu.kanade.tachiyomi.util.system.notificationManager
import kotlinx.coroutines.coroutineScope
import uy.kohesive.injekt.injectLazy
import timber.log.Timber
import java.util.concurrent.TimeUnit
class AppUpdateJob(private val context: Context, workerParams: WorkerParameters) :
@ -22,22 +20,10 @@ class AppUpdateJob(private val context: Context, workerParams: WorkerParameters)
override suspend fun doWork(): Result = coroutineScope {
try {
val preferences: PreferencesHelper by injectLazy()
val result = AppUpdateChecker.getUpdateChecker().checkForUpdate()
if (result is AppUpdateResult.NewUpdate<*>) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S &&
preferences.appShouldAutoUpdate() != AutoAppUpdaterJob.NEVER
) {
AutoAppUpdaterJob.setupTask(context)
}
AppUpdateNotifier(context).promptUpdate(
result.release.info,
result.release.downloadLink,
result.release.releaseLink
)
}
AppUpdateChecker().checkForUpdate(context)
Result.success()
} catch (e: Exception) {
Timber.e(e)
Result.failure()
}
}

View file

@ -1,7 +1,7 @@
package eu.kanade.tachiyomi.data.updater
abstract class AppUpdateResult {
sealed class AppUpdateResult {
open class NewUpdate<T : Release>(val release: T) : AppUpdateResult()
open class NoNewUpdate : AppUpdateResult()
class NewUpdate(val release: GithubRelease) : AppUpdateResult()
object NoNewUpdate : AppUpdateResult()
}

View file

@ -25,8 +25,8 @@ class AutoAppUpdaterJob(private val context: Context, workerParams: WorkerParame
) {
return@coroutineScope Result.failure()
}
val result = AppUpdateChecker.getUpdateChecker().checkForUpdate()
if (result is AppUpdateResult.NewUpdate<*> && !AppUpdateService.isRunning()) {
val result = AppUpdateChecker().checkForUpdate(context, doExtrasAfterNewUpdate = false)
if (result is AppUpdateResult.NewUpdate && !AppUpdateService.isRunning()) {
AppUpdateNotifier(context).cancel()
AppUpdateNotifier.releasePageUrl = result.release.releaseLink
AppUpdateService.start(context, result.release.downloadLink, false)

View file

@ -1,8 +1,8 @@
package eu.kanade.tachiyomi.data.updater.github
package eu.kanade.tachiyomi.data.updater
import android.os.Build
import com.google.gson.annotations.SerializedName
import eu.kanade.tachiyomi.data.updater.Release
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
/**
* Release object.
@ -12,11 +12,12 @@ import eu.kanade.tachiyomi.data.updater.Release
* @param info log of latest release.
* @param assets assets of latest release.
*/
class GithubRelease(
@SerializedName("tag_name") val version: String,
@SerializedName("body") override val info: String,
@SerializedName("html_url") override val releaseLink: String,
@SerializedName("assets") private val assets: List<Assets>
@Serializable
data class GithubRelease(
@SerialName("tag_name") val version: String,
@SerialName("body") override val info: String,
@SerialName("html_url") override val releaseLink: String,
@SerialName("assets") private val assets: List<Assets>
) : Release {
/**
@ -40,5 +41,6 @@ class GithubRelease(
* Assets class containing download url.
* @param downloadLink download url.
*/
inner class Assets(@SerializedName("browser_download_url") val downloadLink: String)
@Serializable
data class Assets(@SerialName("browser_download_url") val downloadLink: String)
}

View file

@ -1,22 +0,0 @@
package eu.kanade.tachiyomi.data.updater.github
import eu.kanade.tachiyomi.BuildConfig
import eu.kanade.tachiyomi.data.updater.AppUpdateChecker
import eu.kanade.tachiyomi.data.updater.AppUpdateResult
class GithubAppUpdateChecker : AppUpdateChecker() {
private val service: GithubService = GithubService.create()
override suspend fun checkForUpdate(): AppUpdateResult {
val release = service.getLatestVersion()
val newVersion = release.version.replace("[^\\d.]".toRegex(), "")
// Check if latest version is different from current version
return if (newVersion != BuildConfig.VERSION_NAME) {
GithubAppUpdateResult.NewUpdate(release)
} else {
GithubAppUpdateResult.NoNewUpdate()
}
}
}

View file

@ -1,9 +0,0 @@
package eu.kanade.tachiyomi.data.updater.github
import eu.kanade.tachiyomi.data.updater.AppUpdateResult
sealed class GithubAppUpdateResult : AppUpdateResult() {
class NewUpdate(release: GithubRelease) : AppUpdateResult.NewUpdate<GithubRelease>(release)
class NoNewUpdate : AppUpdateResult.NoNewUpdate()
}

View file

@ -1,29 +0,0 @@
package eu.kanade.tachiyomi.data.updater.github
import eu.kanade.tachiyomi.network.NetworkHelper
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import retrofit2.http.GET
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
/**
* Used to connect with the GitHub API.
*/
interface GithubService {
companion object {
fun create(): GithubService {
val restAdapter = Retrofit.Builder()
.baseUrl("https://api.github.com")
.addConverterFactory(GsonConverterFactory.create())
.client(Injekt.get<NetworkHelper>().client)
.build()
return restAdapter.create(GithubService::class.java)
}
}
@GET("/repos/Jays2Kings/tachiyomiJ2K/releases/latest")
suspend fun getLatestVersion(): GithubRelease
}

View file

@ -54,6 +54,7 @@ import eu.kanade.tachiyomi.data.preference.asImmediateFlowIn
import eu.kanade.tachiyomi.data.updater.AppUpdateChecker
import eu.kanade.tachiyomi.data.updater.AppUpdateNotifier
import eu.kanade.tachiyomi.data.updater.AppUpdateResult
import eu.kanade.tachiyomi.data.updater.RELEASE_TAG
import eu.kanade.tachiyomi.databinding.MainActivityBinding
import eu.kanade.tachiyomi.extension.ExtensionManager
import eu.kanade.tachiyomi.extension.api.ExtensionGithubApi
@ -78,6 +79,7 @@ import eu.kanade.tachiyomi.util.system.getResourceColor
import eu.kanade.tachiyomi.util.system.hasSideNavBar
import eu.kanade.tachiyomi.util.system.isBottomTappable
import eu.kanade.tachiyomi.util.system.isInNightMode
import eu.kanade.tachiyomi.util.system.launchIO
import eu.kanade.tachiyomi.util.system.launchUI
import eu.kanade.tachiyomi.util.system.prepareSideNavContext
import eu.kanade.tachiyomi.util.system.rootWindowInsetsCompat
@ -122,7 +124,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
private val hideBottomNav
get() = router.backstackSize > 1 && router.backstack[1].controller !is DialogController
private val updateChecker by lazy { AppUpdateChecker.getUpdateChecker() }
private val updateChecker by lazy { AppUpdateChecker() }
private val isUpdaterEnabled = BuildConfig.INCLUDE_UPDATER
private var tabAnimation: ValueAnimator? = null
private var overflowDialog: Dialog? = null
@ -504,7 +506,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
override fun onResume() {
super.onResume()
getAppUpdates()
checkForAppUpdates()
getExtensionUpdates(false)
setExtensionsBadge()
DownloadService.callListeners()
@ -550,15 +552,12 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
mangaShortcutManager.updateShortcuts()
}
private fun getAppUpdates() {
if (isUpdaterEnabled &&
Date().time >= preferences.lastAppCheck().get() + TimeUnit.DAYS.toMillis(1)
) {
lifecycleScope.launch(Dispatchers.IO) {
private fun checkForAppUpdates() {
if (isUpdaterEnabled) {
lifecycleScope.launchIO {
try {
val result = updateChecker.checkForUpdate()
preferences.lastAppCheck().set(Date().time)
if (result is AppUpdateResult.NewUpdate<*>) {
val result = updateChecker.checkForUpdate(this@MainActivity)
if (result is AppUpdateResult.NewUpdate) {
val body = result.release.info
val url = result.release.downloadLink
@ -934,7 +933,7 @@ open class MainActivity : BaseActivity<MainActivityBinding>(), DownloadServiceLi
try {
val intent = Intent(
Intent.ACTION_VIEW,
"https://github.com/jays2kings/tachiyomiJ2K/releases/tag/v${BuildConfig.VERSION_NAME}".toUri()
RELEASE_TAG.toUri()
)
startActivity(intent)
} catch (e: Throwable) {

View file

@ -14,6 +14,7 @@ import eu.kanade.tachiyomi.data.updater.AppUpdateChecker
import eu.kanade.tachiyomi.data.updater.AppUpdateNotifier
import eu.kanade.tachiyomi.data.updater.AppUpdateResult
import eu.kanade.tachiyomi.data.updater.AppUpdateService
import eu.kanade.tachiyomi.data.updater.RELEASE_URL
import eu.kanade.tachiyomi.ui.base.controller.DialogController
import eu.kanade.tachiyomi.util.lang.toTimestampString
import eu.kanade.tachiyomi.util.system.isOnline
@ -36,7 +37,7 @@ class AboutController : SettingsController() {
/**
* Checks for new releases
*/
private val updateChecker by lazy { AppUpdateChecker.getUpdateChecker() }
private val updateChecker by lazy { AppUpdateChecker() }
private val userPreferences: PreferencesHelper by injectLazy()
@ -58,7 +59,7 @@ class AboutController : SettingsController() {
if (BuildConfig.DEBUG) {
"https://github.com/Jays2Kings/tachiyomiJ2K/commits/master"
} else {
"https://github.com/Jays2Kings/tachiyomiJ2K/releases/tag/v${BuildConfig.VERSION_NAME}"
RELEASE_URL
}.toUri()
)
startActivity(intent)
@ -165,20 +166,20 @@ class AboutController : SettingsController() {
* Checks version and shows a user prompt if an update is available.
*/
private fun checkVersion() {
if (activity == null) return
val activity = activity ?: return
activity?.toast(R.string.searching_for_updates)
activity.toast(R.string.searching_for_updates)
viewScope.launch {
val result = try {
updateChecker.checkForUpdate()
updateChecker.checkForUpdate(activity, true)
} catch (error: Exception) {
withContext(Dispatchers.Main) {
activity?.toast(error.message)
activity.toast(error.message)
Timber.e(error)
}
}
when (result) {
is AppUpdateResult.NewUpdate<*> -> {
is AppUpdateResult.NewUpdate -> {
val body = result.release.info
val url = result.release.downloadLink
@ -190,7 +191,7 @@ class AboutController : SettingsController() {
}
is AppUpdateResult.NoNewUpdate -> {
withContext(Dispatchers.Main) {
activity?.toast(R.string.no_new_updates_available)
activity.toast(R.string.no_new_updates_available)
}
}
}