Fix filter capabilities/options default values

Koitharu 2 years ago
parent 3918bfafdf
commit 6d972a13fe
Signed by: Koitharu
GPG Key ID: 676DEE768C17A9D7

1
.gitignore vendored

@ -82,3 +82,4 @@ bin/
src/test/resources/cookies.txt
local.properties
.kotlin/

@ -68,7 +68,7 @@ public abstract class MangaParser @InternalParsersApi constructor(
* @param order one of [availableSortOrders] or [defaultSortOrder] for default value
* @param filter is a set of filter rules
*/
public abstract suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga>
public abstract suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilter): List<Manga>
/**
* Parse details for [Manga]: chapters list, description, large cover, etc.

@ -2,7 +2,7 @@ package org.koitharu.kotatsu.parsers
import androidx.annotation.VisibleForTesting
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaListFilterV2
import org.koitharu.kotatsu.parsers.model.MangaListFilter
import org.koitharu.kotatsu.parsers.model.MangaParserSource
import org.koitharu.kotatsu.parsers.model.SortOrder
import org.koitharu.kotatsu.parsers.util.Paginator
@ -21,7 +21,7 @@ public abstract class PagedMangaParser(
@JvmField
protected val searchPaginator: Paginator = Paginator(searchPageSize)
final override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
final override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
return getList(
paginator = if (filter.query.isNullOrEmpty()) {
paginator
@ -34,13 +34,13 @@ public abstract class PagedMangaParser(
)
}
public abstract suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga>
public abstract suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga>
private suspend fun getList(
paginator: Paginator,
offset: Int,
order: SortOrder,
filter: MangaListFilterV2,
filter: MangaListFilter,
): List<Manga> {
val page = paginator.getPage(offset)
val list = getListPage(page, order, filter)

@ -1,7 +1,7 @@
package org.koitharu.kotatsu.parsers
import org.koitharu.kotatsu.parsers.model.Manga
import org.koitharu.kotatsu.parsers.model.MangaListFilterV2
import org.koitharu.kotatsu.parsers.model.MangaListFilter
import org.koitharu.kotatsu.parsers.model.MangaParserSource
import org.koitharu.kotatsu.parsers.model.SortOrder
@ -11,12 +11,12 @@ public abstract class SinglePageMangaParser(
source: MangaParserSource,
) : MangaParser(context, source) {
final override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
final override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
if (offset > 0) {
return emptyList()
}
return getList(order, filter)
}
public abstract suspend fun getList(order: SortOrder, filter: MangaListFilterV2): List<Manga>
public abstract suspend fun getList(order: SortOrder, filter: MangaListFilter): List<Manga>
}

@ -2,7 +2,7 @@ package org.koitharu.kotatsu.parsers.model
import java.util.*
public data class MangaListFilterV2(
public data class MangaListFilter(
@JvmField val query: String? = null,
@JvmField val tags: Set<MangaTag> = emptySet(),
@JvmField val tagsExclude: Set<MangaTag> = emptySet(),
@ -33,6 +33,6 @@ public data class MangaListFilterV2(
public companion object {
@JvmStatic
public val EMPTY: MangaListFilterV2 = MangaListFilterV2()
public val EMPTY: MangaListFilter = MangaListFilter()
}
}

@ -6,44 +6,44 @@ public data class MangaListFilterCapabilities @InternalParsersApi constructor(
/**
* Whether parser supports filtering by more than one tag
* @see [MangaListFilterV2.tags]
* @see [MangaListFilter.tags]
* @see [MangaListFilterOptions.availableTags]
*/
val isMultipleTagsSupported: Boolean,
val isMultipleTagsSupported: Boolean = false,
/**
* Whether parser supports tagsExclude field in filter
* @see [MangaListFilterV2.tagsExclude]
* @see [MangaListFilter.tagsExclude]
* @see [MangaListFilterOptions.availableTags]
*/
val isTagsExclusionSupported: Boolean,
val isTagsExclusionSupported: Boolean = false,
/**
* Whether parser supports searching by string query
* @see [MangaListFilterV2.query]
* @see [MangaListFilter.query]
*/
val isSearchSupported: Boolean,
val isSearchSupported: Boolean = false,
/**
* Whether parser supports searching by string query combined within other filters
*/
val isSearchWithFiltersSupported: Boolean,
val isSearchWithFiltersSupported: Boolean = false,
/**
* Whether parser supports searching/filtering by year
* @see [MangaListFilterV2.year]
* @see [MangaListFilter.year]
*/
val isYearSupported: Boolean = false,
/**
* Whether parser supports searching by year range
* @see [MangaListFilterV2.yearFrom] and [MangaListFilterV2.yearTo]
* @see [MangaListFilter.yearFrom] and [MangaListFilter.yearTo]
*/
val isYearRangeSupported: Boolean = false,
/**
* Whether parser supports searching Original Languages
* @see [MangaListFilterV2.originalLocale]
* @see [MangaListFilter.originalLocale]
* @see [MangaListFilterOptions.availableLocales]
*/
val isOriginalLocaleSupported: Boolean = false,

@ -8,7 +8,7 @@ public data class MangaListFilterOptions @InternalParsersApi constructor(
/**
* Available tags (genres)
*/
public val availableTags: Set<MangaTag>,
public val availableTags: Set<MangaTag> = emptySet(),
/**
* Supported [MangaState] variants for filtering. May be empty.

@ -65,10 +65,6 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser(
isMultipleTagsSupported = true,
isTagsExclusionSupported = true,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -122,7 +118,7 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser(
"zbato.org",
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
when {
!filter.query.isNullOrEmpty() -> {
return search(page, filter.query)

@ -41,10 +41,7 @@ internal class ComickFunParser(context: MangaLoaderContext) :
isMultipleTagsSupported = true,
isTagsExclusionSupported = true,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = true,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -61,7 +58,7 @@ internal class ComickFunParser(context: MangaLoaderContext) :
availableLocales = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val domain = domain
val url = urlBuilder()
.host("api.$domain")

@ -55,10 +55,6 @@ internal class ExHentaiParser(
isMultipleTagsSupported = true,
isTagsExclusionSupported = true,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override val isAuthorized: Boolean
@ -87,10 +83,6 @@ internal class ExHentaiParser(
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = tagsMap.get().values.toSet(),
availableStates = emptySet(),
availableContentRating = emptySet(),
availableContentTypes = emptySet(),
availableDemographics = emptySet(),
availableLocales = setOf(
Locale.JAPANESE,
Locale.ENGLISH,
@ -110,7 +102,7 @@ internal class ExHentaiParser(
),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val next = nextPages.get(page, 0L)
if (page > 0 && next == 0L) {
@ -431,7 +423,7 @@ internal class ExHentaiParser(
?.toLongOrNull() ?: 1
}
private fun MangaListFilterV2.toSearchQuery(): String? {
private fun MangaListFilter.toSearchQuery(): String? {
val joiner = StringUtil.StringJoiner(" ")
for (tag in tags) {
if (tag.key.isNumeric()) {

@ -73,15 +73,11 @@ internal class HitomiLaParser(context: MangaLoaderContext) : MangaParser(context
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
availableLocales = localeMap.keys,
)
@ -122,7 +118,7 @@ internal class HitomiLaParser(context: MangaLoaderContext) : MangaParser(context
private var cachedSearchIds: List<Int> = emptyList()
override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> = when {
override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilter): List<Manga> = when {
filter.query.isNullOrEmpty() -> {
if (filter.tags.isEmpty()) {
when (order) {

@ -25,9 +25,7 @@ internal class ImHentai(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -45,7 +43,7 @@ internal class ImHentai(context: MangaLoaderContext) :
override suspend fun getListPage(
page: Int,
order: SortOrder,
filter: MangaListFilterV2,
filter: MangaListFilter,
): List<Manga> {
val url = buildString {
append("https://")

@ -25,16 +25,11 @@ internal abstract class LineWebtoonsParser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
private val signer by lazy {
@ -147,7 +142,7 @@ internal abstract class LineWebtoonsParser(
}
}
override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val manga = when {
!filter.query.isNullOrEmpty() -> {
makeRequest("/lineWebtoon/webtoon/searchChallenge?query=${filter.query.urlEncoded()}&startIndex=${offset + 1}&pageSize=20")

@ -64,7 +64,7 @@ internal class MangaDexParser(context: MangaLoaderContext) : MangaParser(context
)
}
override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val domain = domain
val url = buildString {
append("https://api.")

@ -76,10 +76,6 @@ internal abstract class MangaFireParser(
isMultipleTagsSupported = true,
isTagsExclusionSupported = true,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -91,7 +87,7 @@ internal abstract class MangaFireParser(
availableLocales = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = "https://$domain/filter".toHttpUrl().newBuilder().apply {
addQueryParameter("page", page.toString())
addQueryParameter("language[]", siteLang)

@ -26,10 +26,6 @@ internal class MangaPark(context: MangaLoaderContext) :
isMultipleTagsSupported = true,
isTagsExclusionSupported = true,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -73,7 +69,7 @@ internal class MangaPark(context: MangaLoaderContext) :
context.cookieJar.insertCookies(domain, "nsfw", "2")
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -42,21 +42,14 @@ internal abstract class MangaPlusParser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = emptySet(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override suspend fun getFilterOptions() = MangaListFilterOptions()
private val extraHeaders = Headers.headersOf("Session-Token", UUID.randomUUID().toString())
override suspend fun getList(order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getList(order: SortOrder, filter: MangaListFilter): List<Manga> {
return when {
filter.query.isNullOrEmpty() -> {
when (order) {

@ -71,12 +71,7 @@ internal class MangaReaderToParser(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -88,7 +83,7 @@ internal class MangaReaderToParser(context: MangaLoaderContext) :
availableLocales = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = "https://$domain".toHttpUrl().newBuilder().apply {
when {
!filter.query.isNullOrEmpty() -> {

@ -45,10 +45,6 @@ internal abstract class NineMangaParser(
isMultipleTagsSupported = true,
isTagsExclusionSupported = true,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -73,7 +69,7 @@ internal abstract class NineMangaParser(
return chain.proceed(newRequest)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -36,21 +36,11 @@ internal class NineNineNineHentaiParser(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
availableContentTypes = emptySet(),
availableDemographics = emptySet(),
availableLocales = setOf(
Locale.ENGLISH,
Locale.CHINESE,
@ -118,7 +108,7 @@ internal class NineNineNineHentaiParser(context: MangaLoaderContext) :
}
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
return if (filter.query.isNullOrEmpty()) {
if (filter.tags.isEmpty() && order == SortOrder.POPULARITY) {
getPopularList(page, filter.locale)

@ -49,10 +49,7 @@ internal abstract class WebtoonsParser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override val userAgentKey = ConfigKey.UserAgent("nApps (Android 12;; linewebtoon; 3.1.0)")
@ -192,7 +189,7 @@ internal abstract class WebtoonsParser(
}
override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val webtoons = when {
!filter.query.isNullOrEmpty() -> {
makeRequest("/lineWebtoon/webtoon/searchWebtoon?query=${filter.query.urlEncoded()}").getJSONObject("webtoonSearch")

@ -42,25 +42,14 @@ internal abstract class AnimeBootstrapParser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
availableContentTypes = emptySet(),
availableDemographics = emptySet(),
availableLocales = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -28,7 +28,7 @@ internal class PapScan(context: MangaLoaderContext) :
SortOrder.ALPHABETICAL_DESC,
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -24,12 +24,7 @@ internal class FlixScans(context: MangaLoaderContext) : PagedMangaParser(context
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -46,7 +41,7 @@ internal class FlixScans(context: MangaLoaderContext) : PagedMangaParser(context
keys.add(userAgentKey)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val json = when {
!filter.query.isNullOrEmpty() -> {
if (page > 1) {

@ -19,17 +19,10 @@ internal class MangaStorm(context: MangaLoaderContext) : PagedMangaParser(contex
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = emptySet(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override suspend fun getFilterOptions() = MangaListFilterOptions()
override val userAgentKey = ConfigKey.UserAgent(UserAgents.CHROME_DESKTOP)
@ -38,7 +31,7 @@ internal class MangaStorm(context: MangaLoaderContext) : PagedMangaParser(contex
keys.add(userAgentKey)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -27,13 +27,7 @@ internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(contex
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -45,7 +39,7 @@ internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(contex
availableLocales = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -28,15 +28,11 @@ internal class AnibelParser(context: MangaLoaderContext) : MangaParser(context,
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
@ -48,7 +44,7 @@ internal class AnibelParser(context: MangaLoaderContext) : MangaParser(context,
SortOrder.NEWEST,
)
override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val filters = when {
!filter.query.isNullOrEmpty() -> {
return if (offset == 0) {

@ -29,13 +29,7 @@ internal abstract class CupFoxParser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -47,7 +41,7 @@ internal abstract class CupFoxParser(
availableLocales = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -30,12 +30,7 @@ internal class AsuraScansParser(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -52,7 +47,7 @@ internal class AsuraScansParser(context: MangaLoaderContext) :
keys.add(userAgentKey)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -24,25 +24,14 @@ internal class BeeToon(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
availableContentTypes = emptySet(),
availableDemographics = emptySet(),
availableLocales = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -20,24 +20,17 @@ internal class CloneMangaParser(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = emptySet(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override suspend fun getFilterOptions() = MangaListFilterOptions()
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
super.onCreateConfig(keys)
keys.add(userAgentKey)
}
override suspend fun getList(order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getList(order: SortOrder, filter: MangaListFilter): List<Manga> {
if (!filter.query.isNullOrEmpty()) {
return emptyList()
}

@ -23,10 +23,7 @@ internal class ComicExtra(context: MangaLoaderContext) : PagedMangaParser(contex
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -40,7 +37,7 @@ internal class ComicExtra(context: MangaLoaderContext) : PagedMangaParser(contex
keys.add(userAgentKey)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -27,16 +27,11 @@ internal class DynastyScans(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
@ -44,7 +39,7 @@ internal class DynastyScans(context: MangaLoaderContext) :
keys.add(userAgentKey)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
when {
!filter.query.isNullOrEmpty() -> {
val url = buildString {

@ -25,9 +25,6 @@ internal class FlixScansOrg(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = false,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -41,7 +38,7 @@ internal class FlixScansOrg(context: MangaLoaderContext) :
keys.add(userAgentKey)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val json = when {
!filter.query.isNullOrEmpty() -> {
throw IllegalArgumentException(ErrorMessages.SEARCH_NOT_SUPPORTED)

@ -21,16 +21,11 @@ internal class MangaGeko(context: MangaLoaderContext) : PagedMangaParser(context
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
@ -38,7 +33,7 @@ internal class MangaGeko(context: MangaLoaderContext) : PagedMangaParser(context
keys.add(userAgentKey)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -22,16 +22,11 @@ internal class MangaKawaiiEn(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
@ -43,7 +38,7 @@ internal class MangaKawaiiEn(context: MangaLoaderContext) :
.add("Accept-Language", "en")
.build()
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -30,10 +30,7 @@ internal class MangaTownParser(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -45,7 +42,7 @@ internal class MangaTownParser(context: MangaLoaderContext) :
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -33,12 +33,7 @@ internal class Mangaowl(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -58,7 +53,7 @@ internal class Mangaowl(context: MangaLoaderContext) :
override suspend fun getListPage(
page: Int,
order: SortOrder,
filter: MangaListFilterV2,
filter: MangaListFilter,
): List<Manga> {
val url = buildString {
append("https://")

@ -36,7 +36,6 @@ internal class Manhwa18Parser(context: MangaLoaderContext) :
isMultipleTagsSupported = true,
isTagsExclusionSupported = true,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -58,7 +57,7 @@ internal class Manhwa18Parser(context: MangaLoaderContext) :
)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -26,10 +26,7 @@ internal class ManhwasMen(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -41,7 +38,7 @@ internal class ManhwasMen(context: MangaLoaderContext) :
override suspend fun getListPage(
page: Int,
order: SortOrder,
filter: MangaListFilterV2,
filter: MangaListFilter,
): List<Manga> {
val url = buildString {
append("https://")

@ -17,24 +17,17 @@ internal class Po2Scans(context: MangaLoaderContext) : SinglePageMangaParser(con
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = emptySet(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override suspend fun getFilterOptions() = MangaListFilterOptions()
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
super.onCreateConfig(keys)
keys.add(userAgentKey)
}
override suspend fun getList(order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getList(order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -24,16 +24,11 @@ internal class Pururin(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
@ -41,7 +36,7 @@ internal class Pururin(context: MangaLoaderContext) :
keys.add(userAgentKey)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -34,10 +34,7 @@ internal class VyManga(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -46,7 +43,7 @@ internal class VyManga(context: MangaLoaderContext) :
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -27,26 +27,11 @@ internal class TempleScanEsp(context: MangaLoaderContext) :
}
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = false,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
get() = MangaListFilterCapabilities()
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = emptySet(),
availableStates = emptySet(),
availableContentRating = emptySet(),
availableContentTypes = emptySet(),
availableDemographics = emptySet(),
availableLocales = emptySet(),
)
override suspend fun getFilterOptions() = MangaListFilterOptions()
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -41,18 +41,15 @@ internal class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaPars
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = EnumSet.of(ContentRating.SAFE, ContentRating.ADULT),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -44,10 +44,6 @@ internal abstract class FmreaderParser(
isMultipleTagsSupported = true,
isTagsExclusionSupported = true,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
init {
@ -88,7 +84,7 @@ internal abstract class FmreaderParser(
availableLocales = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -22,7 +22,7 @@ internal class Manhwa18Com(context: MangaLoaderContext) :
override val selectPage = "div#chapter-content img"
override val selectBodyTag = "div.advanced-wrapper .genre_label"
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -21,7 +21,7 @@ internal class OlimpoScans(context: MangaLoaderContext) :
isTagsExclusionSupported = false,
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -34,13 +34,7 @@ internal abstract class FoolSlideParser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
init {
@ -48,16 +42,9 @@ internal abstract class FoolSlideParser(
searchPaginator.firstPage = 1
}
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = emptySet(),
availableStates = emptySet(),
availableContentRating = emptySet(),
availableContentTypes = emptySet(),
availableDemographics = emptySet(),
availableLocales = emptySet(),
)
override suspend fun getFilterOptions() = MangaListFilterOptions()
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val doc = when {
!filter.query.isNullOrEmpty() -> {
if (page > 1) {

@ -47,7 +47,6 @@ internal class BentomangaParser(context: MangaLoaderContext) :
isMultipleTagsSupported = true,
isTagsExclusionSupported = true,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -56,7 +55,7 @@ internal class BentomangaParser(context: MangaLoaderContext) :
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = urlBuilder()
.host(domain)
.addPathSegment("manga_list")

@ -25,18 +25,9 @@ internal class FuryoSociety(context: MangaLoaderContext) :
override val userAgentKey = ConfigKey.UserAgent(UserAgents.CHROME_DESKTOP)
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = false,
isSearchWithFiltersSupported = false,
)
get() = MangaListFilterCapabilities()
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = emptySet(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override suspend fun getFilterOptions() = MangaListFilterOptions()
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
super.onCreateConfig(keys)
@ -52,7 +43,7 @@ internal class FuryoSociety(context: MangaLoaderContext) :
)
}
override suspend fun getList(order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getList(order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -22,9 +22,7 @@ internal class LegacyScansParser(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -38,7 +36,7 @@ internal class LegacyScansParser(context: MangaLoaderContext) :
keys.add(userAgentKey)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val end = page * pageSize
val start = end - (pageSize - 1)

@ -20,16 +20,11 @@ internal class LireScan(context: MangaLoaderContext) : PagedMangaParser(context,
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
@ -37,7 +32,7 @@ internal class LireScan(context: MangaLoaderContext) : PagedMangaParser(context,
keys.add(userAgentKey)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val doc = when {
!filter.query.isNullOrEmpty() -> {
if (page > 1) {

@ -30,12 +30,6 @@ internal class LugnicaScans(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = false,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -68,7 +62,7 @@ internal class LugnicaScans(context: MangaLoaderContext) :
)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
when {
!filter.query.isNullOrEmpty() -> {
throw IllegalArgumentException(ErrorMessages.SEARCH_NOT_SUPPORTED)

@ -21,16 +21,11 @@ internal class MangaKawaii(context: MangaLoaderContext) : PagedMangaParser(conte
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
@ -42,7 +37,7 @@ internal class MangaKawaii(context: MangaLoaderContext) : PagedMangaParser(conte
.add("Accept-Language", "fr")
.build()
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -36,10 +36,7 @@ internal class MangaMana(context: MangaLoaderContext) : PagedMangaParser(context
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -53,7 +50,7 @@ internal class MangaMana(context: MangaLoaderContext) : PagedMangaParser(context
keys.add(userAgentKey)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val postData = buildString {
append("page=")
append(page)

@ -29,22 +29,11 @@ internal class ScansMangasMe(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
availableContentTypes = emptySet(),
availableDemographics = emptySet(),
availableLocales = emptySet(),
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
@ -52,7 +41,7 @@ internal class ScansMangasMe(context: MangaLoaderContext) :
keys.add(userAgentKey)
}
override suspend fun getList(order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getList(order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -26,22 +26,11 @@ internal class ScantradUnion(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
availableContentTypes = emptySet(),
availableDemographics = emptySet(),
availableLocales = emptySet(),
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
@ -49,7 +38,7 @@ internal class ScantradUnion(context: MangaLoaderContext) :
keys.add(userAgentKey)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -67,21 +67,19 @@ internal abstract class FuzzyDoodleParser(
protected open val pausedValue = "haitus"
protected open val abandonedValue = "dropped"
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED),
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
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),
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)
@ -258,7 +256,7 @@ internal abstract class FuzzyDoodleParser(
protected open val selectTagsList = "div.mt-1 div.items-center:has(label)"
private suspend fun fetchAvailableTags(): Set<MangaTag> {
private suspend fun fetchAvailableTags(): Set<MangaTag> {
val doc = webClient.httpGet("https://$domain/manga").parseHtml()
return doc.select(selectTagsList).mapNotNullToSet {
val key = it.selectFirst("input")?.attr("value") ?: return@mapNotNullToSet null

@ -32,21 +32,11 @@ internal abstract class GalleryAdultsParser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
availableContentTypes = emptySet(),
availableDemographics = emptySet(),
availableLocales = setOf(
Locale.ENGLISH,
Locale.FRENCH,
@ -68,7 +58,7 @@ internal abstract class GalleryAdultsParser(
override suspend fun getListPage(
page: Int,
order: SortOrder,
filter: MangaListFilterV2,
filter: MangaListFilter,
): List<Manga> {
val url = buildString {
append("https://")

@ -42,7 +42,7 @@ internal class Hentai3(context: MangaLoaderContext) :
),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -38,7 +38,7 @@ internal class HentaiEnvy(context: MangaLoaderContext) :
),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -45,7 +45,7 @@ internal class HentaiEra(context: MangaLoaderContext) :
)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -53,7 +53,7 @@ internal class HentaiForce(context: MangaLoaderContext) :
return doc.selectFirstOrThrow(idImg).src() ?: doc.parseFailed("Image src not found")
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -25,7 +25,7 @@ internal class HentaiFox(context: MangaLoaderContext) :
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -42,7 +42,7 @@ internal class NHentaiParser(context: MangaLoaderContext) :
.set("User-Agent", config[userAgentKey])
.build()
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -27,21 +27,16 @@ internal abstract class GattsuParser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
protected open val tagPrefix = "tag"
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -16,15 +16,11 @@ internal class UniversoHentai(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
private suspend fun fetchAvailableTags(): Set<MangaTag> {

@ -18,23 +18,10 @@ internal abstract class GuyaParser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = emptySet(),
availableStates = emptySet(),
availableContentRating = emptySet(),
availableContentTypes = emptySet(),
availableDemographics = emptySet(),
availableLocales = emptySet(),
)
override suspend fun getFilterOptions() = MangaListFilterOptions()
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
super.onCreateConfig(keys)
@ -43,7 +30,7 @@ internal abstract class GuyaParser(
override val configKeyDomain = ConfigKey.Domain(domain)
override suspend fun getList(order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getList(order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -48,12 +48,7 @@ internal abstract class HeanCms(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -65,7 +60,7 @@ internal abstract class HeanCms(
availableLocales = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(apiPath)

@ -32,12 +32,7 @@ internal abstract class HeanCmsAlt(
protected open val datePattern = "MMMM d, yyyy"
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = false,
isSearchWithFiltersSupported = false,
)
get() = MangaListFilterCapabilities()
init {
paginator.firstPage = 1
@ -47,13 +42,9 @@ internal abstract class HeanCmsAlt(
protected open val selectManga = "div.grid.grid-cols-2 div:not([class]):contains(M)"
protected open val selectMangaTitle = "h5"
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = emptySet(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override suspend fun getFilterOptions() = MangaListFilterOptions()
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -37,31 +37,20 @@ internal abstract class HotComicsParser(
protected open val isSearchSupported: Boolean = true
override val filterCapabilities: MangaListFilterCapabilities
final override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = isSearchSupported,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
availableContentTypes = emptySet(),
availableDemographics = emptySet(),
availableLocales = emptySet(),
)
override fun getRequestHeaders(): Headers = Headers.Builder()
.add("User-Agent", UserAgents.CHROME_DESKTOP)
.build()
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
if (onePage && page > 1) {
return emptyList()
}

@ -28,15 +28,12 @@ internal class DoujinDesuParser(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED),
availableContentRating = emptySet(),
)
override fun getRequestHeaders(): Headers = Headers.Builder()
@ -44,7 +41,7 @@ internal class DoujinDesuParser(context: MangaLoaderContext) :
.add("Referer", "https://$domain/")
.build()
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = urlBuilder().apply {
addPathSegment("manga")
addPathSegment("page")

@ -19,16 +19,11 @@ internal class HentaiCrot(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
@ -36,7 +31,7 @@ internal class HentaiCrot(context: MangaLoaderContext) :
keys.add(userAgentKey)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -19,16 +19,11 @@ internal class PixHentai(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
@ -36,7 +31,7 @@ internal class PixHentai(context: MangaLoaderContext) :
keys.add(userAgentKey)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -31,12 +31,7 @@ internal abstract class IkenParser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
@ -47,13 +42,9 @@ internal abstract class IkenParser(
MangaState.ABANDONED,
MangaState.UPCOMING,
),
availableContentRating = emptySet(),
availableContentTypes = emptySet(),
availableDemographics = emptySet(),
availableLocales = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -23,16 +23,11 @@ internal class NicovideoSeigaParser(context: MangaLoaderContext) :
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
@ -60,7 +55,7 @@ internal class NicovideoSeigaParser(context: MangaLoaderContext) :
override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("nicovideo.jp")
override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val page = (offset / 20f).toIntUp().inc()
val domain = getDomain("seiga")
val url = when {

@ -57,19 +57,14 @@ internal abstract class KeyoappParser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override suspend fun getList(order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getList(order: SortOrder, filter: MangaListFilter): List<Manga> {
var query = ""
var tag = ""

@ -34,19 +34,15 @@ internal abstract class LikeMangaParser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED),
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -32,19 +32,12 @@ internal abstract class MadaraParser(
isMultipleTagsSupported = true,
isTagsExclusionSupported = true,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = EnumSet.allOf(MangaState::class.java),
availableContentRating = EnumSet.of(ContentRating.SAFE, ContentRating.ADULT),
availableContentTypes = emptySet(),
availableDemographics = emptySet(),
availableLocales = emptySet(),
)
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
@ -208,7 +201,7 @@ internal abstract class MadaraParser(
// can be changed to retrieve tags see getTags
protected open val listUrl = "manga/"
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
if (withoutAjax) {
val pages = page + 1

@ -30,7 +30,7 @@ internal class Manga18Fx(context: MangaLoaderContext) :
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -37,7 +37,7 @@ internal class Manhwa18Cc(context: MangaLoaderContext) :
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -1,10 +1,6 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import kotlinx.coroutines.*
import okhttp3.Headers
import okhttp3.Request
import okhttp3.RequestBody
@ -16,170 +12,170 @@ import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
import org.koitharu.kotatsu.parsers.util.*
import java.text.SimpleDateFormat
import java.util.EnumSet
import java.util.*
@MangaSourceParser("ADULT_WEBTOON", "AdultWebtoon", "en", ContentType.HENTAI)
internal class AdultWebtoon(context: MangaLoaderContext) :
MadaraParser(context, MangaParserSource.ADULT_WEBTOON, "adultwebtoon.com") {
override val tagPrefix = "adult-webtoon-genre/"
override val listUrl = "adult-webtoon/"
override val postReq = true
override val withoutAjax = true
override val availableSortOrders: Set<SortOrder> =
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
override val filterCapabilities: MangaListFilterCapabilities
get() = super.filterCapabilities.copy(
isTagsExclusionSupported = false,
)
override suspend fun getFilterOptions() = super.getFilterOptions().copy(
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
val pages = page + 1
val url = buildString {
append("https://")
append(domain)
when {
!filter.query.isNullOrEmpty() -> {
if (pages > 1) {
append("/page/")
append(pages.toString())
}
append("/?s=")
append(filter.query.urlEncoded())
append("&post_type=wp-manga")
}
else -> {
if (filter.tags.isNotEmpty()) {
filter.tags.oneOrThrowIfMany()?.let {
append('/')
append(tagPrefix)
append(it.key)
append('/')
}
} else {
append('/')
append(listUrl)
}
if (pages > 1) {
append("page/")
append(pages)
append('/')
}
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")
else -> append("latest")
}
}
}
}
return parseMangaList(webClient.httpGet(url).parseHtml())
}
override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
val fullUrl = manga.url.toAbsoluteUrl(domain)
val doc = webClient.httpGet(fullUrl).parseHtml()
val body = doc.body()
val chaptersDeferred = async { loadChapters(manga.url, doc) }
val desc = body.select(selectDesc).html()
val stateDiv = if (selectState.isEmpty()) {
body.selectFirst("div.post-content_item:contains(Status)")?.selectLast("div.summary-content")
} else {
body.selectFirst(selectState)
}
val state = stateDiv?.let {
when (it.text()) {
in ongoing -> MangaState.ONGOING
in finished -> MangaState.FINISHED
in abandoned -> MangaState.ABANDONED
in paused -> MangaState.PAUSED
else -> null
}
}
val alt =
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()?.text()
?.trim()
manga.copy(
tags = doc.body().select(selectGenre).mapNotNullToSet { a ->
MangaTag(
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
title = a.text().toTitleCase(),
source = source,
)
},
description = desc,
altTitle = alt,
state = state,
chapters = chaptersDeferred.await(),
)
}
override suspend fun loadChapters(mangaUrl: String, document: Document): List<MangaChapter> {
val mangaId = document.select("div#manga-chapters-holder").attr("data-id")
val url = "https://$domain/wp-admin/admin-ajax.php"
val postData = "post_id=$mangaId&action=ajax_chap"
val headers = Headers.Builder().add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8").build()
val doc = makeRequest(url, postData.toRequestBody(), headers)
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirst("a")
val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing")
val link = href + stylePage
val dateText = li.selectFirst("a.c-new-tag")?.attr("title") ?: li.selectFirst(selectDate)?.text()
val name = a.selectFirst("p")?.text() ?: a.ownText()
MangaChapter(
id = generateUid(href),
url = link,
name = name,
number = i + 1f,
volume = 0,
branch = null,
uploadDate = parseChapterDate(
dateFormat,
dateText,
),
scanlator = null,
source = source,
)
}
}
private suspend fun makeRequest(url: String, payload: RequestBody, headers: Headers): Document {
var retryCount = 0
val backoffDelay = 2000L // Initial delay (milliseconds)
val request = Request.Builder().url(url).post(payload).headers(headers).build()
while (true) {
try {
return context.httpClient.newCall(request).execute().parseHtml()
} catch (e: Exception) {
// Log or handle the exception as needed
if (++retryCount <= 5) {
withContext(Dispatchers.Default) {
delay(backoffDelay)
}
} else {
throw e
}
}
}
}
MadaraParser(context, MangaParserSource.ADULT_WEBTOON, "adultwebtoon.com") {
override val tagPrefix = "adult-webtoon-genre/"
override val listUrl = "adult-webtoon/"
override val postReq = true
override val withoutAjax = true
override val availableSortOrders: Set<SortOrder> =
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
override val filterCapabilities: MangaListFilterCapabilities
get() = super.filterCapabilities.copy(
isTagsExclusionSupported = false,
)
override suspend fun getFilterOptions() = super.getFilterOptions().copy(
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val pages = page + 1
val url = buildString {
append("https://")
append(domain)
when {
!filter.query.isNullOrEmpty() -> {
if (pages > 1) {
append("/page/")
append(pages.toString())
}
append("/?s=")
append(filter.query.urlEncoded())
append("&post_type=wp-manga")
}
else -> {
if (filter.tags.isNotEmpty()) {
filter.tags.oneOrThrowIfMany()?.let {
append('/')
append(tagPrefix)
append(it.key)
append('/')
}
} else {
append('/')
append(listUrl)
}
if (pages > 1) {
append("page/")
append(pages)
append('/')
}
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")
else -> append("latest")
}
}
}
}
return parseMangaList(webClient.httpGet(url).parseHtml())
}
override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
val fullUrl = manga.url.toAbsoluteUrl(domain)
val doc = webClient.httpGet(fullUrl).parseHtml()
val body = doc.body()
val chaptersDeferred = async { loadChapters(manga.url, doc) }
val desc = body.select(selectDesc).html()
val stateDiv = if (selectState.isEmpty()) {
body.selectFirst("div.post-content_item:contains(Status)")?.selectLast("div.summary-content")
} else {
body.selectFirst(selectState)
}
val state = stateDiv?.let {
when (it.text()) {
in ongoing -> MangaState.ONGOING
in finished -> MangaState.FINISHED
in abandoned -> MangaState.ABANDONED
in paused -> MangaState.PAUSED
else -> null
}
}
val alt =
doc.body().select(".post-content_item:contains(Alt) .summary-content").firstOrNull()?.tableValue()?.text()
?.trim()
manga.copy(
tags = doc.body().select(selectGenre).mapNotNullToSet { a ->
MangaTag(
key = a.attr("href").removeSuffix("/").substringAfterLast('/'),
title = a.text().toTitleCase(),
source = source,
)
},
description = desc,
altTitle = alt,
state = state,
chapters = chaptersDeferred.await(),
)
}
override suspend fun loadChapters(mangaUrl: String, document: Document): List<MangaChapter> {
val mangaId = document.select("div#manga-chapters-holder").attr("data-id")
val url = "https://$domain/wp-admin/admin-ajax.php"
val postData = "post_id=$mangaId&action=ajax_chap"
val headers = Headers.Builder().add("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8").build()
val doc = makeRequest(url, postData.toRequestBody(), headers)
val dateFormat = SimpleDateFormat(datePattern, sourceLocale)
return doc.select(selectChapter).mapChapters(reversed = true) { i, li ->
val a = li.selectFirst("a")
val href = a?.attrAsRelativeUrlOrNull("href") ?: li.parseFailed("Link is missing")
val link = href + stylePage
val dateText = li.selectFirst("a.c-new-tag")?.attr("title") ?: li.selectFirst(selectDate)?.text()
val name = a.selectFirst("p")?.text() ?: a.ownText()
MangaChapter(
id = generateUid(href),
url = link,
name = name,
number = i + 1f,
volume = 0,
branch = null,
uploadDate = parseChapterDate(
dateFormat,
dateText,
),
scanlator = null,
source = source,
)
}
}
private suspend fun makeRequest(url: String, payload: RequestBody, headers: Headers): Document {
var retryCount = 0
val backoffDelay = 2000L // Initial delay (milliseconds)
val request = Request.Builder().url(url).post(payload).headers(headers).build()
while (true) {
try {
return context.httpClient.newCall(request).execute().parseHtml()
} catch (e: Exception) {
// Log or handle the exception as needed
if (++retryCount <= 5) {
withContext(Dispatchers.Default) {
delay(backoffDelay)
}
} else {
throw e
}
}
}
}
}

@ -30,7 +30,7 @@ internal class Hentai4Free(context: MangaLoaderContext) :
searchPaginator.firstPage = 1
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -32,7 +32,7 @@ internal class HentaiManga(context: MangaLoaderContext) :
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val pages = page + 1
val url = buildString {

@ -1,10 +1,6 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import kotlinx.coroutines.*
import okhttp3.Headers
import okhttp3.Request
import okhttp3.RequestBody
@ -16,7 +12,7 @@ import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
import org.koitharu.kotatsu.parsers.util.*
import java.text.SimpleDateFormat
import java.util.EnumSet
import java.util.*
@MangaSourceParser("HENTAIWEBTOON", "HentaiWebtoon", "en", ContentType.HENTAI)
internal class HentaiWebtoon(context: MangaLoaderContext) :
@ -36,7 +32,7 @@ internal class HentaiWebtoon(context: MangaLoaderContext) :
availableStates = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val pages = page + 1
val url = buildString {

@ -31,7 +31,7 @@ internal class IsekaiScan(context: MangaLoaderContext) :
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -27,7 +27,7 @@ internal class IsekaiScanEuParser(context: MangaLoaderContext) :
searchPaginator.firstPage = 1
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -37,7 +37,7 @@ internal class MangaDass(context: MangaLoaderContext) :
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -9,7 +9,7 @@ import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
import org.koitharu.kotatsu.parsers.util.*
import java.text.SimpleDateFormat
import java.util.EnumSet
import java.util.*
@MangaSourceParser("MANGADNA", "MangaDna", "en", ContentType.HENTAI)
internal class MangaDna(context: MangaLoaderContext) :
@ -32,7 +32,7 @@ internal class MangaDna(context: MangaLoaderContext) :
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -35,7 +35,7 @@ internal class MangaPure(context: MangaLoaderContext) :
)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -38,7 +38,7 @@ internal class Manhwaz(context: MangaLoaderContext) :
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -1,10 +1,6 @@
package org.koitharu.kotatsu.parsers.site.madara.en
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.withContext
import kotlinx.coroutines.*
import okhttp3.Headers
import okhttp3.Request
import okhttp3.RequestBody
@ -16,7 +12,7 @@ import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
import org.koitharu.kotatsu.parsers.util.*
import java.text.SimpleDateFormat
import java.util.EnumSet
import java.util.*
@MangaSourceParser("MANYTOON", "ManyToon", "en", ContentType.HENTAI)
internal class ManyToon(context: MangaLoaderContext) :
@ -40,7 +36,7 @@ internal class ManyToon(context: MangaLoaderContext) :
)
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val pages = page + 1
val url = buildString {

@ -2,73 +2,76 @@ package org.koitharu.kotatsu.parsers.site.madara.es
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.*
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.SortOrder
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
import org.koitharu.kotatsu.parsers.util.*
import java.util.*
@MangaSourceParser("DRAGONTRANSLATION", "Dragon Translation", "es")
internal class DragonTranslationParser(context: MangaLoaderContext) :
MadaraParser(context, MangaParserSource.DRAGONTRANSLATION, "dragontranslation.net", 30) {
MadaraParser(context, MangaParserSource.DRAGONTRANSLATION, "dragontranslation.net", 30) {
override val selectPage = "div#chapter_imgs img"
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
override val selectPage = "div#chapter_imgs img"
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
init {
paginator.firstPage = 1
searchPaginator.firstPage = 1
}
init {
paginator.firstPage = 1
searchPaginator.firstPage = 1
}
override suspend fun getFilterOptions() = super.getFilterOptions().copy(
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override suspend fun getFilterOptions() = super.getFilterOptions().copy(
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
val url = buildString {
append("https://")
append(domain)
when {
!filter.query.isNullOrEmpty() -> {
append("/mangas?buscar=")
append(filter.query.urlEncoded())
append("&page=")
append(page.toString())
}
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)
when {
!filter.query.isNullOrEmpty() -> {
append("/mangas?buscar=")
append(filter.query.urlEncoded())
append("&page=")
append(page.toString())
}
else -> {
else -> {
append("/mangas?page=")
append(page.toString())
append("/mangas?page=")
append(page.toString())
val tag = filter.tags.oneOrThrowIfMany()
if (filter.tags.isNotEmpty()) {
append("&tag=")
append(tag?.key.orEmpty())
}
}
}
}
val tag = filter.tags.oneOrThrowIfMany()
if (filter.tags.isNotEmpty()) {
append("&tag=")
append(tag?.key.orEmpty())
}
}
}
}
val doc = webClient.httpGet(url).parseHtml()
val doc = webClient.httpGet(url).parseHtml()
return doc.select("div.video-bg div.col-6 ").map { div ->
val href =
div.selectFirst("a.series-link")?.attrAsRelativeUrlOrNull("href") ?: div.parseFailed("Link not found")
Manga(
id = generateUid(href),
url = href,
publicUrl = href.toAbsoluteUrl(div.host ?: domain),
coverUrl = div.selectFirst("img.thumb-img")?.src().orEmpty(),
title = div.selectFirst("div.series-box h5")?.text().orEmpty(),
altTitle = null,
rating = div.selectFirst("span.total_votes")?.ownText()?.toFloatOrNull()?.div(5f) ?: -1f,
tags = emptySet(),
author = null,
state = null,
source = source,
isNsfw = isNsfwSource,
)
}
}
return doc.select("div.video-bg div.col-6 ").map { div ->
val href =
div.selectFirst("a.series-link")?.attrAsRelativeUrlOrNull("href") ?: div.parseFailed("Link not found")
Manga(
id = generateUid(href),
url = href,
publicUrl = href.toAbsoluteUrl(div.host ?: domain),
coverUrl = div.selectFirst("img.thumb-img")?.src().orEmpty(),
title = div.selectFirst("div.series-box h5")?.text().orEmpty(),
altTitle = null,
rating = div.selectFirst("span.total_votes")?.ownText()?.toFloatOrNull()?.div(5f) ?: -1f,
tags = emptySet(),
author = null,
state = null,
source = source,
isNsfw = isNsfwSource,
)
}
}
}

@ -33,7 +33,7 @@ internal class TmoManga(context: MangaLoaderContext) :
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -34,7 +34,7 @@ internal class ManhwaHub(context: MangaLoaderContext) :
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -6,11 +6,9 @@ import org.koitharu.kotatsu.parsers.Broken
import org.koitharu.kotatsu.parsers.MangaLoaderContext
import org.koitharu.kotatsu.parsers.MangaSourceParser
import org.koitharu.kotatsu.parsers.model.*
import org.koitharu.kotatsu.parsers.model.MangaState
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
import org.koitharu.kotatsu.parsers.util.*
import java.util.*
import kotlin.collections.Set
@Broken
@MangaSourceParser("SAYTRUYENHAY", "PheTruyen", "vi")
@ -38,7 +36,7 @@ internal class Saytruyenhay(context: MangaLoaderContext) :
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -60,24 +60,15 @@ internal abstract class MadthemeParser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = true,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
isYearSupported = false,
isYearRangeSupported = false,
isOriginalLocaleSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED),
availableContentRating = emptySet(),
availableContentTypes = emptySet(),
availableDemographics = emptySet(),
availableLocales = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -17,7 +17,7 @@ internal class ManhuaScan(context: MangaLoaderContext) :
override val sourceLocale: Locale = Locale.ENGLISH
override val listUrl = "search"
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

@ -54,19 +54,14 @@ internal abstract class Manga18Parser(
override val filterCapabilities: MangaListFilterCapabilities
get() = MangaListFilterCapabilities(
isMultipleTagsSupported = false,
isTagsExclusionSupported = false,
isSearchSupported = true,
isSearchWithFiltersSupported = false,
)
override suspend fun getFilterOptions() = MangaListFilterOptions(
availableTags = fetchAvailableTags(),
availableStates = emptySet(),
availableContentRating = emptySet(),
)
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilter): List<Manga> {
val url = buildString {
append("https://")
append(domain)

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save