Fix reccomendations

This commit is contained in:
Jobobby04 2022-10-08 19:36:14 -04:00
parent 39c82feb01
commit 06d2e631be

View File

@ -11,14 +11,11 @@ import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.CatalogueSource
import eu.kanade.tachiyomi.source.model.MangasPage import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.util.lang.withIOContext
import eu.kanade.tachiyomi.util.system.logcat import eu.kanade.tachiyomi.util.system.logcat
import exh.util.MangaType import exh.util.MangaType
import exh.util.mangaType import exh.util.mangaType
import exh.util.nullIfEmpty
import kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonArray import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.buildJsonObject import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.contentOrNull import kotlinx.serialization.json.contentOrNull
@ -27,8 +24,8 @@ import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.put import kotlinx.serialization.json.put
import logcat.LogPriority import logcat.LogPriority
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.MediaType.Companion.toMediaTypeOrNull import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody import okhttp3.RequestBody.Companion.toRequestBody
import uy.kohesive.injekt.Injekt import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get import uy.kohesive.injekt.api.get
@ -41,49 +38,54 @@ abstract class API(val endpoint: String) {
abstract suspend fun getRecsBySearch(search: String): List<SManga> abstract suspend fun getRecsBySearch(search: String): List<SManga>
} }
class MyAnimeList : API("https://api.jikan.moe/v3/") { class MyAnimeList : API("https://api.jikan.moe/v4/") {
private suspend fun getRecsById(id: String): List<SManga> { private suspend fun getRecsById(id: String): List<SManga> {
val httpUrl = endpoint.toHttpUrlOrNull() ?: throw Exception("Could not convert endpoint url") val apiUrl = endpoint.toHttpUrl()
val apiUrl = httpUrl.newBuilder() .newBuilder()
.addPathSegment("manga") .addPathSegment("manga")
.addPathSegment(id) .addPathSegment(id)
.addPathSegment("recommendations") .addPathSegment("recommendations")
.build() .build()
.toString()
val response = client.newCall(GET(apiUrl)).await() val data = client.newCall(GET(apiUrl)).await().parseAs<JsonObject>()
val body = withIOContext { response.body.string() } return data["data"]!!.jsonArray
val data = Json.decodeFromString<JsonObject>(body) .map { it.jsonObject["entry"]!!.jsonObject }
val recommendations = data["recommendations"] as? JsonArray .map { rec ->
return recommendations?.filterIsInstance<JsonObject>()?.map { rec -> logcat { "MYANIMELIST > RECOMMENDATION: " + rec["title"]!!.jsonPrimitive.content }
logcat { "MYANIMELIST > RECOMMENDATION: " + rec["title"]?.jsonPrimitive?.content.orEmpty() } SManga(
SManga.create().apply { title = rec["title"]!!.jsonPrimitive.content,
title = rec["title"]!!.jsonPrimitive.content url = rec["url"]!!.jsonPrimitive.content,
thumbnail_url = rec["image_url"]!!.jsonPrimitive.content thumbnail_url = rec["images"]
initialized = true ?.let(JsonElement::jsonObject)
url = rec["url"]!!.jsonPrimitive.content ?.let(::getImage),
initialized = true,
)
} }
}.orEmpty() }
fun getImage(imageObject: JsonObject): String? {
return imageObject["webp"]
?.jsonObject
?.get("image_url")
?.jsonPrimitive
?.contentOrNull
?: imageObject["jpg"]
?.jsonObject
?.get("image_url")
?.jsonPrimitive
?.contentOrNull
} }
override suspend fun getRecsBySearch(search: String): List<SManga> { override suspend fun getRecsBySearch(search: String): List<SManga> {
val httpUrl = endpoint.toHttpUrlOrNull() ?: throw Exception("Could not convert endpoint url") val url = endpoint.toHttpUrl()
val url = httpUrl.newBuilder() .newBuilder()
.addPathSegment("search")
.addPathSegment("manga") .addPathSegment("manga")
.addQueryParameter("q", search) .addQueryParameter("q", search)
.build() .build()
.toString()
val data = client.newCall(GET(url)).await() val data = client.newCall(GET(url)).await()
.parseAs<JsonObject>() .parseAs<JsonObject>()
val results = data["results"] as? JsonArray return getRecsById(data["data"]!!.jsonArray.first().jsonObject["mal_id"]!!.jsonPrimitive.content)
if (results.isNullOrEmpty()) {
throw Exception("'$search' not found")
}
val result = results.first().jsonObject
val id = result["mal_id"]!!.jsonPrimitive.content
return getRecsById(id)
} }
} }
@ -161,15 +163,17 @@ class Anilist : API("https://graphql.anilist.co/") {
put("query", query) put("query", query)
put("variables", variables) put("variables", variables)
} }
val payloadBody = payload.toString().toRequestBody("application/json; charset=utf-8".toMediaTypeOrNull()) val payloadBody = payload.toString().toRequestBody("application/json; charset=utf-8".toMediaType())
val data = client.newCall(POST(endpoint, body = payloadBody)).await() val data = client.newCall(POST(endpoint, body = payloadBody)).await()
.parseAs<JsonObject>() .parseAs<JsonObject>()
val media = data["Page"]?.jsonObject?.get("media")?.jsonArray val media = data["data"]!!
if (media.isNullOrEmpty()) { .jsonObject["Page"]!!
throw Exception("'$search' not found") .jsonObject["media"]!!
} .jsonArray
.ifEmpty { throw Exception("'$search' not found") }
val result = media.sortedWith( val result = media.sortedWith(
compareBy( compareBy(
{ languageContains(it.jsonObject, "romaji", search) }, { languageContains(it.jsonObject, "romaji", search) },
@ -179,17 +183,17 @@ class Anilist : API("https://graphql.anilist.co/") {
), ),
).last().jsonObject ).last().jsonObject
return result["recommendations"]?.jsonObject?.get("edges")?.jsonArray?.map { return result["recommendations"]!!.jsonObject["edges"]!!.jsonArray.map {
val rec = it.jsonObject["node"]!!.jsonObject["mediaRecommendation"]!!.jsonObject val rec = it.jsonObject["node"]!!.jsonObject["mediaRecommendation"]!!.jsonObject
val recTitle = getTitle(rec) val recTitle = getTitle(rec)
logcat { "ANILIST > RECOMMENDATION: $recTitle" } logcat { "ANILIST > RECOMMENDATION: $recTitle" }
SManga.create().apply { SManga(
title = recTitle title = recTitle,
thumbnail_url = rec["coverImage"]!!.jsonObject["large"]!!.jsonPrimitive.content thumbnail_url = rec["coverImage"]!!.jsonObject["large"]!!.jsonPrimitive.content,
initialized = true initialized = true,
url = rec["siteUrl"]!!.jsonPrimitive.content url = rec["siteUrl"]!!.jsonPrimitive.content,
)
} }
}.orEmpty()
} }
} }
@ -207,13 +211,13 @@ open class RecommendsPagingSource(
val recs = apiList.firstNotNullOfOrNull { (key, api) -> val recs = apiList.firstNotNullOfOrNull { (key, api) ->
try { try {
val recs = api.getRecsBySearch(manga.ogTitle) val recs = api.getRecsBySearch(manga.ogTitle)
logcat { key.toString() + " > Results: " + recs.count() } logcat { key.toString() + " > Results: " + recs.size }
recs recs.ifEmpty { null }
} catch (e: Exception) { } catch (e: Exception) {
logcat(LogPriority.ERROR, e) { key.toString() } logcat(LogPriority.ERROR, e) { key.toString() }
null null
} }
}?.nullIfEmpty() ?: throw NoResultsException() } ?: throw NoResultsException()
return MangasPage(recs, false) return MangasPage(recs, false)
} }