diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a7e1751b2..951e86d15 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -251,8 +251,12 @@ dependencies { implementation("org.chromium.net:cronet-embedded:113.5672.61") implementation("com.google.guava:guava:32.0.1-android") + val serialization = "1.5.1" + implementation("org.jetbrains.kotlinx:kotlinx-serialization-cbor:$serialization") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:$serialization") + implementation("org.jetbrains.kotlinx:kotlinx-serialization-json-okio:$serialization") + implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.2") - implementation("org.jetbrains.kotlinx:kotlinx-serialization-cbor:1.5.1") implementation("org.jsoup:jsoup:1.16.1") val chunker = "4.0.0" diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt index 42b8e6f6f..6050dd930 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/EhEngine.kt @@ -49,6 +49,9 @@ import com.hippo.ehviewer.dailycheck.today import com.hippo.ehviewer.network.StatusCodeException import kotlinx.coroutines.CancellationException import kotlinx.coroutines.delay +import kotlinx.serialization.json.add +import kotlinx.serialization.json.addJsonArray +import kotlinx.serialization.json.put import moe.tarsin.coroutines.runSuspendCatching import okhttp3.Headers import okhttp3.MediaType @@ -56,7 +59,6 @@ import okhttp3.MediaType.Companion.toMediaType import okhttp3.MultipartBody import okhttp3.Request import okhttp3.RequestBody.Companion.asRequestBody -import org.json.JSONArray import org.jsoup.Jsoup import splitties.init.appCtx import java.io.File @@ -360,7 +362,14 @@ object EhEngine { ehRequest(EhUrl.apiUrl, referer, EhUrl.origin) { jsonBody { put("method", "gdata") - array("gidlist") { it.forEach { put(jsonArrayOf(it.gid, it.token)) } } + array("gidlist") { + it.forEach { + addJsonArray { + add(it.gid) + add(it.token) + } + } + } put("namespace", 1) } }.executeAndParsingWith { GalleryApiParser.parse(this, it) } @@ -407,7 +416,13 @@ object EhEngine { suspend fun getGalleryToken(gid: Long, gtoken: String?, page: Int) = ehRequest(EhUrl.apiUrl, EhUrl.referer, EhUrl.origin) { jsonBody { put("method", "gtoken") - put("pagelist", JSONArray().put(JSONArray().put(gid).put(gtoken).put(page + 1))) + array("pagelist") { + addJsonArray { + add(gid) + add(gtoken) + add(page + 1) + } + } } }.executeAndParsingWith(GalleryTokenApiParser::parse) diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhRequestBuilder.kt b/app/src/main/java/com/hippo/ehviewer/client/EhRequestBuilder.kt index 338b2d810..79eea838f 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhRequestBuilder.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/EhRequestBuilder.kt @@ -21,6 +21,10 @@ import com.hippo.ehviewer.EhApplication.Companion.okHttpClient import kotlinx.coroutines.coroutineScope import kotlinx.coroutines.launch import kotlinx.coroutines.suspendCancellableCoroutine +import kotlinx.serialization.json.JsonArrayBuilder +import kotlinx.serialization.json.JsonObjectBuilder +import kotlinx.serialization.json.buildJsonArray +import kotlinx.serialization.json.buildJsonObject import okhttp3.Call import okhttp3.FormBody import okhttp3.MediaType @@ -30,8 +34,6 @@ import okhttp3.Request import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.Response import okhttp3.executeAsync -import org.json.JSONArray -import org.json.JSONObject import kotlin.coroutines.resume import kotlin.coroutines.resumeWithException @@ -49,11 +51,9 @@ inline fun Request.Builder.multipartBody(builder: MultipartBody.Builder.() -> Un val MEDIA_TYPE_JSON: MediaType = "application/json; charset=utf-8".toMediaType() -inline fun JSONObject.array(name: String, builder: JSONArray.() -> Unit): JSONObject = put(name, JSONArray().apply(builder)) +inline fun JsonObjectBuilder.array(name: String, builder: JsonArrayBuilder.() -> Unit) = put(name, buildJsonArray(builder)) -fun jsonArrayOf(vararg element: Any?) = JSONArray().apply { element.forEach { put(it) } } // Should ensure it is inlined - -inline fun Request.Builder.jsonBody(builder: JSONObject.() -> Unit) = post(JSONObject().apply(builder).toString().toRequestBody(MEDIA_TYPE_JSON)) +inline fun Request.Builder.jsonBody(builder: JsonObjectBuilder.() -> Unit) = post(buildJsonObject(builder).toString().toRequestBody(MEDIA_TYPE_JSON)) const val TAG_CALL = "CancellableCallReadingScope" diff --git a/app/src/main/java/com/hippo/ehviewer/client/EhTagDatabase.kt b/app/src/main/java/com/hippo/ehviewer/client/EhTagDatabase.kt index 3cd933b7b..c016fb02c 100644 --- a/app/src/main/java/com/hippo/ehviewer/client/EhTagDatabase.kt +++ b/app/src/main/java/com/hippo/ehviewer/client/EhTagDatabase.kt @@ -32,6 +32,8 @@ import kotlinx.coroutines.flow.flow import kotlinx.coroutines.launch import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.withLock +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.okio.decodeFromBufferedSource import moe.tarsin.coroutines.runSuspendCatching import okhttp3.OkHttpClient import okhttp3.Request @@ -40,14 +42,10 @@ import okio.HashingSink.Companion.sha1 import okio.blackholeSink import okio.buffer import okio.source -import org.json.JSONObject import splitties.init.appCtx import java.io.File import java.nio.charset.StandardCharsets -private typealias TagGroup = Map -private typealias TagGroups = Map - object EhTagDatabase : CoroutineScope { private const val NAMESPACE_PREFIX = "n" private val PREFIXES = arrayOf( @@ -56,19 +54,13 @@ object EhTagDatabase : CoroutineScope { "tag:", "weak:", ) - private lateinit var tagGroups: TagGroups + private lateinit var tagGroups: Map> private val updateLock = Mutex() private val dbLock = Mutex() override val coroutineContext = Dispatchers.IO + Job() var initialized by mutableStateOf(false) - private fun JSONObject.toTagGroups(): TagGroups = - keys().asSequence().associateWith { getJSONObject(it).toTagGroup() } - - private fun JSONObject.toTagGroup(): TagGroup = - keys().asSequence().associateWith { getString(it) } - fun getTranslation(prefix: String? = NAMESPACE_PREFIX, tag: String?): String? { return tagGroups[prefix]?.get(tag)?.trim()?.takeIf { it.isNotEmpty() } } @@ -218,9 +210,7 @@ object EhTagDatabase : CoroutineScope { val dir = AppConfig.getFilesDir("tag-translations") val dataFile = File(dir, dataName).takeIf { it.exists() } ?: return runSuspendCatching { - tagGroups = JSONObject( - dataFile.source().buffer().readString(StandardCharsets.UTF_8), - ).toTagGroups() + tagGroups = dataFile.source().buffer().use { Json.decodeFromBufferedSource(it) } initialized = true }.onFailure { it.printStackTrace()