diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineMangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineMangaParser.kt index 5d9ef843..4ef6b192 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineMangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/all/NineMangaParser.kt @@ -35,6 +35,11 @@ internal abstract class NineMangaParser( SortOrder.POPULARITY, ) + override val availableStates: Set = EnumSet.of( + MangaState.ONGOING, + MangaState.FINISHED, + ) + override fun intercept(chain: Interceptor.Chain): Response { val request = chain.request() val newRequest = if (request.url.host == domain) { @@ -45,37 +50,60 @@ internal abstract class NineMangaParser( return chain.proceed(newRequest) } - override suspend fun getListPage( - page: Int, - query: String?, - tags: Set?, - sortOrder: SortOrder, - ): List { + override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { val url = buildString { append("https://") append(domain) - when { - !query.isNullOrEmpty() -> { + when (filter) { + is MangaListFilter.Search -> { append("/search/?name_sel=&wd=") - append(query.urlEncoded()) + append(filter.query.urlEncoded()) append("&page=") + append(page) + append(".html") } - !tags.isNullOrEmpty() -> { - append("/search/?category_id=") - for (tag in tags) { - append(tag.key) - append(',') + is MangaListFilter.Advanced -> { + if (filter.tags.isNotEmpty()) { + append("/search/?category_id=") + for (tag in filter.tags) { + append(tag.key) + append(',') + } + + filter.states.oneOrThrowIfMany()?.let { + append("&completed_series=") + when (it) { + MangaState.ONGOING -> append("no") + MangaState.FINISHED -> append("yes") + else -> append("either") + } + } + append("&page=") + } else { + append("/category/") + if (filter.states.isNotEmpty()) { + filter.states.oneOrThrowIfMany()?.let { + when (it) { + MangaState.ONGOING -> append("updated_") + MangaState.FINISHED -> append("completed_") + else -> append("either") + } + } + } else { + append("index_") + } } - append("&page=") + append(page) + append(".html") } - else -> { + null -> { append("/category/index_") + append(page) + append(".html") } } - append(page) - append(".html") } val doc = webClient.httpGet(url).parseHtml() val root = doc.body().selectFirst("ul.direlist") ?: doc.parseFailed("Cannot find root") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt index 7b029cd5..ae86a442 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fr/BentomangaParser.kt @@ -28,35 +28,55 @@ internal class BentomangaParser(context: MangaLoaderContext) : PagedMangaParser( override val configKeyDomain = ConfigKey.Domain("bentomanga.com", "www.bentomanga.com") + override val availableStates: Set = EnumSet.allOf(MangaState::class.java) + init { paginator.firstPage = 0 searchPaginator.firstPage = 0 } - override suspend fun getListPage( - page: Int, - query: String?, - tags: Set?, - sortOrder: SortOrder, - ): List { + override suspend fun getListPage(page: Int, filter: MangaListFilter?): List { val url = urlBuilder() + .host(domain) .addPathSegment("manga_list") .addQueryParameter("limit", page.toString()) - .addQueryParameter( - "order_by", - when (sortOrder) { - SortOrder.UPDATED -> "update" - SortOrder.POPULARITY -> "views" - SortOrder.RATING -> "top" - SortOrder.NEWEST -> "create" - SortOrder.ALPHABETICAL -> "name" - }, - ) - if (!tags.isNullOrEmpty()) { - url.addQueryParameter("withCategories", tags.joinToString(",") { it.key }) - } - if (!query.isNullOrEmpty()) { - url.addQueryParameter("search", query) + when (filter) { + is MangaListFilter.Search -> { + url.addQueryParameter("search", filter.query) + } + + is MangaListFilter.Advanced -> { + + url.addQueryParameter( + "order_by", + when (filter.sortOrder) { + SortOrder.UPDATED -> "update" + SortOrder.POPULARITY -> "views" + SortOrder.RATING -> "top" + SortOrder.NEWEST -> "create" + SortOrder.ALPHABETICAL -> "name" + }, + ) + + if (filter.tags.isNotEmpty()) { + url.addQueryParameter("withCategories", filter.tags.joinToString(",") { it.key }) + } + + filter.states.oneOrThrowIfMany()?.let { + url.addQueryParameter( + "state", + when (it) { + MangaState.ONGOING -> "1" + MangaState.FINISHED -> "2" + MangaState.PAUSED -> "3" + MangaState.ABANDONED -> "5" + }, + ) + } + + } + + null -> url.addQueryParameter("order_by", "update") } val root = webClient.httpGet(url.build()).parseHtml().requireElementById("mangas_content") return root.select(".manga[data-manga]").map { div -> @@ -109,7 +129,7 @@ internal class BentomangaParser(context: MangaLoaderContext) : PagedMangaParser( "En pause" -> MangaState.PAUSED else -> null }, - author = root.selectFirst(".datas_more-authors-people")?.textOrNull().assertNotNull("author"), + author = root.selectFirst(".datas_more-authors-people")?.textOrNull(), chapters = run { val input = root.selectFirst("input[name=\"limit\"]") ?: return@run parseChapters(root) val max = input.attr("max").toInt()