Migrate to kotlinx.serialization for Shikimori

This commit is contained in:
arkon 2020-10-11 15:44:18 -04:00
parent 980feb6c96
commit f8d82cb052
4 changed files with 58 additions and 54 deletions

View File

@ -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,

View File

@ -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
}

View File

@ -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)
}
}

View File

@ -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()
}