mirror of
				https://github.com/mihonapp/mihon.git
				synced 2025-10-31 06:17:57 +01:00 
			
		
		
		
	Use coroutines for updater
This commit is contained in:
		| @@ -53,12 +53,11 @@ class TrackSearch : Track { | ||||
|         result = 31 * result + media_id | ||||
|         return result | ||||
|     } | ||||
|     companion object { | ||||
|  | ||||
|     companion object { | ||||
|         fun create(serviceId: Int): TrackSearch = TrackSearch().apply { | ||||
|             sync_id = serviceId | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -3,7 +3,6 @@ package eu.kanade.tachiyomi.data.updater | ||||
| import eu.kanade.tachiyomi.BuildConfig | ||||
| import eu.kanade.tachiyomi.data.updater.devrepo.DevRepoUpdateChecker | ||||
| import eu.kanade.tachiyomi.data.updater.github.GithubUpdateChecker | ||||
| import rx.Observable | ||||
|  | ||||
| abstract class UpdateChecker { | ||||
|  | ||||
| @@ -20,6 +19,6 @@ abstract class UpdateChecker { | ||||
|     /** | ||||
|      * 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.data.notification.Notifications | ||||
| import eu.kanade.tachiyomi.util.system.notificationManager | ||||
| import kotlinx.coroutines.runBlocking | ||||
|  | ||||
| class UpdaterJob : Job() { | ||||
|  | ||||
|     override fun onRunJob(params: Params): Result { | ||||
|         return UpdateChecker.getUpdateChecker() | ||||
|                 .checkForUpdate() | ||||
|                 .map { result -> | ||||
|                     if (result is UpdateResult.NewUpdate<*>) { | ||||
|                         val url = result.release.downloadLink | ||||
|         return runBlocking { | ||||
|             try { | ||||
|                 val result = UpdateChecker.getUpdateChecker().checkForUpdate() | ||||
|  | ||||
|                         val intent = Intent(context, UpdaterService::class.java).apply { | ||||
|                             putExtra(UpdaterService.EXTRA_DOWNLOAD_URL, url) | ||||
|                         } | ||||
|                 if (result is UpdateResult.NewUpdate<*>) { | ||||
|                     val url = result.release.downloadLink | ||||
|  | ||||
|                         NotificationCompat.Builder(context, Notifications.CHANNEL_COMMON).update { | ||||
|                             setContentTitle(context.getString(R.string.app_name)) | ||||
|                             setContentText(context.getString(R.string.update_check_notification_update_available)) | ||||
|                             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)) | ||||
|                         } | ||||
|                     val intent = Intent(context, UpdaterService::class.java).apply { | ||||
|                         putExtra(UpdaterService.EXTRA_DOWNLOAD_URL, url) | ||||
|                     } | ||||
|  | ||||
|                     NotificationCompat.Builder(context, Notifications.CHANNEL_COMMON).update { | ||||
|                         setContentTitle(context.getString(R.string.app_name)) | ||||
|                         setContentText(context.getString(R.string.update_check_notification_update_available)) | ||||
|                         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 } | ||||
|                 // Sadly, the task needs to be synchronous. | ||||
|                 .toBlocking() | ||||
|                 .single() | ||||
|                 Result.SUCCESS | ||||
|             } catch (e: Exception) { | ||||
|                 Result.FAILURE | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     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.network.GET | ||||
| import eu.kanade.tachiyomi.network.NetworkHelper | ||||
| import eu.kanade.tachiyomi.network.asObservable | ||||
| import eu.kanade.tachiyomi.network.await | ||||
| import okhttp3.OkHttpClient | ||||
| import rx.Observable | ||||
| import uy.kohesive.injekt.Injekt | ||||
| import uy.kohesive.injekt.api.get | ||||
|  | ||||
| @@ -23,18 +22,17 @@ class DevRepoUpdateChecker : UpdateChecker() { | ||||
|         Regex("tachiyomi-r(\\d+).apk") | ||||
|     } | ||||
|  | ||||
|     override fun checkForUpdate(): Observable<UpdateResult> { | ||||
|         return client.newCall(GET(DevRepoRelease.LATEST_URL)).asObservable() | ||||
|                 .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] | ||||
|     override suspend fun checkForUpdate(): UpdateResult { | ||||
|         val response = client.newCall(GET(DevRepoRelease.LATEST_URL)).await(assertSuccess = false) | ||||
|  | ||||
|                     if (latestVersionNumber.toInt() > BuildConfig.COMMIT_COUNT.toInt()) { | ||||
|                         DevRepoUpdateResult.NewUpdate(DevRepoRelease("v$latestVersionNumber")) | ||||
|                     } else { | ||||
|                         DevRepoUpdateResult.NoNewUpdate() | ||||
|                     } | ||||
|                 } | ||||
|         // Get latest repo version number from header in format "Location: tachiyomi-r1512.apk" | ||||
|         val latestVersionNumber: String = versionRegex.find(response.header("Location")!!)!!.groupValues[1] | ||||
|  | ||||
|         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.converter.gson.GsonConverterFactory | ||||
| import retrofit2.http.GET | ||||
| import rx.Observable | ||||
| import uy.kohesive.injekt.Injekt | ||||
| import uy.kohesive.injekt.api.get | ||||
|  | ||||
| @@ -28,6 +27,6 @@ interface GithubService { | ||||
|     } | ||||
|  | ||||
|     @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.data.updater.UpdateChecker | ||||
| import eu.kanade.tachiyomi.data.updater.UpdateResult | ||||
| import rx.Observable | ||||
|  | ||||
| class GithubUpdateChecker : UpdateChecker() { | ||||
|  | ||||
|     private val service: GithubService = GithubService.create() | ||||
|  | ||||
|     override fun checkForUpdate(): Observable<UpdateResult> { | ||||
|         return service.getLatestVersion().map { release -> | ||||
|             val newVersion = release.version.replace("[^\\d.]".toRegex(), "") | ||||
|     override suspend fun checkForUpdate(): UpdateResult { | ||||
|         val release = service.getLatestVersion() | ||||
|  | ||||
|             // Check if latest version is different from current version | ||||
|             if (newVersion != BuildConfig.VERSION_NAME) { | ||||
|                 GithubUpdateResult.NewUpdate(release) | ||||
|             } else { | ||||
|                 GithubUpdateResult.NoNewUpdate() | ||||
|             } | ||||
|         val newVersion = release.version.replace("[^\\d.]".toRegex(), "") | ||||
|  | ||||
|         // Check if latest version is different from current version | ||||
|         return if (newVersion != BuildConfig.VERSION_NAME) { | ||||
|             GithubUpdateResult.NewUpdate(release) | ||||
|         } else { | ||||
|             GithubUpdateResult.NoNewUpdate() | ||||
|         } | ||||
|     } | ||||
|  | ||||
|   | ||||
| @@ -48,11 +48,11 @@ fun Call.asObservable(): Observable<Response> { | ||||
| } | ||||
|  | ||||
| // 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 -> | ||||
|         enqueue(object : Callback { | ||||
|             override fun onResponse(call: Call, response: Response) { | ||||
|                 if (!response.isSuccessful) { | ||||
|                 if (assertSuccess && !response.isSuccessful) { | ||||
|                     continuation.resumeWithException(Exception("HTTP error ${response.code}")) | ||||
|                     return | ||||
|                 } | ||||
|   | ||||
| @@ -4,7 +4,6 @@ import android.app.Dialog | ||||
| import android.content.Intent | ||||
| import android.net.Uri | ||||
| import android.os.Bundle | ||||
| import android.view.View | ||||
| import androidx.preference.PreferenceScreen | ||||
| import com.afollestad.materialdialogs.MaterialDialog | ||||
| 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.ui.base.controller.DialogController | ||||
| 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.preference.* | ||||
| import eu.kanade.tachiyomi.util.system.toast | ||||
| import rx.Subscription | ||||
| import rx.android.schedulers.AndroidSchedulers | ||||
| import rx.schedulers.Schedulers | ||||
| import timber.log.Timber | ||||
| import uy.kohesive.injekt.injectLazy | ||||
| import java.text.DateFormat | ||||
| @@ -43,11 +41,6 @@ class SettingsAboutController : SettingsController() { | ||||
|  | ||||
|     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 | ||||
|  | ||||
|     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. | ||||
|      */ | ||||
| @@ -131,11 +118,11 @@ class SettingsAboutController : SettingsController() { | ||||
|         if (activity == null) return | ||||
|  | ||||
|         activity?.toast(R.string.update_check_look_for_updates) | ||||
|         releaseSubscription?.unsubscribe() | ||||
|         releaseSubscription = updateChecker.checkForUpdate() | ||||
|                 .subscribeOn(Schedulers.io()) | ||||
|                 .observeOn(AndroidSchedulers.mainThread()) | ||||
|                 .subscribe({ result -> | ||||
|  | ||||
|         launchIO { | ||||
|             try { | ||||
|                 val result = updateChecker.checkForUpdate() | ||||
|                 launchUI { | ||||
|                     when (result) { | ||||
|                         is UpdateResult.NewUpdate<*> -> { | ||||
|                             val body = result.release.info | ||||
| @@ -148,10 +135,14 @@ class SettingsAboutController : SettingsController() { | ||||
|                             activity?.toast(R.string.update_check_no_new_updates) | ||||
|                         } | ||||
|                     } | ||||
|                 }, { error -> | ||||
|                 } | ||||
|             } catch (error: Exception) { | ||||
|                 launchUI { | ||||
|                     activity?.toast(error.message) | ||||
|                     Timber.e(error) | ||||
|                 }) | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     class NewUpdateDialogController(bundle: Bundle? = null) : DialogController(bundle) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user