From f8d82cb0521012f16d11520daaac97e5efb0219c Mon Sep 17 00:00:00 2001 From: arkon Date: Sun, 11 Oct 2020 15:44:18 -0400 Subject: [PATCH] Migrate to kotlinx.serialization for Shikimori --- .../tachiyomi/data/track/shikimori/OAuth.kt | 3 + .../data/track/shikimori/Shikimori.kt | 14 ++- .../data/track/shikimori/ShikimoriApi.kt | 88 ++++++++++--------- .../track/shikimori/ShikimoriInterceptor.kt | 7 +- 4 files changed, 58 insertions(+), 54 deletions(-) diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/OAuth.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/OAuth.kt index 8c6f2a9822..9987891974 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/OAuth.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/OAuth.kt @@ -1,5 +1,8 @@ package eu.kanade.tachiyomi.data.track.shikimori +import kotlinx.serialization.Serializable + +@Serializable data class OAuth( val access_token: String, val token_type: String, diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt index 397559b114..d0244e7c00 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/Shikimori.kt @@ -2,14 +2,15 @@ package eu.kanade.tachiyomi.data.track.shikimori import android.content.Context import android.graphics.Color -import com.google.gson.Gson 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 kotlinx.serialization.decodeFromString +import kotlinx.serialization.encodeToString +import kotlinx.serialization.json.Json import rx.Completable import rx.Observable -import uy.kohesive.injekt.injectLazy class Shikimori(private val context: Context, id: Int) : TrackService(id) { @@ -27,9 +28,7 @@ class Shikimori(private val context: Context, id: Int) : TrackService(id) { override val name = "Shikimori" - private val gson: Gson by injectLazy() - - private val interceptor by lazy { ShikimoriInterceptor(this, gson) } + private val interceptor by lazy { ShikimoriInterceptor(this) } private val api by lazy { ShikimoriApi(client, interceptor) } @@ -117,13 +116,12 @@ class Shikimori(private val context: Context, id: Int) : TrackService(id) { } fun saveToken(oauth: OAuth?) { - val json = gson.toJson(oauth) - preferences.trackToken(this).set(json) + preferences.trackToken(this).set(Json.encodeToString(oauth)) } fun restoreToken(): OAuth? { return try { - gson.fromJson(preferences.trackToken(this).get(), OAuth::class.java) + Json.decodeFromString(preferences.trackToken(this).get()) } catch (e: Exception) { null } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt index 20c14f9268..9473cafe53 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriApi.kt @@ -1,44 +1,46 @@ package eu.kanade.tachiyomi.data.track.shikimori import androidx.core.net.toUri -import com.github.salomonbrys.kotson.array -import com.github.salomonbrys.kotson.jsonObject -import com.github.salomonbrys.kotson.nullString -import com.github.salomonbrys.kotson.obj -import com.google.gson.Gson -import com.google.gson.JsonObject -import com.google.gson.JsonParser import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.track.TrackManager import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.asObservableSuccess +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonArray +import kotlinx.serialization.json.JsonObject +import kotlinx.serialization.json.buildJsonObject +import kotlinx.serialization.json.contentOrNull +import kotlinx.serialization.json.int +import kotlinx.serialization.json.jsonObject +import kotlinx.serialization.json.jsonPrimitive +import kotlinx.serialization.json.put +import kotlinx.serialization.json.putJsonObject import okhttp3.FormBody import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.RequestBody.Companion.toRequestBody import rx.Observable -import uy.kohesive.injekt.injectLazy class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInterceptor) { - private val gson: Gson by injectLazy() private val jsonime = "application/json; charset=utf-8".toMediaTypeOrNull() private val authClient = client.newBuilder().addInterceptor(interceptor).build() fun addLibManga(track: Track, user_id: String): Observable { - val payload = jsonObject( - "user_rate" to jsonObject( - "user_id" to user_id, - "target_id" to track.media_id, - "target_type" to "Manga", - "chapters" to track.last_chapter_read, - "score" to track.score.toInt(), - "status" to track.toShikimoriStatus() - ) - ) + val payload = buildJsonObject { + putJsonObject("user_rate") { + put("user_id", user_id) + put("target_id", track.media_id) + put("target_type", "Manga") + put("chapters", track.last_chapter_read) + put("score", track.score.toInt()) + put("status", track.toShikimoriStatus()) + } + } val body = payload.toString().toRequestBody(jsonime) val request = Request.Builder() .url("$apiUrl/v2/user_rates") @@ -70,34 +72,34 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter if (responseBody.isEmpty()) { throw Exception("Null Response") } - val response = JsonParser.parseString(responseBody).array - response.map { jsonToSearch(it.obj) } + val response = Json.decodeFromString(responseBody) + response.map { jsonToSearch(it.jsonObject) } } } private fun jsonToSearch(obj: JsonObject): TrackSearch { return TrackSearch.create(TrackManager.SHIKIMORI).apply { - media_id = obj["id"].asInt - title = obj["name"].asString - total_chapters = obj["chapters"].asInt - cover_url = baseUrl + obj["image"].obj["preview"].asString + media_id = obj["id"]!!.jsonPrimitive.int + title = obj["name"]!!.jsonPrimitive.content + total_chapters = obj["chapters"]!!.jsonPrimitive.int + cover_url = baseUrl + obj["image"]!!.jsonObject["preview"]!!.jsonPrimitive.content summary = "" - tracking_url = baseUrl + obj["url"].asString - publishing_status = obj["status"].asString - publishing_type = obj["kind"].asString - start_date = obj.get("aired_on").nullString.orEmpty() + tracking_url = baseUrl + obj["url"]!!.jsonPrimitive.content + publishing_status = obj["status"]!!.jsonPrimitive.content + publishing_type = obj["kind"]!!.jsonPrimitive.content + start_date = obj.get("aired_on")!!.jsonPrimitive.contentOrNull ?: "" } } private fun jsonToTrack(obj: JsonObject, mangas: JsonObject): Track { return Track.create(TrackManager.SHIKIMORI).apply { - title = mangas["name"].asString - media_id = obj["id"].asInt - total_chapters = mangas["chapters"].asInt - last_chapter_read = obj["chapters"].asInt - score = (obj["score"].asInt).toFloat() - status = toTrackStatus(obj["status"].asString) - tracking_url = baseUrl + mangas["url"].asString + title = mangas["name"]!!.jsonPrimitive.content + media_id = obj["id"]!!.jsonPrimitive.int + total_chapters = mangas["chapters"]!!.jsonPrimitive.int + last_chapter_read = obj["chapters"]!!.jsonPrimitive.int + score = (obj["score"]!!.jsonPrimitive.int).toFloat() + status = toTrackStatus(obj["status"]!!.jsonPrimitive.content) + tracking_url = baseUrl + mangas["url"]!!.jsonPrimitive.content } } @@ -123,7 +125,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter .asObservableSuccess() .map { netResponse -> val responseBody = netResponse.body?.string().orEmpty() - JsonParser.parseString(responseBody).obj + Json.decodeFromString(responseBody) }.flatMap { mangas -> authClient.newCall(request) .asObservableSuccess() @@ -132,12 +134,12 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter if (responseBody.isEmpty()) { throw Exception("Null Response") } - val response = JsonParser.parseString(responseBody).array - if (response.size() > 1) { + val response = Json.decodeFromString(responseBody) + if (response.size > 1) { throw Exception("Too much mangas in response") } val entry = response.map { - jsonToTrack(it.obj, mangas) + jsonToTrack(it.jsonObject, mangas) } entry.firstOrNull() } @@ -145,8 +147,8 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter } fun getCurrentUser(): Int { - val user = authClient.newCall(GET("$apiUrl/users/whoami")).execute().body?.string() - return JsonParser.parseString(user).obj["id"].asInt + val user = authClient.newCall(GET("$apiUrl/users/whoami")).execute().body?.string()!! + return Json.decodeFromString(user)["id"]!!.jsonPrimitive.int } fun accessToken(code: String): Observable { @@ -155,7 +157,7 @@ class ShikimoriApi(private val client: OkHttpClient, interceptor: ShikimoriInter if (responseBody.isEmpty()) { throw Exception("Null Response") } - gson.fromJson(responseBody, OAuth::class.java) + Json.decodeFromString(responseBody) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriInterceptor.kt b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriInterceptor.kt index 0a2688d70f..d045d1a461 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriInterceptor.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/data/track/shikimori/ShikimoriInterceptor.kt @@ -1,10 +1,11 @@ package eu.kanade.tachiyomi.data.track.shikimori -import com.google.gson.Gson +import kotlinx.serialization.decodeFromString +import kotlinx.serialization.json.Json import okhttp3.Interceptor import okhttp3.Response -class ShikimoriInterceptor(val shikimori: Shikimori, val gson: Gson) : Interceptor { +class ShikimoriInterceptor(val shikimori: Shikimori) : Interceptor { /** * OAuth object used for authenticated requests. @@ -22,7 +23,7 @@ class ShikimoriInterceptor(val shikimori: Shikimori, val gson: Gson) : Intercept if (currAuth.isExpired()) { val response = chain.proceed(ShikimoriApi.refreshTokenRequest(refreshToken)) if (response.isSuccessful) { - newAuth(gson.fromJson(response.body!!.string(), OAuth::class.java)) + newAuth(Json.decodeFromString(response.body!!.string())) } else { response.close() }