From 80a4753f3d42b3bf476071aa2d98483f570cc870 Mon Sep 17 00:00:00 2001 From: Tim Schneeberger Date: Mon, 13 Jan 2025 22:18:35 +0100 Subject: [PATCH] NamiComi: lower chapter list page size and fix missing tags (#7145) * fix(namicomi): request tags in searchMangaRequest * fix(namicomi): request chapter lists & chapter access maps in chunks of 200 entities * fix(namicomi): read id directly from URL query parameter instead of using string manipulation * chore(namicomi): bump version code * Fix regression caused by simplification of createManga(...) * Add missing slash * Use new extension function to add parameters --- src/all/namicomi/build.gradle | 2 +- .../extension/all/namicomi/NamiComi.kt | 47 ++++++++++--------- 2 files changed, 27 insertions(+), 22 deletions(-) diff --git a/src/all/namicomi/build.gradle b/src/all/namicomi/build.gradle index 11a531ba564..308aa7a6e59 100644 --- a/src/all/namicomi/build.gradle +++ b/src/all/namicomi/build.gradle @@ -1,7 +1,7 @@ ext { extName = 'NamiComi' extClass = '.NamiComiFactory' - extVersionCode = 1 + extVersionCode = 2 isNsfw = false } diff --git a/src/all/namicomi/src/eu/kanade/tachiyomi/extension/all/namicomi/NamiComi.kt b/src/all/namicomi/src/eu/kanade/tachiyomi/extension/all/namicomi/NamiComi.kt index 5290e2a9ea7..48d167749d6 100644 --- a/src/all/namicomi/src/eu/kanade/tachiyomi/extension/all/namicomi/NamiComi.kt +++ b/src/all/namicomi/src/eu/kanade/tachiyomi/extension/all/namicomi/NamiComi.kt @@ -25,6 +25,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource import kotlinx.serialization.decodeFromString import kotlinx.serialization.encodeToString import okhttp3.CacheControl +import okhttp3.HttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.Request import okhttp3.RequestBody.Companion.toRequestBody @@ -71,10 +72,7 @@ abstract class NamiComi(final override val lang: String, private val extLang: St .addQueryParameter("availableTranslatedLanguages[]", extLang) .addQueryParameter("limit", NamiComiConstants.mangaLimit.toString()) .addQueryParameter("offset", helper.getMangaListOffset(page)) - .addQueryParameter("includes[]", NamiComiConstants.coverArt) - .addQueryParameter("includes[]", NamiComiConstants.primaryTag) - .addQueryParameter("includes[]", NamiComiConstants.secondaryTag) - .addQueryParameter("includes[]", NamiComiConstants.tag) + .addCommonIncludeParameters() .build() return GET(url, headers, CacheControl.FORCE_NETWORK) @@ -126,7 +124,7 @@ abstract class NamiComi(final override val lang: String, private val extLang: St // If the query is an ID, return the manga directly val url = NamiComiConstants.apiSearchUrl.toHttpUrl().newBuilder() .addQueryParameter("ids[]", query.removePrefix(NamiComiConstants.prefixIdSearch)) - .addQueryParameter("includes[]", NamiComiConstants.coverArt) + .addCommonIncludeParameters() .build() return GET(url, headers, CacheControl.FORCE_NETWORK) @@ -135,7 +133,7 @@ abstract class NamiComi(final override val lang: String, private val extLang: St val tempUrl = NamiComiConstants.apiSearchUrl.toHttpUrl().newBuilder() .addQueryParameter("limit", NamiComiConstants.mangaLimit.toString()) .addQueryParameter("offset", helper.getMangaListOffset(page)) - .addQueryParameter("includes[]", NamiComiConstants.coverArt) + .addCommonIncludeParameters() val actualQuery = query.replace(NamiComiConstants.whitespaceRegex, " ") if (actualQuery.isNotBlank()) { @@ -162,12 +160,8 @@ abstract class NamiComi(final override val lang: String, private val extLang: St * Get the API endpoint URL for the entry details. */ override fun mangaDetailsRequest(manga: SManga): Request { - val url = (NamiComiConstants.apiMangaUrl + manga.url).toHttpUrl().newBuilder() - .addQueryParameter("includes[]", NamiComiConstants.coverArt) - .addQueryParameter("includes[]", NamiComiConstants.organization) - .addQueryParameter("includes[]", NamiComiConstants.tag) - .addQueryParameter("includes[]", NamiComiConstants.primaryTag) - .addQueryParameter("includes[]", NamiComiConstants.secondaryTag) + val url = ("${NamiComiConstants.apiMangaUrl}/${manga.url}").toHttpUrl().newBuilder() + .addCommonIncludeParameters() .build() return GET(url, headers, CacheControl.FORCE_NETWORK) @@ -199,7 +193,7 @@ abstract class NamiComi(final override val lang: String, private val extLang: St val url = NamiComiConstants.apiChapterUrl.toHttpUrl().newBuilder() .addQueryParameter("titleId", mangaId) .addQueryParameter("includes[]", NamiComiConstants.organization) - .addQueryParameter("limit", "500") + .addQueryParameter("limit", "200") .addQueryParameter("offset", offset.toString()) .addQueryParameter("translatedLanguages[]", extLang) .addQueryParameter("order[volume]", "desc") @@ -229,16 +223,14 @@ abstract class NamiComi(final override val lang: String, private val extLang: St return emptyList() } - val mangaId = response.request.url.toString() - .substringBefore("/chapter") - .substringAfter("${NamiComiConstants.apiMangaUrl}/") + val mangaId = response.request.url.queryParameter("titleId")!! val chapterListResponse = response.parseAs() val chapterListResults = chapterListResponse.data.toMutableList() var offset = chapterListResponse.meta.offset var hasNextPage = chapterListResponse.meta.hasNextPage - // Max results that can be returned is 500 so need to make more API + // Max results that can be returned is 200 so need to make more API // calls if the chapter list response has a next page. while (hasNextPage) { offset += chapterListResponse.meta.limit @@ -256,10 +248,16 @@ abstract class NamiComi(final override val lang: String, private val extLang: St return emptyList() } - val gatingCheckRequest = accessibleChapterListRequest(chapterListResults.map { it.id }) - val gatingCheckResponse = client.newCall(gatingCheckRequest).execute() - val accessibleChapterMap = gatingCheckResponse.parseAs() - .data?.attributes?.map ?: emptyMap() + // Split chapter access checks into chunks of 200 chapters + val chapterListResultsChunks = chapterListResults.map { it.id }.chunked(200) + val accessibleChapterMap: MutableMap = mutableMapOf() + + for (chapterIds in chapterListResultsChunks) { + val gatingCheckRequest = accessibleChapterListRequest(chapterIds) + val gatingCheckResponse = client.newCall(gatingCheckRequest).execute() + accessibleChapterMap += gatingCheckResponse.parseAs() + .data?.attributes?.map ?: emptyMap() + } return chapterListResults.mapNotNull { val isAccessible = accessibleChapterMap[it.id]!! @@ -339,6 +337,13 @@ abstract class NamiComi(final override val lang: String, private val extLang: St override fun getFilterList(): FilterList = helper.filters.getFilterList(helper.intl) + private fun HttpUrl.Builder.addCommonIncludeParameters() = + this.addQueryParameter("includes[]", NamiComiConstants.coverArt) + .addQueryParameter("includes[]", NamiComiConstants.organization) + .addQueryParameter("includes[]", NamiComiConstants.tag) + .addQueryParameter("includes[]", NamiComiConstants.primaryTag) + .addQueryParameter("includes[]", NamiComiConstants.secondaryTag) + private inline fun Response.parseAs(): T = use { helper.json.decodeFromString(body.string()) }