diff --git a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt index 348debe44..3ced8edac 100644 --- a/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt +++ b/app/src/main/java/org/koitharu/kotatsu/core/parser/site/GroupleRepository.kt @@ -1,6 +1,7 @@ package org.koitharu.kotatsu.core.parser.site import androidx.collection.arraySetOf +import androidx.core.net.toUri import org.koitharu.kotatsu.core.exceptions.ParseException import org.koitharu.kotatsu.core.model.* import org.koitharu.kotatsu.core.parser.RemoteMangaRepository @@ -30,33 +31,39 @@ abstract class GroupleRepository(loaderContext: MangaLoaderContext) : val doc = when { !query.isNullOrEmpty() -> loaderContext.httpPost( "https://$domain/search", - mapOf("q" to query.urlEncoded(), "offset" to offset.toString()) + mapOf( + "q" to query.urlEncoded(), + "offset" to offset.upBy(PAGE_SIZE_SEARCH).toString() + ) ) tag == null -> loaderContext.httpGet( "https://$domain/list?sortType=${ getSortKey( sortOrder ) - }&offset=$offset" + }&offset=${offset.upBy(PAGE_SIZE)}" ) else -> loaderContext.httpGet( "https://$domain/list/genre/${tag.key}?sortType=${ getSortKey( sortOrder ) - }&offset=$offset" + }&offset=${offset.upBy(PAGE_SIZE)}" ) }.parseHtml() val root = doc.body().getElementById("mangaBox") ?.selectFirst("div.tiles.row") ?: throw ParseException("Cannot find root") + val baseHost = root.baseUri().toUri().host return root.select("div.tile").mapNotNull { node -> val imgDiv = node.selectFirst("div.img") ?: return@mapNotNull null val descDiv = node.selectFirst("div.desc") ?: return@mapNotNull null if (descDiv.selectFirst("i.fa-user") != null) { return@mapNotNull null //skip author } - val href = imgDiv.selectFirst("a").attr("href")?.withDomain(domain) - ?: return@mapNotNull null + val href = imgDiv.selectFirst("a").attr("href")?.inContextOf(node) + if (href == null || href.toUri().host != baseHost) { + return@mapNotNull null // skip external links + } val title = descDiv.selectFirst("h3")?.selectFirst("a")?.text() ?: return@mapNotNull null val tileInfo = descDiv.selectFirst("div.tile-info") @@ -179,4 +186,10 @@ abstract class GroupleRepository(loaderContext: MangaLoaderContext) : SortOrder.RATING -> "votes" null -> "updated" } + + private companion object { + + private const val PAGE_SIZE = 70 + private const val PAGE_SIZE_SEARCH = 50 + } } \ No newline at end of file diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/JsonExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/JsonExt.kt index 69823ffcb..c1c91f9f3 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/JsonExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/JsonExt.kt @@ -4,14 +4,20 @@ import androidx.collection.ArraySet import org.json.JSONArray import org.json.JSONObject -fun JSONArray.map(block: (JSONObject) -> T): List { +inline fun > JSONArray.mapTo( + destination: C, + block: (JSONObject) -> R +): C { val len = length() - val result = ArrayList(len) for (i in 0 until len) { val jo = getJSONObject(i) - result.add(block(jo)) + destination.add(block(jo)) } - return result + return destination +} + +inline fun JSONArray.map(block: (JSONObject) -> T): List { + return mapTo(ArrayList(length()), block) } fun JSONArray.mapIndexed(block: (Int, JSONObject) -> T): List { diff --git a/app/src/main/java/org/koitharu/kotatsu/utils/ext/PrimitiveExt.kt b/app/src/main/java/org/koitharu/kotatsu/utils/ext/PrimitiveExt.kt index b6fd83b6b..525418ea2 100644 --- a/app/src/main/java/org/koitharu/kotatsu/utils/ext/PrimitiveExt.kt +++ b/app/src/main/java/org/koitharu/kotatsu/utils/ext/PrimitiveExt.kt @@ -31,4 +31,13 @@ fun Float.toIntUp(): Int { } else { intValue + 1 } +} + +fun Int.upBy(step: Int): Int { + val mod = this % step + return if (mod == this) { + this + } else { + this - mod + step + } } \ No newline at end of file