mirror of
https://github.com/tachiyomiorg/tachiyomi.git
synced 2024-12-22 21:41:50 +01:00
Use coroutines for updater
This commit is contained in:
parent
340829bb71
commit
6a95ff56df
@ -110,16 +110,16 @@ dependencies {
|
|||||||
// Android support library
|
// Android support library
|
||||||
implementation 'androidx.appcompat:appcompat:1.1.0'
|
implementation 'androidx.appcompat:appcompat:1.1.0'
|
||||||
implementation 'androidx.cardview:cardview:1.0.0'
|
implementation 'androidx.cardview:cardview:1.0.0'
|
||||||
implementation 'com.google.android.material:material:1.1.0'
|
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
||||||
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
implementation 'androidx.recyclerview:recyclerview:1.1.0'
|
||||||
implementation 'androidx.preference:preference:1.1.0'
|
implementation 'androidx.preference:preference:1.1.0'
|
||||||
implementation 'androidx.annotation:annotation:1.1.0'
|
implementation 'androidx.annotation:annotation:1.1.0'
|
||||||
implementation 'androidx.browser:browser:1.2.0'
|
implementation 'androidx.browser:browser:1.2.0'
|
||||||
|
|
||||||
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
|
|
||||||
|
|
||||||
implementation 'androidx.multidex:multidex:2.0.1'
|
implementation 'androidx.multidex:multidex:2.0.1'
|
||||||
|
|
||||||
|
// UI library
|
||||||
|
implementation 'com.google.android.material:material:1.1.0'
|
||||||
|
|
||||||
standardImplementation 'com.google.firebase:firebase-core:17.2.2'
|
standardImplementation 'com.google.firebase:firebase-core:17.2.2'
|
||||||
|
|
||||||
// ReactiveX
|
// ReactiveX
|
||||||
@ -221,7 +221,7 @@ dependencies {
|
|||||||
implementation "com.jakewharton.rxbinding:rxbinding-recyclerview-v7-kotlin:$rxbindings_version"
|
implementation "com.jakewharton.rxbinding:rxbinding-recyclerview-v7-kotlin:$rxbindings_version"
|
||||||
|
|
||||||
// Tests
|
// Tests
|
||||||
testImplementation 'junit:junit:4.12'
|
testImplementation 'junit:junit:4.13'
|
||||||
testImplementation 'org.assertj:assertj-core:1.7.1'
|
testImplementation 'org.assertj:assertj-core:1.7.1'
|
||||||
testImplementation 'org.mockito:mockito-core:1.10.19'
|
testImplementation 'org.mockito:mockito-core:1.10.19'
|
||||||
|
|
||||||
|
@ -53,12 +53,11 @@ class TrackSearch : Track {
|
|||||||
result = 31 * result + media_id
|
result = 31 * result + media_id
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
companion object {
|
|
||||||
|
|
||||||
|
companion object {
|
||||||
fun create(serviceId: Int): TrackSearch = TrackSearch().apply {
|
fun create(serviceId: Int): TrackSearch = TrackSearch().apply {
|
||||||
sync_id = serviceId
|
sync_id = serviceId
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.data.updater
|
|||||||
import eu.kanade.tachiyomi.BuildConfig
|
import eu.kanade.tachiyomi.BuildConfig
|
||||||
import eu.kanade.tachiyomi.data.updater.devrepo.DevRepoUpdateChecker
|
import eu.kanade.tachiyomi.data.updater.devrepo.DevRepoUpdateChecker
|
||||||
import eu.kanade.tachiyomi.data.updater.github.GithubUpdateChecker
|
import eu.kanade.tachiyomi.data.updater.github.GithubUpdateChecker
|
||||||
import rx.Observable
|
|
||||||
|
|
||||||
abstract class UpdateChecker {
|
abstract class UpdateChecker {
|
||||||
|
|
||||||
@ -20,6 +19,6 @@ abstract class UpdateChecker {
|
|||||||
/**
|
/**
|
||||||
* Returns observable containing release information
|
* Returns observable containing release information
|
||||||
*/
|
*/
|
||||||
abstract fun checkForUpdate(): Observable<UpdateResult>
|
abstract suspend fun checkForUpdate(): UpdateResult
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -9,36 +9,37 @@ import com.evernote.android.job.JobRequest
|
|||||||
import eu.kanade.tachiyomi.R
|
import eu.kanade.tachiyomi.R
|
||||||
import eu.kanade.tachiyomi.data.notification.Notifications
|
import eu.kanade.tachiyomi.data.notification.Notifications
|
||||||
import eu.kanade.tachiyomi.util.system.notificationManager
|
import eu.kanade.tachiyomi.util.system.notificationManager
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
|
|
||||||
class UpdaterJob : Job() {
|
class UpdaterJob : Job() {
|
||||||
|
|
||||||
override fun onRunJob(params: Params): Result {
|
override fun onRunJob(params: Params): Result {
|
||||||
return UpdateChecker.getUpdateChecker()
|
return runBlocking {
|
||||||
.checkForUpdate()
|
try {
|
||||||
.map { result ->
|
val result = UpdateChecker.getUpdateChecker().checkForUpdate()
|
||||||
if (result is UpdateResult.NewUpdate<*>) {
|
|
||||||
val url = result.release.downloadLink
|
|
||||||
|
|
||||||
val intent = Intent(context, UpdaterService::class.java).apply {
|
if (result is UpdateResult.NewUpdate<*>) {
|
||||||
putExtra(UpdaterService.EXTRA_DOWNLOAD_URL, url)
|
val url = result.release.downloadLink
|
||||||
}
|
|
||||||
|
|
||||||
NotificationCompat.Builder(context, Notifications.CHANNEL_COMMON).update {
|
val intent = Intent(context, UpdaterService::class.java).apply {
|
||||||
setContentTitle(context.getString(R.string.app_name))
|
putExtra(UpdaterService.EXTRA_DOWNLOAD_URL, url)
|
||||||
setContentText(context.getString(R.string.update_check_notification_update_available))
|
}
|
||||||
setSmallIcon(android.R.drawable.stat_sys_download_done)
|
|
||||||
// Download action
|
NotificationCompat.Builder(context, Notifications.CHANNEL_COMMON).update {
|
||||||
addAction(android.R.drawable.stat_sys_download_done,
|
setContentTitle(context.getString(R.string.app_name))
|
||||||
context.getString(R.string.action_download),
|
setContentText(context.getString(R.string.update_check_notification_update_available))
|
||||||
PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT))
|
setSmallIcon(android.R.drawable.stat_sys_download_done)
|
||||||
}
|
// Download action
|
||||||
|
addAction(android.R.drawable.stat_sys_download_done,
|
||||||
|
context.getString(R.string.action_download),
|
||||||
|
PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT))
|
||||||
}
|
}
|
||||||
Result.SUCCESS
|
|
||||||
}
|
}
|
||||||
.onErrorReturn { Result.FAILURE }
|
Result.SUCCESS
|
||||||
// Sadly, the task needs to be synchronous.
|
} catch (e: Exception) {
|
||||||
.toBlocking()
|
Result.FAILURE
|
||||||
.single()
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun NotificationCompat.Builder.update(block: NotificationCompat.Builder.() -> Unit) {
|
fun NotificationCompat.Builder.update(block: NotificationCompat.Builder.() -> Unit) {
|
||||||
|
@ -5,9 +5,8 @@ import eu.kanade.tachiyomi.data.updater.UpdateChecker
|
|||||||
import eu.kanade.tachiyomi.data.updater.UpdateResult
|
import eu.kanade.tachiyomi.data.updater.UpdateResult
|
||||||
import eu.kanade.tachiyomi.network.GET
|
import eu.kanade.tachiyomi.network.GET
|
||||||
import eu.kanade.tachiyomi.network.NetworkHelper
|
import eu.kanade.tachiyomi.network.NetworkHelper
|
||||||
import eu.kanade.tachiyomi.network.asObservable
|
import eu.kanade.tachiyomi.network.await
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import rx.Observable
|
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
@ -23,18 +22,17 @@ class DevRepoUpdateChecker : UpdateChecker() {
|
|||||||
Regex("tachiyomi-r(\\d+).apk")
|
Regex("tachiyomi-r(\\d+).apk")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun checkForUpdate(): Observable<UpdateResult> {
|
override suspend fun checkForUpdate(): UpdateResult {
|
||||||
return client.newCall(GET(DevRepoRelease.LATEST_URL)).asObservable()
|
val response = client.newCall(GET(DevRepoRelease.LATEST_URL)).await(assertSuccess = false)
|
||||||
.map { response ->
|
|
||||||
// Get latest repo version number from header in format "Location: tachiyomi-r1512.apk"
|
|
||||||
val latestVersionNumber: String = versionRegex.find(response.header("Location")!!)!!.groupValues[1]
|
|
||||||
|
|
||||||
if (latestVersionNumber.toInt() > BuildConfig.COMMIT_COUNT.toInt()) {
|
// Get latest repo version number from header in format "Location: tachiyomi-r1512.apk"
|
||||||
DevRepoUpdateResult.NewUpdate(DevRepoRelease("v$latestVersionNumber"))
|
val latestVersionNumber: String = versionRegex.find(response.header("Location")!!)!!.groupValues[1]
|
||||||
} else {
|
|
||||||
DevRepoUpdateResult.NoNewUpdate()
|
return if (latestVersionNumber.toInt() > BuildConfig.COMMIT_COUNT.toInt()) {
|
||||||
}
|
DevRepoUpdateResult.NewUpdate(DevRepoRelease("v$latestVersionNumber"))
|
||||||
}
|
} else {
|
||||||
|
DevRepoUpdateResult.NoNewUpdate()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ import retrofit2.Retrofit
|
|||||||
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory
|
import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory
|
||||||
import retrofit2.converter.gson.GsonConverterFactory
|
import retrofit2.converter.gson.GsonConverterFactory
|
||||||
import retrofit2.http.GET
|
import retrofit2.http.GET
|
||||||
import rx.Observable
|
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
@ -28,6 +27,6 @@ interface GithubService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@GET("/repos/inorichi/tachiyomi/releases/latest")
|
@GET("/repos/inorichi/tachiyomi/releases/latest")
|
||||||
fun getLatestVersion(): Observable<GithubRelease>
|
suspend fun getLatestVersion(): GithubRelease
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,22 +3,21 @@ package eu.kanade.tachiyomi.data.updater.github
|
|||||||
import eu.kanade.tachiyomi.BuildConfig
|
import eu.kanade.tachiyomi.BuildConfig
|
||||||
import eu.kanade.tachiyomi.data.updater.UpdateChecker
|
import eu.kanade.tachiyomi.data.updater.UpdateChecker
|
||||||
import eu.kanade.tachiyomi.data.updater.UpdateResult
|
import eu.kanade.tachiyomi.data.updater.UpdateResult
|
||||||
import rx.Observable
|
|
||||||
|
|
||||||
class GithubUpdateChecker : UpdateChecker() {
|
class GithubUpdateChecker : UpdateChecker() {
|
||||||
|
|
||||||
private val service: GithubService = GithubService.create()
|
private val service: GithubService = GithubService.create()
|
||||||
|
|
||||||
override fun checkForUpdate(): Observable<UpdateResult> {
|
override suspend fun checkForUpdate(): UpdateResult {
|
||||||
return service.getLatestVersion().map { release ->
|
val release = service.getLatestVersion()
|
||||||
val newVersion = release.version.replace("[^\\d.]".toRegex(), "")
|
|
||||||
|
|
||||||
// Check if latest version is different from current version
|
val newVersion = release.version.replace("[^\\d.]".toRegex(), "")
|
||||||
if (newVersion != BuildConfig.VERSION_NAME) {
|
|
||||||
GithubUpdateResult.NewUpdate(release)
|
// Check if latest version is different from current version
|
||||||
} else {
|
return if (newVersion != BuildConfig.VERSION_NAME) {
|
||||||
GithubUpdateResult.NoNewUpdate()
|
GithubUpdateResult.NewUpdate(release)
|
||||||
}
|
} else {
|
||||||
|
GithubUpdateResult.NoNewUpdate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,11 +48,11 @@ fun Call.asObservable(): Observable<Response> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Based on https://github.com/gildor/kotlin-coroutines-okhttp
|
// Based on https://github.com/gildor/kotlin-coroutines-okhttp
|
||||||
suspend fun Call.await(): Response {
|
suspend fun Call.await(assertSuccess: Boolean = false): Response {
|
||||||
return suspendCancellableCoroutine { continuation ->
|
return suspendCancellableCoroutine { continuation ->
|
||||||
enqueue(object : Callback {
|
enqueue(object : Callback {
|
||||||
override fun onResponse(call: Call, response: Response) {
|
override fun onResponse(call: Call, response: Response) {
|
||||||
if (!response.isSuccessful) {
|
if (assertSuccess && !response.isSuccessful) {
|
||||||
continuation.resumeWithException(Exception("HTTP error ${response.code}"))
|
continuation.resumeWithException(Exception("HTTP error ${response.code}"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,6 @@ import android.app.Dialog
|
|||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
|
||||||
import androidx.preference.PreferenceScreen
|
import androidx.preference.PreferenceScreen
|
||||||
import com.afollestad.materialdialogs.MaterialDialog
|
import com.afollestad.materialdialogs.MaterialDialog
|
||||||
import eu.kanade.tachiyomi.BuildConfig
|
import eu.kanade.tachiyomi.BuildConfig
|
||||||
@ -17,12 +16,11 @@ import eu.kanade.tachiyomi.data.updater.UpdaterJob
|
|||||||
import eu.kanade.tachiyomi.data.updater.UpdaterService
|
import eu.kanade.tachiyomi.data.updater.UpdaterService
|
||||||
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
import eu.kanade.tachiyomi.ui.base.controller.DialogController
|
||||||
import eu.kanade.tachiyomi.ui.main.ChangelogDialogController
|
import eu.kanade.tachiyomi.ui.main.ChangelogDialogController
|
||||||
|
import eu.kanade.tachiyomi.util.lang.launchIO
|
||||||
|
import eu.kanade.tachiyomi.util.lang.launchUI
|
||||||
import eu.kanade.tachiyomi.util.lang.toTimestampString
|
import eu.kanade.tachiyomi.util.lang.toTimestampString
|
||||||
import eu.kanade.tachiyomi.util.preference.*
|
import eu.kanade.tachiyomi.util.preference.*
|
||||||
import eu.kanade.tachiyomi.util.system.toast
|
import eu.kanade.tachiyomi.util.system.toast
|
||||||
import rx.Subscription
|
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
|
||||||
import rx.schedulers.Schedulers
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.text.DateFormat
|
import java.text.DateFormat
|
||||||
@ -43,11 +41,6 @@ class SettingsAboutController : SettingsController() {
|
|||||||
|
|
||||||
private val dateFormat: DateFormat = userPreferences.dateFormat().getOrDefault()
|
private val dateFormat: DateFormat = userPreferences.dateFormat().getOrDefault()
|
||||||
|
|
||||||
/**
|
|
||||||
* The subscribtion service of the obtained release object
|
|
||||||
*/
|
|
||||||
private var releaseSubscription: Subscription? = null
|
|
||||||
|
|
||||||
private val isUpdaterEnabled = BuildConfig.INCLUDE_UPDATER
|
private val isUpdaterEnabled = BuildConfig.INCLUDE_UPDATER
|
||||||
|
|
||||||
override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) {
|
override fun setupPreferenceScreen(screen: PreferenceScreen) = with(screen) {
|
||||||
@ -118,12 +111,6 @@ class SettingsAboutController : SettingsController() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onDestroyView(view: View) {
|
|
||||||
super.onDestroyView(view)
|
|
||||||
releaseSubscription?.unsubscribe()
|
|
||||||
releaseSubscription = null
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks version and shows a user prompt if an update is available.
|
* Checks version and shows a user prompt if an update is available.
|
||||||
*/
|
*/
|
||||||
@ -131,11 +118,11 @@ class SettingsAboutController : SettingsController() {
|
|||||||
if (activity == null) return
|
if (activity == null) return
|
||||||
|
|
||||||
activity?.toast(R.string.update_check_look_for_updates)
|
activity?.toast(R.string.update_check_look_for_updates)
|
||||||
releaseSubscription?.unsubscribe()
|
|
||||||
releaseSubscription = updateChecker.checkForUpdate()
|
launchIO {
|
||||||
.subscribeOn(Schedulers.io())
|
try {
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
val result = updateChecker.checkForUpdate()
|
||||||
.subscribe({ result ->
|
launchUI {
|
||||||
when (result) {
|
when (result) {
|
||||||
is UpdateResult.NewUpdate<*> -> {
|
is UpdateResult.NewUpdate<*> -> {
|
||||||
val body = result.release.info
|
val body = result.release.info
|
||||||
@ -148,10 +135,14 @@ class SettingsAboutController : SettingsController() {
|
|||||||
activity?.toast(R.string.update_check_no_new_updates)
|
activity?.toast(R.string.update_check_no_new_updates)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, { error ->
|
}
|
||||||
|
} catch (error: Exception) {
|
||||||
|
launchUI {
|
||||||
activity?.toast(error.message)
|
activity?.toast(error.message)
|
||||||
Timber.e(error)
|
Timber.e(error)
|
||||||
})
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class NewUpdateDialogController(bundle: Bundle? = null) : DialogController(bundle) {
|
class NewUpdateDialogController(bundle: Bundle? = null) : DialogController(bundle) {
|
||||||
|
Loading…
Reference in New Issue
Block a user