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
This commit is contained in:
Tim Schneeberger 2025-01-13 22:18:35 +01:00 committed by Draff
parent cf29bdafd3
commit 4ceef9ca9b
No known key found for this signature in database
GPG Key ID: E8A89F3211677653
2 changed files with 27 additions and 22 deletions

View File

@ -1,7 +1,7 @@
ext { ext {
extName = 'NamiComi' extName = 'NamiComi'
extClass = '.NamiComiFactory' extClass = '.NamiComiFactory'
extVersionCode = 1 extVersionCode = 2
isNsfw = false isNsfw = false
} }

View File

@ -25,6 +25,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource
import kotlinx.serialization.decodeFromString import kotlinx.serialization.decodeFromString
import kotlinx.serialization.encodeToString import kotlinx.serialization.encodeToString
import okhttp3.CacheControl import okhttp3.CacheControl
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody 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("availableTranslatedLanguages[]", extLang)
.addQueryParameter("limit", NamiComiConstants.mangaLimit.toString()) .addQueryParameter("limit", NamiComiConstants.mangaLimit.toString())
.addQueryParameter("offset", helper.getMangaListOffset(page)) .addQueryParameter("offset", helper.getMangaListOffset(page))
.addQueryParameter("includes[]", NamiComiConstants.coverArt) .addCommonIncludeParameters()
.addQueryParameter("includes[]", NamiComiConstants.primaryTag)
.addQueryParameter("includes[]", NamiComiConstants.secondaryTag)
.addQueryParameter("includes[]", NamiComiConstants.tag)
.build() .build()
return GET(url, headers, CacheControl.FORCE_NETWORK) 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 // If the query is an ID, return the manga directly
val url = NamiComiConstants.apiSearchUrl.toHttpUrl().newBuilder() val url = NamiComiConstants.apiSearchUrl.toHttpUrl().newBuilder()
.addQueryParameter("ids[]", query.removePrefix(NamiComiConstants.prefixIdSearch)) .addQueryParameter("ids[]", query.removePrefix(NamiComiConstants.prefixIdSearch))
.addQueryParameter("includes[]", NamiComiConstants.coverArt) .addCommonIncludeParameters()
.build() .build()
return GET(url, headers, CacheControl.FORCE_NETWORK) 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() val tempUrl = NamiComiConstants.apiSearchUrl.toHttpUrl().newBuilder()
.addQueryParameter("limit", NamiComiConstants.mangaLimit.toString()) .addQueryParameter("limit", NamiComiConstants.mangaLimit.toString())
.addQueryParameter("offset", helper.getMangaListOffset(page)) .addQueryParameter("offset", helper.getMangaListOffset(page))
.addQueryParameter("includes[]", NamiComiConstants.coverArt) .addCommonIncludeParameters()
val actualQuery = query.replace(NamiComiConstants.whitespaceRegex, " ") val actualQuery = query.replace(NamiComiConstants.whitespaceRegex, " ")
if (actualQuery.isNotBlank()) { 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. * Get the API endpoint URL for the entry details.
*/ */
override fun mangaDetailsRequest(manga: SManga): Request { override fun mangaDetailsRequest(manga: SManga): Request {
val url = (NamiComiConstants.apiMangaUrl + manga.url).toHttpUrl().newBuilder() val url = ("${NamiComiConstants.apiMangaUrl}/${manga.url}").toHttpUrl().newBuilder()
.addQueryParameter("includes[]", NamiComiConstants.coverArt) .addCommonIncludeParameters()
.addQueryParameter("includes[]", NamiComiConstants.organization)
.addQueryParameter("includes[]", NamiComiConstants.tag)
.addQueryParameter("includes[]", NamiComiConstants.primaryTag)
.addQueryParameter("includes[]", NamiComiConstants.secondaryTag)
.build() .build()
return GET(url, headers, CacheControl.FORCE_NETWORK) 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() val url = NamiComiConstants.apiChapterUrl.toHttpUrl().newBuilder()
.addQueryParameter("titleId", mangaId) .addQueryParameter("titleId", mangaId)
.addQueryParameter("includes[]", NamiComiConstants.organization) .addQueryParameter("includes[]", NamiComiConstants.organization)
.addQueryParameter("limit", "500") .addQueryParameter("limit", "200")
.addQueryParameter("offset", offset.toString()) .addQueryParameter("offset", offset.toString())
.addQueryParameter("translatedLanguages[]", extLang) .addQueryParameter("translatedLanguages[]", extLang)
.addQueryParameter("order[volume]", "desc") .addQueryParameter("order[volume]", "desc")
@ -229,16 +223,14 @@ abstract class NamiComi(final override val lang: String, private val extLang: St
return emptyList() return emptyList()
} }
val mangaId = response.request.url.toString() val mangaId = response.request.url.queryParameter("titleId")!!
.substringBefore("/chapter")
.substringAfter("${NamiComiConstants.apiMangaUrl}/")
val chapterListResponse = response.parseAs<ChapterListDto>() val chapterListResponse = response.parseAs<ChapterListDto>()
val chapterListResults = chapterListResponse.data.toMutableList() val chapterListResults = chapterListResponse.data.toMutableList()
var offset = chapterListResponse.meta.offset var offset = chapterListResponse.meta.offset
var hasNextPage = chapterListResponse.meta.hasNextPage 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. // calls if the chapter list response has a next page.
while (hasNextPage) { while (hasNextPage) {
offset += chapterListResponse.meta.limit offset += chapterListResponse.meta.limit
@ -256,10 +248,16 @@ abstract class NamiComi(final override val lang: String, private val extLang: St
return emptyList() return emptyList()
} }
val gatingCheckRequest = accessibleChapterListRequest(chapterListResults.map { it.id }) // Split chapter access checks into chunks of 200 chapters
val chapterListResultsChunks = chapterListResults.map { it.id }.chunked(200)
val accessibleChapterMap: MutableMap<String, Boolean> = mutableMapOf()
for (chapterIds in chapterListResultsChunks) {
val gatingCheckRequest = accessibleChapterListRequest(chapterIds)
val gatingCheckResponse = client.newCall(gatingCheckRequest).execute() val gatingCheckResponse = client.newCall(gatingCheckRequest).execute()
val accessibleChapterMap = gatingCheckResponse.parseAs<EntityAccessMapDto>() accessibleChapterMap += gatingCheckResponse.parseAs<EntityAccessMapDto>()
.data?.attributes?.map ?: emptyMap() .data?.attributes?.map ?: emptyMap()
}
return chapterListResults.mapNotNull { return chapterListResults.mapNotNull {
val isAccessible = accessibleChapterMap[it.id]!! 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 = override fun getFilterList(): FilterList =
helper.filters.getFilterList(helper.intl) 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 <reified T> Response.parseAs(): T = use { private inline fun <reified T> Response.parseAs(): T = use {
helper.json.decodeFromString(body.string()) helper.json.decodeFromString(body.string())
} }