Migrate extension list fetch to coroutine
This commit is contained in:
parent
3bb1c9efa7
commit
dc9545570d
@ -17,9 +17,7 @@ import uy.kohesive.injekt.injectLazy
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
class UpdaterService : IntentService(UpdaterService::class.java.name) {
|
class UpdaterService : IntentService(UpdaterService::class.java.name) {
|
||||||
/**
|
|
||||||
* Network helper
|
|
||||||
*/
|
|
||||||
private val network: NetworkHelper by injectLazy()
|
private val network: NetworkHelper by injectLazy()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -15,8 +15,6 @@ import eu.kanade.tachiyomi.source.SourceManager
|
|||||||
import eu.kanade.tachiyomi.util.system.launchNow
|
import eu.kanade.tachiyomi.util.system.launchNow
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.android.schedulers.AndroidSchedulers
|
|
||||||
import rx.schedulers.Schedulers
|
|
||||||
import uy.kohesive.injekt.Injekt
|
import uy.kohesive.injekt.Injekt
|
||||||
import uy.kohesive.injekt.api.get
|
import uy.kohesive.injekt.api.get
|
||||||
|
|
||||||
@ -146,11 +144,13 @@ class ExtensionManager(
|
|||||||
* Finds the available extensions in the [api] and updates [availableExtensions].
|
* Finds the available extensions in the [api] and updates [availableExtensions].
|
||||||
*/
|
*/
|
||||||
fun findAvailableExtensions() {
|
fun findAvailableExtensions() {
|
||||||
|
launchNow {
|
||||||
|
availableExtensions = try {
|
||||||
api.findExtensions()
|
api.findExtensions()
|
||||||
.onErrorReturn { emptyList() }
|
} catch (e: Exception) {
|
||||||
.subscribeOn(Schedulers.io())
|
emptyList()
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
}
|
||||||
.subscribe { availableExtensions = it }
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,12 +13,10 @@ import eu.kanade.tachiyomi.extension.model.LoadResult
|
|||||||
import eu.kanade.tachiyomi.extension.util.ExtensionLoader
|
import eu.kanade.tachiyomi.extension.util.ExtensionLoader
|
||||||
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.asObservableSuccess
|
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.GlobalScope
|
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
|
import eu.kanade.tachiyomi.network.await
|
||||||
import okhttp3.Response
|
import okhttp3.Response
|
||||||
import rx.Observable
|
|
||||||
import uy.kohesive.injekt.injectLazy
|
import uy.kohesive.injekt.injectLazy
|
||||||
import java.lang.Exception
|
import java.lang.Exception
|
||||||
|
|
||||||
@ -26,23 +24,18 @@ internal class ExtensionGithubApi {
|
|||||||
|
|
||||||
private val network: NetworkHelper by injectLazy()
|
private val network: NetworkHelper by injectLazy()
|
||||||
|
|
||||||
private val client get() = network.client
|
|
||||||
|
|
||||||
private val gson: Gson by injectLazy()
|
private val gson: Gson by injectLazy()
|
||||||
|
|
||||||
private val repoUrl = "https://raw.githubusercontent.com/inorichi/tachiyomi-extensions/repo"
|
suspend fun findExtensions(): List<Extension.Available> {
|
||||||
|
val call = GET("$REPO_URL/index.json")
|
||||||
|
|
||||||
fun findExtensions(): Observable<List<Extension.Available>> {
|
return parseResponse(network.client.newCall(call).await())
|
||||||
val call = GET("$repoUrl/index.json")
|
|
||||||
|
|
||||||
return client.newCall(call).asObservableSuccess()
|
|
||||||
.map(::parseResponse)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun checkforUpdates(context: Context): List<Extension.Installed> {
|
suspend fun checkforUpdates(context: Context): List<Extension.Installed> {
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
val call = GET("$repoUrl/index.json")
|
val call = GET("$REPO_URL/index.json")
|
||||||
val response = client.newCall(call).execute()
|
val response = network.client.newCall(call).await()
|
||||||
|
|
||||||
if (response.isSuccessful) {
|
if (response.isSuccessful) {
|
||||||
val extensions = parseResponse(response)
|
val extensions = parseResponse(response)
|
||||||
@ -80,13 +73,17 @@ internal class ExtensionGithubApi {
|
|||||||
val versionName = element["version"].string
|
val versionName = element["version"].string
|
||||||
val versionCode = element["code"].int
|
val versionCode = element["code"].int
|
||||||
val lang = element["lang"].string
|
val lang = element["lang"].string
|
||||||
val icon = "$repoUrl/icon/${apkName.replace(".apk", ".png")}"
|
val icon = "$REPO_URL/icon/${apkName.replace(".apk", ".png")}"
|
||||||
|
|
||||||
Extension.Available(name, pkgName, versionName, versionCode, lang, apkName, icon)
|
Extension.Available(name, pkgName, versionName, versionCode, lang, apkName, icon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun getApkUrl(extension: Extension.Available): String {
|
fun getApkUrl(extension: Extension.Available): String {
|
||||||
return "$repoUrl/apk/${extension.apkName}"
|
return "$REPO_URL/apk/${extension.apkName}"
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val REPO_URL = "https://raw.githubusercontent.com/inorichi/tachiyomi-extensions/repo"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,13 +1,14 @@
|
|||||||
package eu.kanade.tachiyomi.network
|
package eu.kanade.tachiyomi.network
|
||||||
|
|
||||||
import okhttp3.Call
|
import kotlinx.coroutines.suspendCancellableCoroutine
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.*
|
||||||
import okhttp3.Request
|
|
||||||
import okhttp3.Response
|
|
||||||
import rx.Observable
|
import rx.Observable
|
||||||
import rx.Producer
|
import rx.Producer
|
||||||
import rx.Subscription
|
import rx.Subscription
|
||||||
|
import java.io.IOException
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
|
import kotlin.coroutines.resume
|
||||||
|
import kotlin.coroutines.resumeWithException
|
||||||
|
|
||||||
fun Call.asObservable(): Observable<Response> {
|
fun Call.asObservable(): Observable<Response> {
|
||||||
return Observable.unsafeCreate { subscriber ->
|
return Observable.unsafeCreate { subscriber ->
|
||||||
@ -46,6 +47,31 @@ fun Call.asObservable(): Observable<Response> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Based on https://github.com/gildor/kotlin-coroutines-okhttp
|
||||||
|
suspend fun Call.await(): Response {
|
||||||
|
return suspendCancellableCoroutine { continuation ->
|
||||||
|
enqueue(object : Callback {
|
||||||
|
override fun onResponse(call: Call, response: Response) {
|
||||||
|
continuation.resume(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onFailure(call: Call, e: IOException) {
|
||||||
|
// Don't bother with resuming the continuation if it is already cancelled.
|
||||||
|
if (continuation.isCancelled) return
|
||||||
|
continuation.resumeWithException(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
continuation.invokeOnCancellation {
|
||||||
|
try {
|
||||||
|
cancel()
|
||||||
|
} catch (ex: Throwable) {
|
||||||
|
// Ignore cancel exception
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun Call.asObservableSuccess(): Observable<Response> {
|
fun Call.asObservableSuccess(): Observable<Response> {
|
||||||
return asObservable().doOnNext { response ->
|
return asObservable().doOnNext { response ->
|
||||||
if (!response.isSuccessful) {
|
if (!response.isSuccessful) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user