komikku/app/src/main/java/exh/recs/sources/MangaUpdatesPagingSource.kt

115 lines
4 KiB
Kotlin
Raw Normal View History

package exh.recs.sources
import dev.icerock.moko.resources.StringResource
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.awaitSuccess
import eu.kanade.tachiyomi.network.parseAs
import eu.kanade.tachiyomi.source.model.SManga
import kotlinx.serialization.json.JsonArray
import kotlinx.serialization.json.JsonElement
import kotlinx.serialization.json.JsonObject
import kotlinx.serialization.json.buildJsonObject
import kotlinx.serialization.json.contentOrNull
import kotlinx.serialization.json.jsonArray
import kotlinx.serialization.json.jsonObject
import kotlinx.serialization.json.jsonPrimitive
import kotlinx.serialization.json.put
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import tachiyomi.core.common.util.system.logcat
import tachiyomi.data.source.NoResultsException
import tachiyomi.domain.manga.model.Manga
import tachiyomi.i18n.sy.SYMR
abstract class MangaUpdatesPagingSource(manga: Manga) : TrackerRecommendationPagingSource(
"https://api.mangaupdates.com/v1/",
manga,
) {
override val name: String
get() = "MangaUpdates"
override val associatedTrackerId: Long
get() = trackerManager.mangaUpdates.id
protected abstract val recommendationJsonObjectName: String
override suspend fun getRecsById(id: String): List<SManga> {
val apiUrl = endpoint.toHttpUrl()
.newBuilder()
.addPathSegment("series")
.addPathSegment(id)
.build()
val data = with(json) { client.newCall(GET(apiUrl)).awaitSuccess().parseAs<JsonObject>() }
return getRecommendations(data[recommendationJsonObjectName]!!.jsonArray)
}
private fun getRecommendations(recommendations: JsonArray): List<SManga> {
return recommendations
.map(JsonElement::jsonObject)
.map { rec ->
logcat { "MANGAUPDATES > RECOMMENDATION: " + rec["series_name"]!!.jsonPrimitive.content }
SManga(
title = rec["series_name"]!!.jsonPrimitive.content,
url = rec["series_url"]!!.jsonPrimitive.content,
thumbnail_url = rec["series_image"]
?.jsonObject
?.get("url")
?.jsonObject
?.get("original")
?.jsonPrimitive
?.contentOrNull,
initialized = true,
)
}
}
override suspend fun getRecsBySearch(search: String): List<SManga> {
val url = endpoint.toHttpUrl()
.newBuilder()
.addPathSegments("series/search")
.build()
.toString()
val payload = buildJsonObject {
put("search", search)
put("stype", "title")
}
val body = payload
.toString()
.toRequestBody("application/json; charset=utf-8".toMediaType())
val data = with(json) {
client.newCall(POST(url, body = body))
.awaitSuccess()
.parseAs<JsonObject>()
}
return getRecsById(
data["results"]!!
.jsonArray
.ifEmpty { throw NoResultsException() }
.first()
.jsonObject["record"]!!
.jsonObject["series_id"]!!
.jsonPrimitive.content,
)
}
}
class MangaUpdatesCommunityPagingSource(manga: Manga) : MangaUpdatesPagingSource(manga) {
override val category: StringResource
get() = SYMR.strings.community_recommendations
override val recommendationJsonObjectName: String
get() = "recommendations"
}
class MangaUpdatesSimilarPagingSource(manga: Manga) : MangaUpdatesPagingSource(manga) {
override val category: StringResource
get() = SYMR.strings.similar_titles
override val recommendationJsonObjectName: String
get() = "category_recommendations"
}