From dc3ed7fffc19774caf2b129bf230f0fbd69a9d07 Mon Sep 17 00:00:00 2001 From: arkon Date: Thu, 24 Dec 2020 16:55:04 -0500 Subject: [PATCH] Use coroutines for Anilist API --- .../tachiyomi/data/track/anilist/Anilist.kt | 17 +-- .../data/track/anilist/AnilistApi.kt | 125 ++++++++---------- 2 files changed, 61 insertions(+), 81 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt index 7725a2ded4..80905b7e77 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/Anilist.kt +++ b/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 { - return api.addLibManga(track) + return runAsObservable({ api.addLibManga(track) }) } override fun update(track: Track): Observable { // 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 { - 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> { - return api.search(query) + return runAsObservable({ api.search(query) }) } override fun refresh(track: Track): Observable { - 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 { diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt index 4ee0e80de3..ac56e5808f 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/anilist/AnilistApi.kt +++ b/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 { + 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(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(responseBody) + track.library_id = response["data"]!!.jsonObject["SaveMediaListEntry"]!!.jsonObject["id"]!!.jsonPrimitive.long + track + } } - fun updateLibManga(track: Track): Observable { + 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> { + suspend fun search(search: String): List { 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(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(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 { + 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(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(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 { - 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> { + suspend fun getCurrentUser(): Pair { 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(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(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 {