diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/HentaiVnPlus.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/HentaiVnPlus.kt index 097c7e24c..b7355cf10 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/HentaiVnPlus.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/madara/vi/HentaiVnPlus.kt @@ -2,9 +2,17 @@ package org.koitharu.kotatsu.parsers.site.madara.vi import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.ContentRating import org.koitharu.kotatsu.parsers.model.ContentType +import org.koitharu.kotatsu.parsers.model.Manga +import org.koitharu.kotatsu.parsers.model.MangaListFilter import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.model.MangaState +import org.koitharu.kotatsu.parsers.model.SortOrder import org.koitharu.kotatsu.parsers.site.madara.MadaraParser +import org.koitharu.kotatsu.parsers.util.oneOrThrowIfMany +import org.koitharu.kotatsu.parsers.util.parseHtml +import org.koitharu.kotatsu.parsers.util.urlEncoded @MangaSourceParser("HENTAIVNPLUS", "HentaiVN.plus", "vi", ContentType.HENTAI) internal class HentaiVnPlus(context: MangaLoaderContext) : @@ -12,4 +20,99 @@ internal class HentaiVnPlus(context: MangaLoaderContext) : override val listUrl = "truyen-hentai/" override val tagPrefix = "the-loai/" override val datePattern = "dd/MM/yyyy" + override val authorSearchSupported = true + + override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List { + val pages = page + 1 + + val url = buildString { + if (!filter.author.isNullOrEmpty()) { + clear() + append("https://") + append(domain) + append("/tac-gia/") + append(filter.author.lowercase().replace(" ", "-")) + + if (pages > 1) { + append("/page/") + append(pages.toString()) + } + + append("/?m_orderby=") + when (order) { + SortOrder.POPULARITY -> append("views") + SortOrder.UPDATED -> append("latest") + SortOrder.NEWEST -> append("new-manga") + SortOrder.ALPHABETICAL -> {} + SortOrder.RATING -> append("trending") + SortOrder.RELEVANCE -> {} + else -> append("latest") // default + } + return@buildString + } + + append("https://") + append(domain) + + if (pages > 1) { + append("/page/") + append(pages.toString()) + } + + append("/?s=") + + filter.query?.let { + append(filter.query.urlEncoded()) + } + + append("&post_type=wp-manga") + + if (filter.tags.isNotEmpty()) { + filter.tags.forEach { + append("&genre[]=") + append(it.key) + } + } + + filter.states.forEach { + append("&status[]=") + when (it) { + MangaState.ONGOING -> append("on-going") + MangaState.FINISHED -> append("end") + MangaState.ABANDONED -> append("canceled") + MangaState.PAUSED -> append("on-hold") + MangaState.UPCOMING -> append("upcoming") + else -> throw IllegalArgumentException("$it not supported") + } + } + + filter.contentRating.oneOrThrowIfMany()?.let { + append("&adult=") + append( + when (it) { + ContentRating.SAFE -> "0" + ContentRating.ADULT -> "1" + else -> "" + }, + ) + } + + if (filter.year != 0) { + append("&release=") + append(filter.year.toString()) + } + + append("&m_orderby=") + when (order) { + SortOrder.POPULARITY -> append("views") + SortOrder.UPDATED -> append("latest") + SortOrder.NEWEST -> append("new-manga") + SortOrder.ALPHABETICAL -> append("alphabet") + SortOrder.RATING -> append("rating") + SortOrder.RELEVANCE -> {} + else -> {} + } + } + return parseMangaList(webClient.httpGet(url).parseHtml()) + } }