Эх сурвалжийг харах

Use coroutines for Anilist API

arkon 4 жил өмнө
parent
commit
dc3ed7fffc

+ 9 - 8
app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt

@@ -6,6 +6,7 @@ import eu.kanade.tachiyomi.R
 import eu.kanade.tachiyomi.data.database.models.Track
 import eu.kanade.tachiyomi.data.track.TrackService
 import eu.kanade.tachiyomi.data.track.model.TrackSearch
+import eu.kanade.tachiyomi.util.lang.runAsObservable
 import kotlinx.serialization.decodeFromString
 import kotlinx.serialization.encodeToString
 import kotlinx.serialization.json.Json
@@ -132,26 +133,26 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
     }
 
     override fun add(track: Track): Observable<Track> {
-        return api.addLibManga(track)
+        return runAsObservable({ api.addLibManga(track) })
     }
 
     override fun update(track: Track): Observable<Track> {
         // If user was using API v1 fetch library_id
         if (track.library_id == null || track.library_id!! == 0L) {
-            return api.findLibManga(track, getUsername().toInt()).flatMap {
+            return runAsObservable({ api.findLibManga(track, getUsername().toInt()) }).flatMap {
                 if (it == null) {
                     throw Exception("$track not found on user library")
                 }
                 track.library_id = it.library_id
-                api.updateLibManga(track)
+                runAsObservable({ api.updateLibManga(track) })
             }
         }
 
-        return api.updateLibManga(track)
+        return runAsObservable({ api.updateLibManga(track) })
     }
 
     override fun bind(track: Track): Observable<Track> {
-        return api.findLibManga(track, getUsername().toInt())
+        return runAsObservable({ api.findLibManga(track, getUsername().toInt()) })
             .flatMap { remoteTrack ->
                 if (remoteTrack != null) {
                     track.copyPersonalFrom(remoteTrack)
@@ -167,11 +168,11 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
     }
 
     override fun search(query: String): Observable<List<TrackSearch>> {
-        return api.search(query)
+        return runAsObservable({ api.search(query) })
     }
 
     override fun refresh(track: Track): Observable<Track> {
-        return api.getLibManga(track, getUsername().toInt())
+        return runAsObservable({ api.getLibManga(track, getUsername().toInt()) })
             .map { remoteTrack ->
                 track.copyPersonalFrom(remoteTrack)
                 track.total_chapters = remoteTrack.total_chapters
@@ -184,7 +185,7 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
     fun login(token: String): Completable {
         val oauth = api.createOAuth(token)
         interceptor.setAuth(oauth)
-        return api.getCurrentUser().map { (username, scoreType) ->
+        return runAsObservable({ api.getCurrentUser() }).map { (username, scoreType) ->
             scorePreference.set(scoreType)
             saveCredentials(username.toString(), oauth.access_token)
         }.doOnError {

+ 52 - 73
app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt

@@ -5,7 +5,7 @@ import androidx.core.net.toUri
 import eu.kanade.tachiyomi.data.database.models.Track
 import eu.kanade.tachiyomi.data.track.model.TrackSearch
 import eu.kanade.tachiyomi.network.POST
-import eu.kanade.tachiyomi.network.asObservableSuccess
+import eu.kanade.tachiyomi.network.await
 import kotlinx.serialization.decodeFromString
 import kotlinx.serialization.json.Json
 import kotlinx.serialization.json.JsonObject
@@ -22,7 +22,6 @@ import kotlinx.serialization.json.putJsonObject
 import okhttp3.MediaType.Companion.toMediaType
 import okhttp3.OkHttpClient
 import okhttp3.RequestBody.Companion.toRequestBody
-import rx.Observable
 import uy.kohesive.injekt.injectLazy
 import java.util.Calendar
 
@@ -33,7 +32,7 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
     private val jsonMime = "application/json; charset=utf-8".toMediaType()
     private val authClient = client.newBuilder().addInterceptor(interceptor).build()
 
-    fun addLibManga(track: Track): Observable<Track> {
+    suspend fun addLibManga(track: Track): Track {
         val query =
             """
             |mutation AddManga(${'$'}mangaId: Int, ${'$'}progress: Int, ${'$'}status: MediaListStatus) {
@@ -51,22 +50,18 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
                 put("status", track.toAnilistStatus())
             }
         }
-        return authClient.newCall(POST(apiUrl, body = payload.toString().toRequestBody(jsonMime)))
-            .asObservableSuccess()
-            .map { netResponse ->
-                netResponse.use {
-                    val responseBody = it.body?.string().orEmpty()
-                    if (responseBody.isEmpty()) {
-                        throw Exception("Null Response")
-                    }
-                    val response = json.decodeFromString<JsonObject>(responseBody)
-                    track.library_id = response["data"]!!.jsonObject["SaveMediaListEntry"]!!.jsonObject["id"]!!.jsonPrimitive.long
-                    track
-                }
+        return authClient.newCall(POST(apiUrl, body = payload.toString().toRequestBody(jsonMime))).await().use {
+            val responseBody = it.body?.string().orEmpty()
+            if (responseBody.isEmpty()) {
+                throw Exception("Null Response")
             }
+            val response = json.decodeFromString<JsonObject>(responseBody)
+            track.library_id = response["data"]!!.jsonObject["SaveMediaListEntry"]!!.jsonObject["id"]!!.jsonPrimitive.long
+            track
+        }
     }
 
-    fun updateLibManga(track: Track): Observable<Track> {
+    suspend fun updateLibManga(track: Track): Track {
         val query =
             """
             |mutation UpdateManga(${'$'}listId: Int, ${'$'}progress: Int, ${'$'}status: MediaListStatus, ${'$'}score: Int) {
@@ -86,14 +81,11 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
                 put("score", track.score.toInt())
             }
         }
-        return authClient.newCall(POST(apiUrl, body = payload.toString().toRequestBody(jsonMime)))
-            .asObservableSuccess()
-            .map {
-                track
-            }
+        authClient.newCall(POST(apiUrl, body = payload.toString().toRequestBody(jsonMime))).await()
+        return track
     }
 
-    fun search(search: String): Observable<List<TrackSearch>> {
+    suspend fun search(search: String): List<TrackSearch> {
         val query =
             """
             |query Search(${'$'}query: String) {
@@ -125,25 +117,21 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
                 put("query", search)
             }
         }
-        return authClient.newCall(POST(apiUrl, body = payload.toString().toRequestBody(jsonMime)))
-            .asObservableSuccess()
-            .map { netResponse ->
-                netResponse.use {
-                    val responseBody = it.body?.string().orEmpty()
-                    if (responseBody.isEmpty()) {
-                        throw Exception("Null Response")
-                    }
-                    val response = json.decodeFromString<JsonObject>(responseBody)
-                    val data = response["data"]!!.jsonObject
-                    val page = data["Page"]!!.jsonObject
-                    val media = page["media"]!!.jsonArray
-                    val entries = media.map { jsonToALManga(it.jsonObject) }
-                    entries.map { it.toTrack() }
-                }
+        return authClient.newCall(POST(apiUrl, body = payload.toString().toRequestBody(jsonMime))).await().use {
+            val responseBody = it.body?.string().orEmpty()
+            if (responseBody.isEmpty()) {
+                throw Exception("Null Response")
             }
+            val response = json.decodeFromString<JsonObject>(responseBody)
+            val data = response["data"]!!.jsonObject
+            val page = data["Page"]!!.jsonObject
+            val media = page["media"]!!.jsonArray
+            val entries = media.map { jsonToALManga(it.jsonObject) }
+            entries.map { it.toTrack() }
+        }
     }
 
-    fun findLibManga(track: Track, userid: Int): Observable<Track?> {
+    suspend fun findLibManga(track: Track, userid: Int): Track? {
         val query =
             """
             |query (${'$'}id: Int!, ${'$'}manga_id: Int!) {
@@ -182,34 +170,29 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
                 put("manga_id", track.media_id)
             }
         }
-        return authClient.newCall(POST(apiUrl, body = payload.toString().toRequestBody(jsonMime)))
-            .asObservableSuccess()
-            .map { netResponse ->
-                netResponse.use {
-                    val responseBody = it.body?.string().orEmpty()
-                    if (responseBody.isEmpty()) {
-                        throw Exception("Null Response")
-                    }
-                    val response = json.decodeFromString<JsonObject>(responseBody)
-                    val data = response["data"]!!.jsonObject
-                    val page = data["Page"]!!.jsonObject
-                    val media = page["mediaList"]!!.jsonArray
-                    val entries = media.map { jsonToALUserManga(it.jsonObject) }
-                    entries.firstOrNull()?.toTrack()
-                }
+        return authClient.newCall(POST(apiUrl, body = payload.toString().toRequestBody(jsonMime))).await().use {
+            val responseBody = it.body?.string().orEmpty()
+            if (responseBody.isEmpty()) {
+                throw Exception("Null Response")
             }
+            val response = json.decodeFromString<JsonObject>(responseBody)
+            val data = response["data"]!!.jsonObject
+            val page = data["Page"]!!.jsonObject
+            val media = page["mediaList"]!!.jsonArray
+            val entries = media.map { jsonToALUserManga(it.jsonObject) }
+            entries.firstOrNull()?.toTrack()
+        }
     }
 
-    fun getLibManga(track: Track, userid: Int): Observable<Track> {
-        return findLibManga(track, userid)
-            .map { it ?: throw Exception("Could not find manga") }
+    suspend fun getLibManga(track: Track, userid: Int): Track {
+        return findLibManga(track, userid) ?: throw Exception("Could not find manga")
     }
 
     fun createOAuth(token: String): OAuth {
         return OAuth(token, "Bearer", System.currentTimeMillis() + 31536000000, 31536000000)
     }
 
-    fun getCurrentUser(): Observable<Pair<Int, String>> {
+    suspend fun getCurrentUser(): Pair<Int, String> {
         val query =
             """
             |query User {
@@ -224,23 +207,19 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
         val payload = buildJsonObject {
             put("query", query)
         }
-        return authClient.newCall(POST(apiUrl, body = payload.toString().toRequestBody(jsonMime)))
-            .asObservableSuccess()
-            .map { netResponse ->
-                netResponse.use {
-                    val responseBody = it.body?.string().orEmpty()
-                    if (responseBody.isEmpty()) {
-                        throw Exception("Null Response")
-                    }
-                    val response = json.decodeFromString<JsonObject>(responseBody)
-                    val data = response["data"]!!.jsonObject
-                    val viewer = data["Viewer"]!!.jsonObject
-                    Pair(
-                        viewer["id"]!!.jsonPrimitive.int,
-                        viewer["mediaListOptions"]!!.jsonObject["scoreFormat"]!!.jsonPrimitive.content
-                    )
-                }
+        return authClient.newCall(POST(apiUrl, body = payload.toString().toRequestBody(jsonMime))).await().use {
+            val responseBody = it.body?.string().orEmpty()
+            if (responseBody.isEmpty()) {
+                throw Exception("Null Response")
             }
+            val response = json.decodeFromString<JsonObject>(responseBody)
+            val data = response["data"]!!.jsonObject
+            val viewer = data["Viewer"]!!.jsonObject
+            Pair(
+                viewer["id"]!!.jsonPrimitive.int,
+                viewer["mediaListOptions"]!!.jsonObject["scoreFormat"]!!.jsonPrimitive.content
+            )
+        }
     }
 
     private fun jsonToALManga(struct: JsonObject): ALManga {