[Anibel] Fix parser

Koitharu 3 years ago
parent cae7073f87
commit 12522ce8d8
No known key found for this signature in database
GPG Key ID: 8E861F8CE6E7CE27

@ -81,7 +81,14 @@ class OkHttpWebClient(
body.put("operationName", null as Any?) body.put("operationName", null as Any?)
body.put("variables", JSONObject()) body.put("variables", JSONObject())
body.put("query", "{$query}") body.put("query", "{$query}")
val json = httpPost(endpoint, body).parseJson()
val mediaType = "application/json; charset=utf-8".toMediaType()
val requestBody = body.toString().toRequestBody(mediaType)
val request = Request.Builder()
.post(requestBody)
.url(endpoint)
.addTags()
val json = httpClient.newCall(request.build()).await().parseJson()
json.optJSONArray("errors")?.let { json.optJSONArray("errors")?.let {
if (it.length() != 0) { if (it.length() != 0) {
throw GraphQLException(it) throw GraphQLException(it)

@ -13,6 +13,7 @@ import org.koitharu.kotatsu.parsers.util.generateUid
import org.koitharu.kotatsu.parsers.util.getDomain import org.koitharu.kotatsu.parsers.util.getDomain
import org.koitharu.kotatsu.parsers.util.json.mapJSON import org.koitharu.kotatsu.parsers.util.json.mapJSON
import org.koitharu.kotatsu.parsers.util.json.mapJSONIndexed import org.koitharu.kotatsu.parsers.util.json.mapJSONIndexed
import org.koitharu.kotatsu.parsers.util.json.mapJSONNotNull
import org.koitharu.kotatsu.parsers.util.json.stringIterator import org.koitharu.kotatsu.parsers.util.json.stringIterator
import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl
import java.util.* import java.util.*
@ -72,7 +73,7 @@ internal class AnibelParser(context: MangaLoaderContext) : MangaParser(context,
title = title.getString("be"), title = title.getString("be"),
coverUrl = jo.getString("poster").removePrefix("/cdn") coverUrl = jo.getString("poster").removePrefix("/cdn")
.toAbsoluteUrl(getDomain("cdn")) + "?width=200&height=280", .toAbsoluteUrl(getDomain("cdn")) + "?width=200&height=280",
altTitle = title.getString("alt").takeUnless(String::isEmpty), altTitle = title.optJSONArray("alt")?.optString(0)?.takeUnless(String::isEmpty),
author = null, author = null,
isNsfw = false, isNsfw = false,
rating = jo.getDouble("rating").toFloat() / 10f, rating = jo.getDouble("rating").toFloat() / 10f,
@ -110,20 +111,21 @@ internal class AnibelParser(context: MangaLoaderContext) : MangaParser(context,
""".trimIndent(), """.trimIndent(),
).getJSONObject("media") ).getJSONObject("media")
val title = details.getJSONObject("title") val title = details.getJSONObject("title")
val poster = details.getString("poster").removePrefix("/cdn") val poster = details.getString("poster").removePrefix("/cdn").toAbsoluteUrl(getDomain("cdn"))
.toAbsoluteUrl(getDomain("cdn"))
val chapters = apiCall( val chapters = apiCall(
""" """
chapters(mediaId: "${details.getString("mediaId")}") { chapters(mediaId: "${details.getString("mediaId")}", offset: 0, limit: 99999) {
docs {
id id
chapter chapter
released released
} }
}
""".trimIndent(), """.trimIndent(),
).getJSONArray("chapters") ).getJSONObject("chapters").getJSONArray("docs")
return manga.copy( return manga.copy(
title = title.getString("be"), title = title.getString("be"),
altTitle = title.getString("alt"), altTitle = title.optJSONArray("alt")?.optString(0)?.takeUnless(String::isEmpty),
coverUrl = "$poster?width=200&height=280", coverUrl = "$poster?width=200&height=280",
largeCoverUrl = poster, largeCoverUrl = poster,
description = details.getJSONObject("description").getString("be"), description = details.getJSONObject("description").getString("be"),
@ -164,7 +166,6 @@ internal class AnibelParser(context: MangaLoaderContext) : MangaParser(context,
""".trimIndent(), """.trimIndent(),
).getJSONObject("chapter") ).getJSONObject("chapter")
val pages = chapterJson.getJSONArray("images") val pages = chapterJson.getJSONArray("images")
val chapterUrl = "https://${domain}/${chapter.url}"
return pages.mapJSONIndexed { i, jo -> return pages.mapJSONIndexed { i, jo ->
MangaPage( MangaPage(
id = generateUid("${chapter.url}/$i"), id = generateUid("${chapter.url}/$i"),
@ -190,23 +191,29 @@ internal class AnibelParser(context: MangaLoaderContext) : MangaParser(context,
private suspend fun search(query: String): List<Manga> { private suspend fun search(query: String): List<Manga> {
val json = apiCall( val json = apiCall(
""" """
search(query: "$query", limit: 40) { search(query: "$query", limit: 60) {
id mediaId
title { title {
be be
en en
} }
poster poster
url status
type slug
mediaType
genres
} }
""".trimIndent(), """.trimIndent(),
) )
val array = json.getJSONArray("search") val array = json.getJSONArray("search")
return array.mapJSON { jo -> return array.mapJSONNotNull { jo ->
val mediaId = jo.getString("id") val type = jo.getString("mediaType").lowercase()
if (type != "manga") {
return@mapJSONNotNull null
}
val mediaId = jo.getString("mediaId")
val title = jo.getJSONObject("title") val title = jo.getJSONObject("title")
val href = "${jo.getString("type").lowercase()}/${jo.getString("url")}" val href = "$type/${jo.getString("slug")}"
Manga( Manga(
id = generateUid(mediaId), id = generateUid(mediaId),
title = title.getString("be"), title = title.getString("be"),
@ -218,16 +225,19 @@ internal class AnibelParser(context: MangaLoaderContext) : MangaParser(context,
rating = RATING_UNKNOWN, rating = RATING_UNKNOWN,
url = href, url = href,
publicUrl = "https://${domain}/$href", publicUrl = "https://${domain}/$href",
tags = emptySet(), tags = jo.getJSONArray("genres").mapToTags(),
state = null, state = when (jo.getString("status")) {
"ongoing" -> MangaState.ONGOING
"finished" -> MangaState.FINISHED
else -> null
},
source = source, source = source,
) )
} }
} }
private suspend fun apiCall(request: String): JSONObject { private suspend fun apiCall(request: String): JSONObject {
return webClient.graphQLQuery("https://api.${domain}/graphql", request) return webClient.graphQLQuery("https://${domain}/graphql", request).getJSONObject("data")
.getJSONObject("data")
} }
private fun JSONArray.mapToTags(): Set<MangaTag> { private fun JSONArray.mapToTags(): Set<MangaTag> {

@ -5,6 +5,8 @@ import kotlinx.coroutines.CancellationException
inline fun <T, R> T.runCatchingCancellable(block: T.() -> R): Result<R> { inline fun <T, R> T.runCatchingCancellable(block: T.() -> R): Result<R> {
return try { return try {
Result.success(block()) Result.success(block())
} catch (e: InterruptedException) {
throw e
} catch (e: CancellationException) { } catch (e: CancellationException) {
throw e throw e
} catch (e: Throwable) { } catch (e: Throwable) {

Loading…
Cancel
Save