diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/AsuraScansParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/AsuraScansParser.kt index fbf1b7b8..4c7d012c 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/AsuraScansParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/en/AsuraScansParser.kt @@ -158,16 +158,16 @@ internal class AsuraScansParser(context: MangaLoaderContext) : return manga.copy( description = doc.selectFirst("span.font-medium.text-sm")?.text().orEmpty(), tags = tags, - author = doc.selectFirst("div.grid > div:has(h3:eq(0):containsOwn(Author)) > h3:eq(1)")?.text(), + author = doc.selectFirst("div.grid > div:has(h3:eq(0):containsOwn(Author)) > h3:eq(1)")?.text().orEmpty(), chapters = doc.select("div.scrollbar-thumb-themecolor > div.group").mapChapters(reversed = true) { i, div -> val a = div.selectLastOrThrow("a") val urlRelative = "/series/" + a.attrAsRelativeUrl("href") val url = urlRelative.toAbsoluteUrl(domain) - val date = div.selectFirst("h3:eq(1)")!!.ownText() + val date = div.selectLast("h3")?.text().orEmpty() val cleanDate = date.replace(regexDate, "$1") MangaChapter( id = generateUid(url), - name = div.selectFirstOrThrow("h3:eq(0)").text(), + name = div.selectFirst("h3")?.text() ?: "Chapter : ${i + 1f}", number = i + 1f, volume = 0, url = url, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/FuzzyDoodleParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/FuzzyDoodleParser.kt index 4ae56678..3df52aeb 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/FuzzyDoodleParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/FuzzyDoodleParser.kt @@ -31,6 +31,24 @@ internal abstract class FuzzyDoodleParser( override val availableSortOrders: Set = EnumSet.of(SortOrder.NEWEST) + override val filterCapabilities: MangaListFilterCapabilities + get() = MangaListFilterCapabilities( + isMultipleTagsSupported = true, + isSearchSupported = true, + isSearchWithFiltersSupported = true, + ) + + override suspend fun getFilterOptions() = MangaListFilterOptions( + availableTags = fetchAvailableTags(), + availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED), + availableContentTypes = EnumSet.of( + ContentType.MANGA, + ContentType.MANHWA, + ContentType.MANHUA, + ContentType.COMICS, + ), + ) + @JvmField protected val ongoing = scatterSetOf( "en cours", @@ -67,54 +85,53 @@ internal abstract class FuzzyDoodleParser( protected open val pausedValue = "haitus" protected open val abandonedValue = "dropped" - override val filterCapabilities: MangaListFilterCapabilities - get() = MangaListFilterCapabilities( - isMultipleTagsSupported = true, - isSearchSupported = true, - ) - - override suspend fun getFilterOptions() = MangaListFilterOptions( - availableTags = fetchAvailableTags(), - availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED), - ) + protected open val mangaValue = "manga" + protected open val manhwaValue = "manhwa" + protected open val manhuaValue = "manhua" + protected open val comicsValue = "bande-dessinee" override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List { val url = buildString { append("https://") append(domain) append("/manga?page=") - append(page) - - when { - - !filter.query.isNullOrEmpty() -> { - append("&title=") - append(filter.query.urlEncoded()) - } + append(page.toString()) + + append("&type=") + filter.types.oneOrThrowIfMany().let { + append( + when (it) { + ContentType.MANGA -> mangaValue + ContentType.MANHWA -> manhwaValue + ContentType.MANHUA -> manhuaValue + ContentType.COMICS -> comicsValue + else -> "" + }, + ) + } - else -> { - append("&type=") - - append("&status=") - filter.states.oneOrThrowIfMany()?.let { - append( - when (it) { - MangaState.ONGOING -> ongoingValue - MangaState.FINISHED -> finishedValue - MangaState.PAUSED -> pausedValue - MangaState.ABANDONED -> abandonedValue - else -> "" - }, - ) - } + filter.query?.let { + append("&title=") + append(filter.query.urlEncoded()) + } + append("&status=") + filter.states.oneOrThrowIfMany()?.let { + append( + when (it) { + MangaState.ONGOING -> ongoingValue + MangaState.FINISHED -> finishedValue + MangaState.PAUSED -> pausedValue + MangaState.ABANDONED -> abandonedValue + else -> "" + }, + ) + } - filter.tags.forEach { - append("&") - append("genre[]".urlEncoded()) - append("=") - append(it.key) - } - } + filter.tags.forEach { + append("&") + append("genre[]".urlEncoded()) + append("=") + append(it.key) } } @@ -270,17 +287,14 @@ internal abstract class FuzzyDoodleParser( private fun parseChapterDate(dateFormat: DateFormat, date: String?): Long { val d = date?.lowercase() ?: return 0 return when { - d.endsWith(" ago") || - d.endsWith("مضت") || d.startsWith("منذ") || - d.startsWith("il y a") -> parseRelativeDate(date) - date.contains(Regex("""\d(st|nd|rd|th)""")) -> date.split(" ").map { - if (it.contains(Regex("""\d\D\D"""))) { - it.replace(Regex("""\D"""), "") - } else { - it - } - }.let { dateFormat.tryParse(it.joinToString(" ")) } + WordSet(" ago", "مضت").endsWith(d) -> { + parseRelativeDate(d) + } + + WordSet("il y a", "منذ").startsWith(d) -> { + parseRelativeDate(d) + } else -> dateFormat.tryParse(date) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/ar/HentaiSlayer.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/ar/HentaiSlayer.kt index d3a3b3ed..7ceeaec8 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/ar/HentaiSlayer.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/ar/HentaiSlayer.kt @@ -16,7 +16,16 @@ internal class HentaiSlayer(context: MangaLoaderContext) : override val finishedValue = "مكتمل" override val abandonedValue = "متوقف" + override val mangaValue = "مانجا" + override val manhuaValue = "مانهوا" + override val comicsValue = "كوميكس" + override suspend fun getFilterOptions() = super.getFilterOptions().copy( availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.ABANDONED), + availableContentTypes = EnumSet.of( + ContentType.MANGA, + ContentType.MANHUA, + ContentType.COMICS, + ), ) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/en/ScyllaComics.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/en/ScyllaComics.kt index 142165a9..f29ed983 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/en/ScyllaComics.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/fuzzydoodle/en/ScyllaComics.kt @@ -2,9 +2,21 @@ package org.koitharu.kotatsu.parsers.site.fuzzydoodle.en import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser +import org.koitharu.kotatsu.parsers.model.ContentType +import org.koitharu.kotatsu.parsers.model.MangaListFilterOptions import org.koitharu.kotatsu.parsers.model.MangaParserSource import org.koitharu.kotatsu.parsers.site.fuzzydoodle.FuzzyDoodleParser +import java.util.EnumSet @MangaSourceParser("SCYLLACOMICS", "ScyllaComics", "en") internal class ScyllaComics(context: MangaLoaderContext) : - FuzzyDoodleParser(context, MangaParserSource.SCYLLACOMICS, "scyllacomics.xyz") + FuzzyDoodleParser(context, MangaParserSource.SCYLLACOMICS, "scyllacomics.xyz") { + + override suspend fun getFilterOptions() = MangaListFilterOptions( + availableContentTypes = EnumSet.of( + ContentType.MANGA, + ContentType.MANHWA, + ContentType.MANHUA, + ), + ) +} 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 24dfa5e2..2a96c1af 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 @@ -116,7 +116,7 @@ internal abstract class GalleryAdultsParser( publicUrl = href.toAbsoluteUrl(domain), rating = RATING_UNKNOWN, isNsfw = isNsfwSource, - coverUrl = div.selectFirstOrThrow(selectGalleryImg).src().orEmpty(), + coverUrl = div.selectFirst(selectGalleryImg)?.src().orEmpty(), tags = emptySet(), state = null, author = null, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/AsmHentai.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/AsmHentai.kt index 84983689..fcc67c65 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/AsmHentai.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/AsmHentai.kt @@ -19,6 +19,7 @@ internal class AsmHentai(context: MangaLoaderContext) : override val selectGalleryLink = ".image a" override val selectGalleryImg = ".image img" override val pathTagUrl = "/tags/?page=" + override val selectTags = ".tags_page ul.tags" override val selectAuthor = "div.tags:contains(Artists:) .tag_list a span.tag" override val idImg = "fimg" diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/DoujinDesuUk.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/DoujinDesuUk.kt index 778184c5..45daf881 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/DoujinDesuUk.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/galleryadults/all/DoujinDesuUk.kt @@ -1,6 +1,7 @@ package org.koitharu.kotatsu.parsers.site.galleryadults.all import org.jsoup.nodes.Document +import org.koitharu.kotatsu.parsers.Broken import org.koitharu.kotatsu.parsers.MangaLoaderContext import org.koitharu.kotatsu.parsers.MangaSourceParser import org.koitharu.kotatsu.parsers.model.* @@ -8,6 +9,7 @@ import org.koitharu.kotatsu.parsers.site.galleryadults.GalleryAdultsParser import org.koitharu.kotatsu.parsers.util.* import java.util.* +@Broken @MangaSourceParser("DOUJINDESUUK", "DoujinDesu.uk", type = ContentType.HENTAI) internal class DoujinDesuUk(context: MangaLoaderContext) : GalleryAdultsParser(context, MangaParserSource.DOUJINDESUUK, "doujindesu.uk", 25) { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/GattsuParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/GattsuParser.kt index b0a08a80..a8ac3c87 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/GattsuParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/gattsu/GattsuParser.kt @@ -77,7 +77,7 @@ internal abstract class GattsuParser( id = generateUid(href), url = href, publicUrl = href, - title = li.selectLastOrThrow(".thumb-titulo, .video-titulo").text(), + title = li.selectLast(".thumb-titulo, .video-titulo")?.text().orEmpty(), coverUrl = li.selectFirst("img")?.src().orEmpty(), altTitle = null, rating = RATING_UNKNOWN, diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/guya/GuyaParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/guya/GuyaParser.kt index 6a90e50b..7e1ad7c4 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/guya/GuyaParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/guya/GuyaParser.kt @@ -14,6 +14,13 @@ internal abstract class GuyaParser( domain: String, ) : SinglePageMangaParser(context, source) { + override val configKeyDomain = ConfigKey.Domain(domain) + + override fun onCreateConfig(keys: MutableCollection>) { + super.onCreateConfig(keys) + keys.add(userAgentKey) + } + override val availableSortOrders: Set = EnumSet.of(SortOrder.ALPHABETICAL) override val filterCapabilities: MangaListFilterCapabilities @@ -23,13 +30,6 @@ internal abstract class GuyaParser( override suspend fun getFilterOptions() = MangaListFilterOptions() - override fun onCreateConfig(keys: MutableCollection>) { - super.onCreateConfig(keys) - keys.add(userAgentKey) - } - - override val configKeyDomain = ConfigKey.Domain(domain) - override suspend fun getList(order: SortOrder, filter: MangaListFilter): List { val url = buildString { append("https://") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt index 02f94b61..33828e80 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancms/HeanCms.kt @@ -39,16 +39,11 @@ internal abstract class HeanCms( SortOrder.POPULARITY_ASC, ) - protected open val pathManga = "series" - protected open val apiPath - get() = getDomain("api") - - protected open val paramsUpdated = "latest" - override val filterCapabilities: MangaListFilterCapabilities get() = MangaListFilterCapabilities( isMultipleTagsSupported = true, isSearchSupported = true, + isSearchWithFiltersSupported = true, ) override suspend fun getFilterOptions() = MangaListFilterOptions( @@ -56,52 +51,59 @@ internal abstract class HeanCms( availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED), ) + protected open val pathManga = "series" + protected open val apiPath + get() = getDomain("api") + + protected open val paramsUpdated = "latest" + override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List { val url = buildString { append("https://") append(apiPath) - append("/query?query_string=&series_type=Comic&perPage=$pageSize") - when { - !filter.query.isNullOrEmpty() -> { - append(filter.query.urlEncoded()) - } - - else -> { - - filter.states.oneOrThrowIfMany()?.let { - append("&status=") - append( - when (it) { - MangaState.ONGOING -> "Ongoing" - MangaState.FINISHED -> "Completed" - MangaState.ABANDONED -> "Dropped" - MangaState.PAUSED -> "Hiatus" - else -> "" - }, - ) - } - - append("&orderBy=") - when (order) { - SortOrder.POPULARITY -> append("total_views&order=desc") - SortOrder.POPULARITY_ASC -> append("total_views&order=asc") - SortOrder.UPDATED -> append("$paramsUpdated&order=desc") - SortOrder.UPDATED_ASC -> append("$paramsUpdated&order=asc") - SortOrder.NEWEST -> append("created_at&order=desc") - SortOrder.NEWEST_ASC -> append("created_at&order=asc") - SortOrder.ALPHABETICAL -> append("title&order=asc") - SortOrder.ALPHABETICAL_DESC -> append("title&order=desc") - else -> append("latest&order=desc") - } - append("&tags_ids=") - append("[".urlEncoded()) - append(filter.tags.joinToString(",") { it.key }) - append("]".urlEncoded()) - } + append("/query?query_string=") + + filter.query?.let { + append(filter.query.urlEncoded()) + } + + append("&series_type=Comic&perPage=$pageSize") + + filter.states.oneOrThrowIfMany()?.let { + append("&status=") + append( + when (it) { + MangaState.ONGOING -> "Ongoing" + MangaState.FINISHED -> "Completed" + MangaState.ABANDONED -> "Dropped" + MangaState.PAUSED -> "Hiatus" + else -> "" + }, + ) } + + append("&orderBy=") + when (order) { + SortOrder.POPULARITY -> append("total_views&order=desc") + SortOrder.POPULARITY_ASC -> append("total_views&order=asc") + SortOrder.UPDATED -> append("$paramsUpdated&order=desc") + SortOrder.UPDATED_ASC -> append("$paramsUpdated&order=asc") + SortOrder.NEWEST -> append("created_at&order=desc") + SortOrder.NEWEST_ASC -> append("created_at&order=asc") + SortOrder.ALPHABETICAL -> append("title&order=asc") + SortOrder.ALPHABETICAL_DESC -> append("title&order=desc") + else -> append("latest&order=desc") + } + append("&tags_ids=") + append("[".urlEncoded()) + append(filter.tags.joinToString(",") { it.key }) + append("]".urlEncoded()) + append("&page=") append(page.toString()) } + + return parseMangaList(webClient.httpGet(url).parseJson()) } diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt index c0dffcfb..70d49687 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/heancmsalt/HeanCmsAlt.kt @@ -65,8 +65,8 @@ internal abstract class HeanCmsAlt( id = generateUid(href), url = href, publicUrl = href.toAbsoluteUrl(div.host ?: domain), - coverUrl = div.selectFirstOrThrow("img").src().orEmpty(), - title = div.selectFirstOrThrow(selectMangaTitle).text().orEmpty(), + coverUrl = div.selectFirst("img")?.src().orEmpty(), + title = div.selectFirst(selectMangaTitle)?.text().orEmpty(), altTitle = null, rating = RATING_UNKNOWN, tags = emptySet(), @@ -90,14 +90,14 @@ internal abstract class HeanCmsAlt( val dateFormat = SimpleDateFormat(datePattern, sourceLocale) return manga.copy( altTitle = doc.selectFirst(selectAlt)?.text().orEmpty(), - description = doc.selectFirstOrThrow(selectDesc).html(), + description = doc.selectFirst(selectDesc)?.html(), chapters = doc.select(selectChapter) .mapChapters(reversed = true) { i, a -> - val dateText = a.selectFirstOrThrow(selectChapterDate).text() + val dateText = a.selectFirst(selectChapterDate)?.text() val url = a.attrAsRelativeUrl("href").toAbsoluteUrl(domain) MangaChapter( id = generateUid(url), - name = a.selectFirstOrThrow(selectChapterTitle).text(), + name = a.selectFirst(selectChapterTitle)?.text() ?: "Chapter : ${i + 1f}", number = i + 1f, volume = 0, url = url, @@ -137,8 +137,6 @@ internal abstract class HeanCmsAlt( } } - // Parses dates in this form: - // 21 hours ago private fun parseRelativeDate(date: String): Long { val number = Regex("""(\d+)""").find(date)?.value?.toIntOrNull() ?: return 0 val cal = Calendar.getInstance() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/hotcomics/HotComicsParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/hotcomics/HotComicsParser.kt index 35b29f9a..3edebb76 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/hotcomics/HotComicsParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/hotcomics/HotComicsParser.kt @@ -24,6 +24,10 @@ internal abstract class HotComicsParser( override val configKeyDomain = ConfigKey.Domain(domain) + override fun getRequestHeaders(): Headers = Headers.Builder() + .add("User-Agent", UserAgents.CHROME_DESKTOP) + .build() + override fun onCreateConfig(keys: MutableCollection>) { super.onCreateConfig(keys) keys.add(userAgentKey) @@ -31,10 +35,6 @@ internal abstract class HotComicsParser( override val availableSortOrders: Set = EnumSet.of(SortOrder.NEWEST) - protected open val mangasUrl = "/genres" - - protected open val onePage = false - protected open val isSearchSupported: Boolean = true final override val filterCapabilities: MangaListFilterCapabilities @@ -46,9 +46,9 @@ internal abstract class HotComicsParser( availableTags = fetchAvailableTags(), ) - override fun getRequestHeaders(): Headers = Headers.Builder() - .add("User-Agent", UserAgents.CHROME_DESKTOP) - .build() + protected open val mangasUrl = "/genres" + + protected open val onePage = false override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List { if (onePage && page > 1) { @@ -161,7 +161,6 @@ internal abstract class HotComicsParser( ) } - protected open val selectPages = "#viewer-img img" override suspend fun getPages(chapter: MangaChapter): List { diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/DoujinDesuParser.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/DoujinDesuParser.kt index d711d39e..3d7ba5ea 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/DoujinDesuParser.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/DoujinDesuParser.kt @@ -29,11 +29,17 @@ internal class DoujinDesuParser(context: MangaLoaderContext) : get() = MangaListFilterCapabilities( isMultipleTagsSupported = true, isSearchSupported = true, + isSearchWithFiltersSupported = true, ) override suspend fun getFilterOptions() = MangaListFilterOptions( availableTags = fetchAvailableTags(), availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED), + availableContentTypes = EnumSet.of( + ContentType.MANGA, + ContentType.MANHWA, + ContentType.HENTAI, + ), ) override fun getRequestHeaders(): Headers = Headers.Builder() @@ -47,40 +53,58 @@ internal class DoujinDesuParser(context: MangaLoaderContext) : addPathSegment("page") addPathSegment("$page/") - when { - !filter.query.isNullOrEmpty() -> { - addQueryParameter("title", filter.query) - } - - else -> { - addQueryParameter("title", "") - addQueryParameter( - "order", - when (order) { - SortOrder.UPDATED -> "update" - SortOrder.POPULARITY -> "popular" - SortOrder.ALPHABETICAL -> "title" - SortOrder.NEWEST -> "latest" - else -> "latest" - }, - ) + addQueryParameter( + "title", + filter.query?.let { + filter.query + }, + ) + + addQueryParameter( + "order", + when (order) { + SortOrder.UPDATED -> "update" + SortOrder.POPULARITY -> "popular" + SortOrder.ALPHABETICAL -> "title" + SortOrder.NEWEST -> "latest" + else -> "latest" + }, + ) - filter.tags.forEach { - addEncodedQueryParameter("genre[]".urlEncoded(), it.key.urlEncoded()) - } - - filter.states.oneOrThrowIfMany()?.let { - addEncodedQueryParameter( - "statusx", - when (it) { - MangaState.ONGOING -> "Publishing" - MangaState.FINISHED -> "Finished" - else -> "" - }, - ) - } - } + filter.tags.forEach { + addEncodedQueryParameter("genre[]".urlEncoded(), it.key.urlEncoded()) + } + + filter.states.oneOrThrowIfMany()?.let { + addEncodedQueryParameter( + "statusx", + when (it) { + MangaState.ONGOING -> "Publishing" + MangaState.FINISHED -> "Finished" + else -> "" + }, + ) } + + filter.types.oneOrThrowIfMany()?.let { + addQueryParameter( + "typex", + when (it) { + ContentType.MANGA -> "Manga" + ContentType.MANHWA -> "Manhwa" + ContentType.HENTAI -> "Doujinshi" + else -> "" + }, + ) + } + + // Author + // addQueryParameter("author", + // filter.author?.let { + // filter.author + // } + // ) + }.build() return webClient.httpGet(url).parseHtml() diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/HentaiCrot.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/HentaiCrot.kt index 2eb3fcd9..00adfdde 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/HentaiCrot.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/HentaiCrot.kt @@ -12,10 +12,16 @@ import java.util.* internal class HentaiCrot(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.HENTAICROT, 8) { + override val configKeyDomain = ConfigKey.Domain("hentaicrot.com") + + override fun onCreateConfig(keys: MutableCollection>) { + super.onCreateConfig(keys) + keys.add(userAgentKey) + } + override val availableSortOrders: Set = EnumSet.of( SortOrder.UPDATED, ) - override val configKeyDomain = ConfigKey.Domain("hentaicrot.com") override val filterCapabilities: MangaListFilterCapabilities get() = MangaListFilterCapabilities( @@ -26,11 +32,6 @@ internal class HentaiCrot(context: MangaLoaderContext) : availableTags = fetchAvailableTags(), ) - override fun onCreateConfig(keys: MutableCollection>) { - super.onCreateConfig(keys) - keys.add(userAgentKey) - } - override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List { val url = buildString { append("https://") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/PixHentai.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/PixHentai.kt index d968d04b..fd2feb6e 100644 --- a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/PixHentai.kt +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/id/PixHentai.kt @@ -12,10 +12,16 @@ import java.util.* internal class PixHentai(context: MangaLoaderContext) : PagedMangaParser(context, MangaParserSource.PIXHENTAI, 8) { + override val configKeyDomain = ConfigKey.Domain("pixhentai.com") + + override fun onCreateConfig(keys: MutableCollection>) { + super.onCreateConfig(keys) + keys.add(userAgentKey) + } + override val availableSortOrders: Set = EnumSet.of( SortOrder.UPDATED, ) - override val configKeyDomain = ConfigKey.Domain("pixhentai.com") override val filterCapabilities: MangaListFilterCapabilities get() = MangaListFilterCapabilities( @@ -26,11 +32,6 @@ internal class PixHentai(context: MangaLoaderContext) : availableTags = fetchAvailableTags(), ) - override fun onCreateConfig(keys: MutableCollection>) { - super.onCreateConfig(keys) - keys.add(userAgentKey) - } - override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List { val url = buildString { append("https://") diff --git a/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/SoManga.kt b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/SoManga.kt new file mode 100644 index 00000000..5daf0af7 --- /dev/null +++ b/src/main/kotlin/org/koitharu/kotatsu/parsers/site/mangareader/id/SoManga.kt @@ -0,0 +1,12 @@ +package org.koitharu.kotatsu.parsers.site.mangareader.id + +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.mangareader.MangaReaderParser + +@MangaSourceParser("SOMANGA", "SoManga", "id") +internal class SoManga(context: MangaLoaderContext) : + MangaReaderParser(context, MangaParserSource.SOMANGA, "so-manga.com", pageSize = 5, searchPageSize = 25) { + override val datePattern = "MMM d, yyyy" +}