Dantotsu/app/src/main/java/ani/dantotsu/others/Kitsu.kt
2024-08-12 12:37:34 +05:30

155 lines
4.4 KiB
Kotlin

package ani.dantotsu.others
import ani.dantotsu.FileUrl
import ani.dantotsu.client
import ani.dantotsu.media.Media
import ani.dantotsu.media.anime.Episode
import ani.dantotsu.tryWithSuspend
import ani.dantotsu.util.Logger
import com.google.gson.Gson
import com.lagradost.nicehttp.NiceResponse
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import java.io.InputStreamReader
import java.util.zip.GZIPInputStream
object Kitsu {
private suspend fun getKitsuData(query: String): KitsuResponse? {
val headers = mapOf(
"Content-Type" to "application/json",
"Accept" to "application/json",
"Accept-Encoding" to "gzip, deflate",
"Accept-Language" to "en-US,en;q=0.5",
"Host" to "kitsu.app",
"Connection" to "keep-alive",
"Origin" to "https://kitsu.app",
"Sec-Fetch-Dest" to "empty",
"Sec-Fetch-Mode" to "cors",
"Sec-Fetch-Site" to "cross-site",
)
val response = tryWithSuspend {
val res = client.post(
"https://kitsu.app/api/graphql",
headers,
data = mapOf("query" to query)
)
res
}
val json = decodeToString(response)
val gson = Gson()
return gson.fromJson(json, KitsuResponse::class.java)
}
suspend fun getKitsuEpisodesDetails(media: Media): Map<String, Episode>? {
Logger.log("Kitsu : title=${media.mainName()}")
val query =
"""
query {
lookupMapping(externalId: ${media.id}, externalSite: ANILIST_ANIME) {
__typename
... on Anime {
id
episodes(first: 2000) {
nodes {
number
titles {
canonical
}
description
thumbnail {
original {
url
}
}
}
}
}
}
}""".trimIndent()
val result = getKitsuData(query) ?: return null
//Logger.log("Kitsu : result=$result")
media.idKitsu = result.data?.lookupMapping?.id
val a = (result.data?.lookupMapping?.episodes?.nodes ?: return null).mapNotNull { ep ->
val num = ep?.number?.toString() ?: return@mapNotNull null
num to Episode(
number = num,
title = ep.titles?.canonical,
desc = ep.description?.en,
thumb = FileUrl[ep.thumbnail?.original?.url],
)
}.toMap()
//Logger.log("Kitsu : a=$a")
return a
}
private fun decodeToString(res: NiceResponse?): String? {
return when (res?.headers?.get("Content-Encoding")) {
"gzip" -> {
res.body.byteStream().use { inputStream ->
GZIPInputStream(inputStream).use { gzipInputStream ->
InputStreamReader(gzipInputStream).use { reader ->
reader.readText()
}
}
}
}
else -> {
res?.body?.string()
}
}
}
@Serializable
private data class KitsuResponse(
@SerialName("data") val data: Data? = null
) {
@Serializable
data class Data(
@SerialName("lookupMapping") val lookupMapping: LookupMapping? = null
)
@Serializable
data class LookupMapping(
@SerialName("id") val id: String? = null,
@SerialName("episodes") val episodes: Episodes? = null
)
@Serializable
data class Episodes(
@SerialName("nodes") val nodes: List<Node?>? = null
)
@Serializable
data class Node(
@SerialName("number") val number: Int? = null,
@SerialName("titles") val titles: Titles? = null,
@SerialName("description") val description: Description? = null,
@SerialName("thumbnail") val thumbnail: Thumbnail? = null
)
@Serializable
data class Description(
@SerialName("en") val en: String? = null
)
@Serializable
data class Thumbnail(
@SerialName("original") val original: Original? = null
)
@Serializable
data class Original(
@SerialName("url") val url: String? = null
)
@Serializable
data class Titles(
@SerialName("canonical") val canonical: String? = null
)
}
}