瀏覽代碼

Migrate to kotlinx.serialization for Shikimori

arkon 4 年之前
父節點
當前提交
f8d82cb052

+ 3 - 0
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,

+ 6 - 8
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<OAuth>(preferences.trackToken(this).get())
         } catch (e: Exception) {
             null
         }

+ 45 - 43
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<Track> {
-        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<JsonArray>(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<JsonObject>(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<JsonArray>(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<JsonObject>(user)["id"]!!.jsonPrimitive.int
     }
 
     fun accessToken(code: String): Observable<OAuth> {
@@ -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<OAuth>(responseBody)
         }
     }
 

+ 4 - 3
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<OAuth>(response.body!!.string()))
             } else {
                 response.close()
             }