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 { val apiUrl = endpoint.toHttpUrl() .newBuilder() .addPathSegment("series") .addPathSegment(id) .build() val data = with(json) { client.newCall(GET(apiUrl)).awaitSuccess().parseAs() } return getRecommendations(data[recommendationJsonObjectName]!!.jsonArray) } private fun getRecommendations(recommendations: JsonArray): List { 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 { 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() } 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" }