Migrate to kotlinx.serialization for Anilist

This commit is contained in:
arkon 2020-10-11 15:26:30 -04:00
parent 7a476abb53
commit e7d6605490
3 changed files with 87 additions and 78 deletions

View file

@ -2,14 +2,15 @@ package eu.kanade.tachiyomi.data.track.anilist
import android.content.Context import android.content.Context
import android.graphics.Color import android.graphics.Color
import com.google.gson.Gson
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.TrackService import eu.kanade.tachiyomi.data.track.TrackService
import eu.kanade.tachiyomi.data.track.model.TrackSearch 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.Completable
import rx.Observable import rx.Observable
import uy.kohesive.injekt.injectLazy
class Anilist(private val context: Context, id: Int) : TrackService(id) { class Anilist(private val context: Context, id: Int) : TrackService(id) {
@ -33,8 +34,6 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
override val name = "AniList" override val name = "AniList"
private val gson: Gson by injectLazy()
private val interceptor by lazy { AnilistInterceptor(this, getPassword()) } private val interceptor by lazy { AnilistInterceptor(this, getPassword()) }
private val api by lazy { AnilistApi(client, interceptor) } private val api by lazy { AnilistApi(client, interceptor) }
@ -197,12 +196,12 @@ class Anilist(private val context: Context, id: Int) : TrackService(id) {
} }
fun saveOAuth(oAuth: OAuth?) { fun saveOAuth(oAuth: OAuth?) {
preferences.trackToken(this).set(gson.toJson(oAuth)) preferences.trackToken(this).set(Json.encodeToString(oAuth))
} }
fun loadOAuth(): OAuth? { fun loadOAuth(): OAuth? {
return try { return try {
gson.fromJson(preferences.trackToken(this).get(), OAuth::class.java) Json.decodeFromString<OAuth>(preferences.trackToken(this).get())
} catch (e: Exception) { } catch (e: Exception) {
null null
} }

View file

@ -2,17 +2,22 @@ package eu.kanade.tachiyomi.data.track.anilist
import android.net.Uri import android.net.Uri
import androidx.core.net.toUri import androidx.core.net.toUri
import com.github.salomonbrys.kotson.array
import com.github.salomonbrys.kotson.get
import com.github.salomonbrys.kotson.jsonObject
import com.github.salomonbrys.kotson.nullInt
import com.github.salomonbrys.kotson.nullString
import com.github.salomonbrys.kotson.obj
import com.google.gson.JsonObject
import com.google.gson.JsonParser
import eu.kanade.tachiyomi.data.database.models.Track import eu.kanade.tachiyomi.data.database.models.Track
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.contentOrNull
import kotlinx.serialization.json.int
import kotlinx.serialization.json.intOrNull
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.long
import kotlinx.serialization.json.put
import kotlinx.serialization.json.putJsonObject
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import okhttp3.Request import okhttp3.Request
@ -35,15 +40,14 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|} |}
|} |}
|""".trimMargin() |""".trimMargin()
val variables = jsonObject( val payload = buildJsonObject {
"mangaId" to track.media_id, put("query", query)
"progress" to track.last_chapter_read, putJsonObject("variables") {
"status" to track.toAnilistStatus() put("mangaId", track.media_id)
) put("progress", track.last_chapter_read)
val payload = jsonObject( put("status", track.toAnilistStatus())
"query" to query, }
"variables" to variables }
)
val body = payload.toString().toRequestBody(jsonMime) val body = payload.toString().toRequestBody(jsonMime)
val request = Request.Builder() val request = Request.Builder()
.url(apiUrl) .url(apiUrl)
@ -57,8 +61,8 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
if (responseBody.isEmpty()) { if (responseBody.isEmpty()) {
throw Exception("Null Response") throw Exception("Null Response")
} }
val response = JsonParser.parseString(responseBody).obj val response = Json.decodeFromString<JsonObject>(responseBody)
track.library_id = response["data"]["SaveMediaListEntry"]["id"].asLong track.library_id = response["data"]!!.jsonObject["SaveMediaListEntry"]!!.jsonObject["id"]!!.jsonPrimitive.long
track track
} }
} }
@ -74,16 +78,15 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|} |}
|} |}
|""".trimMargin() |""".trimMargin()
val variables = jsonObject( val payload = buildJsonObject {
"listId" to track.library_id, put("query", query)
"progress" to track.last_chapter_read, putJsonObject("variables") {
"status" to track.toAnilistStatus(), put("listId", track.library_id)
"score" to track.score.toInt() put("progress", track.last_chapter_read)
) put("status", track.toAnilistStatus())
val payload = jsonObject( put("score", track.score.toInt())
"query" to query, }
"variables" to variables }
)
val body = payload.toString().toRequestBody(jsonMime) val body = payload.toString().toRequestBody(jsonMime)
val request = Request.Builder() val request = Request.Builder()
.url(apiUrl) .url(apiUrl)
@ -122,13 +125,12 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|} |}
|} |}
|""".trimMargin() |""".trimMargin()
val variables = jsonObject( val payload = buildJsonObject {
"query" to search put("query", query)
) putJsonObject("variables") {
val payload = jsonObject( put("query", search)
"query" to query, }
"variables" to variables }
)
val body = payload.toString().toRequestBody(jsonMime) val body = payload.toString().toRequestBody(jsonMime)
val request = Request.Builder() val request = Request.Builder()
.url(apiUrl) .url(apiUrl)
@ -141,11 +143,11 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
if (responseBody.isEmpty()) { if (responseBody.isEmpty()) {
throw Exception("Null Response") throw Exception("Null Response")
} }
val response = JsonParser.parseString(responseBody).obj val response = Json.decodeFromString<JsonObject>(responseBody)
val data = response["data"]!!.obj val data = response["data"]!!.jsonObject
val page = data["Page"].obj val page = data["Page"]!!.jsonObject
val media = page["media"].array val media = page["media"]!!.jsonArray
val entries = media.map { jsonToALManga(it.obj) } val entries = media.map { jsonToALManga(it.jsonObject) }
entries.map { it.toTrack() } entries.map { it.toTrack() }
} }
} }
@ -182,14 +184,13 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|} |}
|} |}
|""".trimMargin() |""".trimMargin()
val variables = jsonObject( val payload = buildJsonObject {
"id" to userid, put("query", query)
"manga_id" to track.media_id putJsonObject("variables") {
) put("id", userid)
val payload = jsonObject( put("manga_id", track.media_id)
"query" to query, }
"variables" to variables }
)
val body = payload.toString().toRequestBody(jsonMime) val body = payload.toString().toRequestBody(jsonMime)
val request = Request.Builder() val request = Request.Builder()
.url(apiUrl) .url(apiUrl)
@ -202,11 +203,11 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
if (responseBody.isEmpty()) { if (responseBody.isEmpty()) {
throw Exception("Null Response") throw Exception("Null Response")
} }
val response = JsonParser.parseString(responseBody).obj val response = Json.decodeFromString<JsonObject>(responseBody)
val data = response["data"]!!.obj val data = response["data"]!!.jsonObject
val page = data["Page"].obj val page = data["Page"]!!.jsonObject
val media = page["mediaList"].array val media = page["mediaList"]!!.jsonArray
val entries = media.map { jsonToALUserManga(it.obj) } val entries = media.map { jsonToALUserManga(it.jsonObject) }
entries.firstOrNull()?.toTrack() entries.firstOrNull()?.toTrack()
} }
} }
@ -232,9 +233,9 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
|} |}
|} |}
|""".trimMargin() |""".trimMargin()
val payload = jsonObject( val payload = buildJsonObject {
"query" to query put("query", query)
) }
val body = payload.toString().toRequestBody(jsonMime) val body = payload.toString().toRequestBody(jsonMime)
val request = Request.Builder() val request = Request.Builder()
.url(apiUrl) .url(apiUrl)
@ -247,10 +248,10 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
if (responseBody.isEmpty()) { if (responseBody.isEmpty()) {
throw Exception("Null Response") throw Exception("Null Response")
} }
val response = JsonParser.parseString(responseBody).obj val response = Json.decodeFromString<JsonObject>(responseBody)
val data = response["data"]!!.obj val data = response["data"]!!.jsonObject
val viewer = data["Viewer"].obj val viewer = data["Viewer"]!!.jsonObject
Pair(viewer["id"].asInt, viewer["mediaListOptions"]["scoreFormat"].asString) Pair(viewer["id"]!!.jsonPrimitive.int, viewer["mediaListOptions"]!!.jsonObject["scoreFormat"]!!.jsonPrimitive.content)
} }
} }
@ -258,12 +259,12 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
val date = try { val date = try {
val date = Calendar.getInstance() val date = Calendar.getInstance()
date.set( date.set(
struct["startDate"]["year"].nullInt ?: 0, struct["startDate"]!!.jsonObject["year"]!!.jsonPrimitive.intOrNull ?: 0,
( (
struct["startDate"]["month"].nullInt struct["startDate"]!!.jsonObject["month"]!!.jsonPrimitive.intOrNull
?: 0 ?: 0
) - 1, ) - 1,
struct["startDate"]["day"].nullInt ?: 0 struct["startDate"]!!.jsonObject["day"]!!.jsonPrimitive.intOrNull ?: 0
) )
date.timeInMillis date.timeInMillis
} catch (_: Exception) { } catch (_: Exception) {
@ -271,19 +272,25 @@ class AnilistApi(val client: OkHttpClient, interceptor: AnilistInterceptor) {
} }
return ALManga( return ALManga(
struct["id"].asInt, struct["id"]!!.jsonPrimitive.int,
struct["title"]["romaji"].asString, struct["title"]!!.jsonObject["romaji"]!!.jsonPrimitive.content,
struct["coverImage"]["large"].asString, struct["coverImage"]!!.jsonObject["large"]!!.jsonPrimitive.content,
struct["description"].nullString.orEmpty(), struct["description"]!!.jsonPrimitive.contentOrNull,
struct["type"].asString, struct["type"]!!.jsonPrimitive.content,
struct["status"].nullString.orEmpty(), struct["status"]!!.jsonPrimitive.contentOrNull ?: "",
date, date,
struct["chapters"].nullInt ?: 0 struct["chapters"]!!.jsonPrimitive.intOrNull ?: 0
) )
} }
private fun jsonToALUserManga(struct: JsonObject): ALUserManga { private fun jsonToALUserManga(struct: JsonObject): ALUserManga {
return ALUserManga(struct["id"].asLong, struct["status"].asString, struct["scoreRaw"].asInt, struct["progress"].asInt, jsonToALManga(struct["media"].obj)) return ALUserManga(
struct["id"]!!.jsonPrimitive.long,
struct["status"]!!.jsonPrimitive.content,
struct["scoreRaw"]!!.jsonPrimitive.int,
struct["progress"]!!.jsonPrimitive.int,
jsonToALManga(struct["media"]!!.jsonObject)
)
} }
companion object { companion object {

View file

@ -1,5 +1,8 @@
package eu.kanade.tachiyomi.data.track.anilist package eu.kanade.tachiyomi.data.track.anilist
import kotlinx.serialization.Serializable
@Serializable
data class OAuth( data class OAuth(
val access_token: String, val access_token: String,
val token_type: String, val token_type: String,