From 32e7b7184f8e9bafe5a2dd394d9139a2ba6c51e5 Mon Sep 17 00:00:00 2001 From: palaks-1 Date: Thu, 13 Feb 2025 12:39:49 +0200 Subject: [PATCH] [NHentai.to] Add source --- .github/summary.yaml | 2 +- .../site/galleryadults/GalleryAdultsParser.kt | 3 +- .../site/galleryadults/all/NHentaiToParser.kt | 115 ++++++++++++++++++ 3 files changed, 118 insertions(+), 2 deletions(-) create mode 100644 src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/NHentaiToParser.kt diff --git a/.github/summary.yaml b/.github/summary.yaml index 84edfe5b..9b400d1b 100644 --- a/.github/summary.yaml +++ b/.github/summary.yaml @@ -1 +1 @@ -total: 1183 \ No newline at end of file +total: 1184 diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/GalleryAdultsParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/GalleryAdultsParser.kt index da2ed22a..000478e5 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/GalleryAdultsParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/GalleryAdultsParser.kt @@ -152,6 +152,7 @@ internal abstract class GalleryAdultsParser( ) } + protected open val selectTitle = "h1.title" protected open val selectTag = "div.tags:contains(Tags:) .tag_list" protected open val selectAuthor = "ul.artists a.tag_btn" protected open val selectLanguageChapter = "div.tags:contains(Languages:) .tag_list a span.tag" @@ -166,7 +167,7 @@ internal abstract class GalleryAdultsParser( } return manga.copy( tags = tag.orEmpty(), - title = doc.selectFirst("h1.title")?.textOrNull()?.cleanupTitle() ?: manga.title, + title = doc.selectFirst(selectTitle)?.textOrNull()?.cleanupTitle() ?: manga.title, author = doc.selectFirst(selectAuthor)?.html()?.substringBefore(" = + EnumSet.of(SortOrder.UPDATED) + + override val filterCapabilities: MangaListFilterCapabilities + get() = super.filterCapabilities.copy( + isMultipleTagsSupported = false, + ) + + override suspend fun getFilterOptions() = super.getFilterOptions().copy( + availableLocales = setOf(Locale.ENGLISH, Locale.JAPANESE, Locale.CHINESE), + ) + + override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List { + val url = buildString { + append("https://") + append(domain) + when { + filter.tags.isEmpty() && filter.locale == null -> { + append("/search/?q=") + append(if (filter.query.isNullOrEmpty()) "" else filter.query.urlEncoded()) + append("&") + } + + else -> { + val tag = filter.tags.oneOrThrowIfMany() + val lang = filter.locale + if (tag != null && lang != null) { + throw IllegalArgumentException(ErrorMessages.FILTER_BOTH_LOCALE_GENRES_NOT_SUPPORTED) + } + if (tag != null) { + append("/tag/") + append(tag.key) + append("/?") + } else if (filter.locale != null) { + append("/language/") + append(filter.locale.toLanguagePath()) + append("/?") + } else { + append("/?") + } + } + } + append("page=") + append(page) + } + + return parseMangaList(webClient.httpGet(url).parseHtml()) + } + + override fun parseMangaList(doc: Document): List { + return doc.select(selectGallery).map { div -> + val href = div.selectFirstOrThrow(selectGalleryLink).attrAsRelativeUrl("href") + Manga( + id = generateUid(href), + title = div.select(selectGalleryTitle).text().cleanupTitle(), + altTitle = null, + url = href, + publicUrl = href.toAbsoluteUrl(domain), + rating = RATING_UNKNOWN, + contentRating = ContentRating.ADULT, + coverUrl = div.selectFirstOrThrow(selectGalleryImg).src().orEmpty(), + tags = emptySet(), + state = null, + author = null, + largeCoverUrl = null, + description = "N/A", + chapters = null, + source = source, + ) + } + } + + override suspend fun getPageUrl(page: MangaPage): String { + val doc = webClient.httpGet(page.url.toAbsoluteUrl(domain)).parseHtml() + val root = doc.body() + return root.requireElementById(idImg).selectFirstOrThrow("img").requireSrc() + } + + override fun Element.parseTags() = select("a").mapToSet { + val key = it.attr("href").removeSuffix('/').substringAfterLast('/') + val name = it.selectFirst(".name")?.text() ?: it.text() + MangaTag( + key = key, + title = name.toTitleCase(sourceLocale), + source = source, + ) + } +}