From 78d64713a27cb799fac470e93779d20a45f36780 Mon Sep 17 00:00:00 2001 From: Draken <131387159+dragonx943@users.noreply.github.com> Date: Sat, 28 Sep 2024 18:36:10 +0700 Subject: [PATCH 1/5] Create NetTruyenUU.kt --- .../parsers/site/wpcomics/vi/NetTruyenUU.kt | 133 ++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/NetTruyenUU.kt diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/NetTruyenUU.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/NetTruyenUU.kt new file mode 100644 index 00000000..62a7915b --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/NetTruyenUU.kt @@ -0,0 +1,133 @@ +package org.koitharu.kotatsu.parsers.site.wpcomics.vi + +import androidx.collection.ArrayMap +import kotlinx.coroutines.sync.withLock +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.exception.NotFoundException +import org.koitharu.kotatsu.parsers.model.* +import org.koitharu.kotatsu.parsers.site.wpcomics.WpComicsParser +import org.koitharu.kotatsu.parsers.util.* +import java.util.* + +@MangaSourceParser("NETTRUYENUU", "NetTruyenUU", "vi") +internal class NetTruyenUU(context: MangaLoaderContext) : + WpComicsParser(context, MangaParserSource.NETTRUYENUU, "nettruyenuu.com", 20) { + + override val listUrl = "/tim-kiem-nang-cao" + + override val availableSortOrders: Set = EnumSet.of( + SortOrder.UPDATED, + SortOrder.POPULARITY, + SortOrder.RATING, + SortOrder.NEWEST, + SortOrder.ALPHABETICAL, + SortOrder.ALPHABETICAL_DESC, + ) + + override val filterCapabilities: MangaListFilterCapabilities + get() = super.filterCapabilities.copy( + isMultipleTagsSupported = true, + isTagsExclusionSupported = true, + ) + + override suspend fun getFilterOptions() = super.getFilterOptions().copy( + availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED), + ) + + override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List { + val response = + when { + !filter.query.isNullOrEmpty() -> { + val url = buildString { + append("https://") + append(domain) + append("/search") + append('/') + append(page.toString()) + append('/') + append("?keyword=") + append(filter.query.urlEncoded()) + } + + val result = runCatchingCancellable { webClient.httpGet(url) } + val exception = result.exceptionOrNull() + if (exception is NotFoundException) { + return emptyList() + } + result.getOrThrow() + } + + else -> { + val url = buildString { + append("https://") + append(domain) + append(listUrl) + + append('/') + append(page.toString()) + append('/') + + val tagQuery = filter.tags.joinToString(",") { it.key } + append("?genres=") + append(tagQuery) + + val tagQueryExclude = filter.tagsExclude.joinToString(",") { it.key } + append("¬Genres=") + append(tagQueryExclude) + + append("&sex=All") + + filter.states.oneOrThrowIfMany()?.let { + append("&status=") + append( + when (it) { + MangaState.ONGOING -> "on-going" + MangaState.FINISHED -> "completed" + MangaState.PAUSED -> "on-hold" + MangaState.ABANDONED -> "canceled" + else -> "-1" + }, + ) + } + + append("&chapter_count=0") + + append("&sort=") + append( + when (order) { + SortOrder.UPDATED -> "latest-updated" + SortOrder.POPULARITY -> "views" + SortOrder.NEWEST -> "new" + SortOrder.RATING -> "score" + SortOrder.ALPHABETICAL -> "az" + SortOrder.ALPHABETICAL_DESC -> "za" + else -> null + }, + ) + } + + webClient.httpGet(url) + } + } + + val tagMap = getOrCreateTagMap() + return parseMangaList(response.parseHtml(), tagMap) + } + + override suspend fun getOrCreateTagMap(): ArrayMap = mutex.withLock { + tagCache?.let { return@withLock it } + val doc = webClient.httpGet(listUrl.toAbsoluteUrl(domain)).parseHtml() + val tagItems = doc.select("div.genre-item") + val result = ArrayMap(tagItems.size) + for (item in tagItems) { + val title = item.text() + val key = item.selectFirstOrThrow("span").attr("data-id") + if (key.isNotEmpty() && title.isNotEmpty()) { + result[title] = MangaTag(title = title, key = key, source = source) + } + } + tagCache = result + result + } +} From aac722909bf50163fd15e1b831a624b5550514c4 Mon Sep 17 00:00:00 2001 From: Draken <131387159+dragonx943@users.noreply.github.com> Date: Sat, 28 Sep 2024 18:42:20 +0700 Subject: [PATCH 2/5] Update HentaiVNParser.kt --- .../org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt index 547ed0b3..31021650 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt @@ -21,7 +21,7 @@ private const val SEARCH_PAGE_SIZE = 10 @MangaSourceParser("HENTAIVN", "HentaiVN", "vi", type = ContentType.HENTAI) internal class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaParserSource.HENTAIVN) { - override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("ayamehentai.cc") + override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("ayamehentai.cc", "hentaihvn.tv") override fun onCreateConfig(keys: MutableCollection>) { super.onCreateConfig(keys) From 06d6653c782faeaa6111b9ba0a81c1ff04fac550 Mon Sep 17 00:00:00 2001 From: Draken <131387159+dragonx943@users.noreply.github.com> Date: Sat, 28 Sep 2024 18:54:05 +0700 Subject: [PATCH 3/5] Create DocTruyen3Q.kt --- .../kotatsu/parsers/site/wpcomics/vi/DocTruyen3Q.kt | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/DocTruyen3Q.kt diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/DocTruyen3Q.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/DocTruyen3Q.kt new file mode 100644 index 00000000..1f38ccec --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/DocTruyen3Q.kt @@ -0,0 +1,10 @@ +package org.koitharu.kotatsu.parsers.site.wpcomics.vi + +import org.koitharu.kotatsu.parsers.MangaLoaderContext +import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.MangaParserSource +import org.koitharu.kotatsu.parsers.site.wpcomics.WpComicsParser + +@MangaSourceParser("DOCTRUYEN3Q", "DocTruyen3Q", "vi") +internal class TopTruyenViet(context: MangaLoaderContext) : + WpComicsParser(context, MangaParserSource.DOCTRUYEN3Q, "doctruyen3qto.pro", 36) From c6325eef5088b5ffee00c1a989bdcffe7f273bf9 Mon Sep 17 00:00:00 2001 From: Draken <131387159+dragonx943@users.noreply.github.com> Date: Sat, 28 Sep 2024 18:59:16 +0700 Subject: [PATCH 4/5] Update DocTruyen3Q.kt --- .../koitharu/kotatsu/parsers/site/wpcomics/vi/DocTruyen3Q.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/DocTruyen3Q.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/DocTruyen3Q.kt index 1f38ccec..c5de80fd 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/DocTruyen3Q.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/wpcomics/vi/DocTruyen3Q.kt @@ -6,5 +6,5 @@ import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.wpcomics.WpComicsParser @MangaSourceParser("DOCTRUYEN3Q", "DocTruyen3Q", "vi") -internal class TopTruyenViet(context: MangaLoaderContext) : +internal class DocTruyen3Q(context: MangaLoaderContext) : WpComicsParser(context, MangaParserSource.DOCTRUYEN3Q, "doctruyen3qto.pro", 36) From e93a6865e7435aadcbcab4dde509b21eb6630bae Mon Sep 17 00:00:00 2001 From: Draken <131387159+dragonx943@users.noreply.github.com> Date: Sat, 28 Sep 2024 20:07:57 +0700 Subject: [PATCH 5/5] Update HentaiVNParser.kt --- .../org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt index 31021650..a399bd99 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/vi/HentaiVNParser.kt @@ -21,7 +21,7 @@ private const val SEARCH_PAGE_SIZE = 10 @MangaSourceParser("HENTAIVN", "HentaiVN", "vi", type = ContentType.HENTAI) internal class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaParserSource.HENTAIVN) { - override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("ayamehentai.cc", "hentaihvn.tv") + override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("hentaihvn.tv", "ayamehentai.cc") override fun onCreateConfig(keys: MutableCollection>) { super.onCreateConfig(keys)