Migration to MangaListFilterCapabilities
This commit is contained in:
@@ -2,8 +2,8 @@ import tasks.ReportGenerateTask
|
||||
|
||||
plugins {
|
||||
id 'java-library'
|
||||
id 'org.jetbrains.kotlin.jvm' version '2.0.10-RC'
|
||||
id 'com.google.devtools.ksp' version '2.0.10-RC-1.0.23'
|
||||
id 'org.jetbrains.kotlin.jvm' version '2.0.20'
|
||||
id 'com.google.devtools.ksp' version '2.0.20-1.0.25'
|
||||
id 'maven-publish'
|
||||
}
|
||||
|
||||
@@ -37,6 +37,7 @@ compileTestKotlin {
|
||||
|
||||
kotlin {
|
||||
jvmToolchain(8)
|
||||
explicitApi = 'warning'
|
||||
sourceSets {
|
||||
main.kotlin.srcDirs += 'build/generated/ksp/main/kotlin'
|
||||
}
|
||||
@@ -53,7 +54,7 @@ afterEvaluate {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0-RC'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0'
|
||||
implementation 'com.squareup.okhttp3:okhttp:4.12.0'
|
||||
implementation 'com.squareup.okio:okio:3.9.0'
|
||||
api 'org.jsoup:jsoup:1.18.1'
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id 'org.jetbrains.kotlin.jvm' version '2.0.10-RC'
|
||||
id 'org.jetbrains.kotlin.jvm' version '2.0.20'
|
||||
}
|
||||
|
||||
repositories {
|
||||
@@ -14,5 +14,5 @@ dependencies {
|
||||
implementation gradleApi()
|
||||
implementation 'org.simpleframework:simple-xml:2.7.1'
|
||||
implementation 'com.soywiz.korlibs.korte:korte-jvm:4.0.10'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0-RC'
|
||||
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.9.0'
|
||||
}
|
||||
|
||||
@@ -7,5 +7,5 @@ kotlin {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.devtools.ksp:symbol-processing-api:2.0.10-RC-1.0.23'
|
||||
implementation 'com.google.devtools.ksp:symbol-processing-api:2.0.20-1.0.25'
|
||||
}
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package org.koitharu.kotatsu.parsers
|
||||
|
||||
import androidx.annotation.CallSuper
|
||||
import kotlinx.coroutines.async
|
||||
import kotlinx.coroutines.coroutineScope
|
||||
import okhttp3.Headers
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.config.MangaSourceConfig
|
||||
import org.koitharu.kotatsu.parsers.model.*
|
||||
import org.koitharu.kotatsu.parsers.network.OkHttpWebClient
|
||||
import org.koitharu.kotatsu.parsers.network.WebClient
|
||||
@@ -14,9 +13,9 @@ import org.koitharu.kotatsu.parsers.util.domain
|
||||
import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl
|
||||
import java.util.*
|
||||
|
||||
abstract class MangaParser @InternalParsersApi constructor(
|
||||
@property:InternalParsersApi val context: MangaLoaderContext,
|
||||
val source: MangaParserSource,
|
||||
public abstract class MangaParser @InternalParsersApi constructor(
|
||||
@property:InternalParsersApi public val context: MangaLoaderContext,
|
||||
public val source: MangaParserSource,
|
||||
) {
|
||||
|
||||
/**
|
||||
@@ -24,43 +23,16 @@ abstract class MangaParser @InternalParsersApi constructor(
|
||||
*
|
||||
* For better performance use [EnumSet] for more than one item.
|
||||
*/
|
||||
abstract val availableSortOrders: Set<SortOrder>
|
||||
public abstract val availableSortOrders: Set<SortOrder>
|
||||
|
||||
/**
|
||||
* Supported [MangaState] variants for filtering. May be empty.
|
||||
*
|
||||
* For better performance use [EnumSet] for more than one item.
|
||||
*/
|
||||
@Deprecated("")
|
||||
internal open val availableStates: Set<MangaState>
|
||||
get() = emptySet()
|
||||
public abstract val filterCapabilities: MangaListFilterCapabilities
|
||||
|
||||
open val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = MangaListFilterCapabilities(
|
||||
isMultipleTagsSupported = isMultipleTagsSupported,
|
||||
isTagsExclusionSupported = isTagsExclusionSupported,
|
||||
isSearchSupported = true,
|
||||
isSearchWithFiltersSupported = false,
|
||||
)
|
||||
public val config: MangaSourceConfig by lazy { context.getConfig(source) }
|
||||
|
||||
/**
|
||||
* Whether parser supports filtering by more than one tag
|
||||
*/
|
||||
@Deprecated("Use getListFilterCapabilities instead")
|
||||
internal open val isMultipleTagsSupported: Boolean = true
|
||||
|
||||
/**
|
||||
* Whether parser supports tagsExclude field in filter
|
||||
*/
|
||||
@Deprecated("Use getListFilterCapabilities instead")
|
||||
internal open val isTagsExclusionSupported: Boolean = false
|
||||
|
||||
val config by lazy { context.getConfig(source) }
|
||||
|
||||
open val sourceLocale: Locale
|
||||
public open val sourceLocale: Locale
|
||||
get() = if (source.locale.isEmpty()) Locale.ROOT else Locale(source.locale)
|
||||
|
||||
protected val isNsfwSource = source.contentType == ContentType.HENTAI
|
||||
protected val isNsfwSource: Boolean = source.contentType == ContentType.HENTAI
|
||||
|
||||
/**
|
||||
* Provide default domain and available alternatives, if any.
|
||||
@@ -68,18 +40,18 @@ abstract class MangaParser @InternalParsersApi constructor(
|
||||
* Never hardcode domain in requests, use [domain] instead.
|
||||
*/
|
||||
@InternalParsersApi
|
||||
abstract val configKeyDomain: ConfigKey.Domain
|
||||
public abstract val configKeyDomain: ConfigKey.Domain
|
||||
|
||||
protected open val userAgentKey = ConfigKey.UserAgent(context.getDefaultUserAgent())
|
||||
protected open val userAgentKey: ConfigKey.UserAgent = ConfigKey.UserAgent(context.getDefaultUserAgent())
|
||||
|
||||
open fun getRequestHeaders(): Headers = Headers.Builder()
|
||||
public open fun getRequestHeaders(): Headers = Headers.Builder()
|
||||
.add("User-Agent", config[userAgentKey])
|
||||
.build()
|
||||
|
||||
/**
|
||||
* Used as fallback if value of `order` passed to [getList] is null
|
||||
*/
|
||||
open val defaultSortOrder: SortOrder
|
||||
public open val defaultSortOrder: SortOrder
|
||||
get() {
|
||||
val supported = availableSortOrders
|
||||
return SortOrder.entries.first { it in supported }
|
||||
@@ -96,55 +68,41 @@ abstract class MangaParser @InternalParsersApi constructor(
|
||||
* @param order one of [availableSortOrders] or [defaultSortOrder] for default value
|
||||
* @param filter is a set of filter rules
|
||||
*/
|
||||
abstract suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga>
|
||||
public abstract suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga>
|
||||
|
||||
/**
|
||||
* Parse details for [Manga]: chapters list, description, large cover, etc.
|
||||
* Must return the same manga, may change any fields excepts id, url and source
|
||||
* @see Manga.copy
|
||||
*/
|
||||
abstract suspend fun getDetails(manga: Manga): Manga
|
||||
public abstract suspend fun getDetails(manga: Manga): Manga
|
||||
|
||||
/**
|
||||
* Parse pages list for specified chapter.
|
||||
* @see MangaPage for details
|
||||
*/
|
||||
abstract suspend fun getPages(chapter: MangaChapter): List<MangaPage>
|
||||
public abstract suspend fun getPages(chapter: MangaChapter): List<MangaPage>
|
||||
|
||||
/**
|
||||
* Fetch direct link to the page image.
|
||||
*/
|
||||
internal open suspend fun getPageUrl(page: MangaPage): String = page.url.toAbsoluteUrl(domain)
|
||||
|
||||
/**
|
||||
* Fetch available tags (genres) for source
|
||||
*/
|
||||
@Deprecated("Use getListFilterDatasets instead")
|
||||
internal open suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
|
||||
open suspend fun getFilterOptions(): MangaListFilterOptions = coroutineScope {
|
||||
val tagsDeferred = async { getAvailableTags() }
|
||||
MangaListFilterOptions(
|
||||
availableTags = tagsDeferred.await(),
|
||||
availableStates = availableStates,
|
||||
availableContentRating = emptySet(),
|
||||
availableLocales = emptySet(),
|
||||
)
|
||||
}
|
||||
public abstract suspend fun getFilterOptions(): MangaListFilterOptions
|
||||
|
||||
/**
|
||||
* Parse favicons from the main page of the source`s website
|
||||
*/
|
||||
open suspend fun getFavicons(): Favicons {
|
||||
public open suspend fun getFavicons(): Favicons {
|
||||
return FaviconParser(webClient, domain).parseFavicons()
|
||||
}
|
||||
|
||||
@CallSuper
|
||||
open fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
|
||||
public open fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
|
||||
keys.add(configKeyDomain)
|
||||
}
|
||||
|
||||
open suspend fun getRelatedManga(seed: Manga): List<Manga> {
|
||||
public open suspend fun getRelatedManga(seed: Manga): List<Manga> {
|
||||
return RelatedMangaFinder(listOf(this)).invoke(seed)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.util.Paginator
|
||||
|
||||
@InternalParsersApi
|
||||
abstract class PagedMangaParser(
|
||||
public abstract class PagedMangaParser(
|
||||
context: MangaLoaderContext,
|
||||
source: MangaParserSource,
|
||||
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) @JvmField internal val pageSize: Int,
|
||||
@@ -16,10 +16,10 @@ abstract class PagedMangaParser(
|
||||
) : MangaParser(context, source) {
|
||||
|
||||
@JvmField
|
||||
protected val paginator = Paginator(pageSize)
|
||||
protected val paginator: Paginator = Paginator(pageSize)
|
||||
|
||||
@JvmField
|
||||
protected val searchPaginator = Paginator(searchPageSize)
|
||||
protected val searchPaginator: Paginator = Paginator(searchPageSize)
|
||||
|
||||
final override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
return getList(
|
||||
@@ -34,7 +34,7 @@ abstract class PagedMangaParser(
|
||||
)
|
||||
}
|
||||
|
||||
abstract suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga>
|
||||
public abstract suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga>
|
||||
|
||||
private suspend fun getList(
|
||||
paginator: Paginator,
|
||||
|
||||
@@ -23,7 +23,19 @@ internal abstract class LineWebtoonsParser(
|
||||
source: MangaParserSource,
|
||||
) : MangaParser(context, source) {
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
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 {
|
||||
WebtoonsUrlSigner("gUtPzJFZch4ZyAGviiyH94P99lQ3pFdRTwpJWDlSGFfwgpr6ses5ALOxWHOIT7R1")
|
||||
@@ -237,7 +249,7 @@ internal abstract class LineWebtoonsParser(
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
return makeRequest("/lineWebtoon/webtoon/challengeGenreList.json")
|
||||
.getJSONObject("genreList")
|
||||
.getJSONArray("challengeGenres")
|
||||
|
||||
@@ -40,10 +40,21 @@ internal abstract class MangaPlusParser(
|
||||
SortOrder.ALPHABETICAL,
|
||||
)
|
||||
|
||||
private val extraHeaders = Headers.headersOf("Session-Token", UUID.randomUUID().toString())
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = MangaListFilterCapabilities(
|
||||
isMultipleTagsSupported = false,
|
||||
isTagsExclusionSupported = false,
|
||||
isSearchSupported = true,
|
||||
isSearchWithFiltersSupported = false,
|
||||
)
|
||||
|
||||
// no tags or tag search available
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getFilterOptions() = MangaListFilterOptions(
|
||||
availableTags = emptySet(),
|
||||
availableStates = emptySet(),
|
||||
availableContentRating = emptySet(),
|
||||
)
|
||||
|
||||
private val extraHeaders = Headers.headersOf("Session-Token", UUID.randomUUID().toString())
|
||||
|
||||
override suspend fun getList(order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
return when {
|
||||
|
||||
@@ -16,7 +16,20 @@ internal class MangaStorm(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.POPULARITY, SortOrder.UPDATED)
|
||||
override val configKeyDomain = ConfigKey.Domain("mangastorm.org")
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
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 val userAgentKey = ConfigKey.UserAgent(UserAgents.CHROME_DESKTOP)
|
||||
|
||||
@@ -78,8 +91,6 @@ internal class MangaStorm(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga {
|
||||
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||
val root = doc.selectFirstOrThrow(".card-body .col-lg-9")
|
||||
|
||||
@@ -25,6 +25,20 @@ internal class AnibelParser(context: MangaLoaderContext) : MangaParser(context,
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("anibel.net")
|
||||
|
||||
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<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
keys.add(userAgentKey)
|
||||
@@ -186,7 +200,7 @@ internal class AnibelParser(context: MangaLoaderContext) : MangaParser(context,
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val json = apiCall(
|
||||
"""
|
||||
getFilters(mediaType: manga) {
|
||||
|
||||
@@ -18,6 +18,20 @@ internal class CloneMangaParser(context: MangaLoaderContext) :
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("manga.clone-army.org")
|
||||
|
||||
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 fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
keys.add(userAgentKey)
|
||||
@@ -92,6 +106,4 @@ internal class CloneMangaParser(context: MangaLoaderContext) :
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
}
|
||||
|
||||
@@ -17,19 +17,29 @@ internal class ComicExtra(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.POPULARITY, SortOrder.UPDATED, SortOrder.NEWEST)
|
||||
|
||||
override val availableStates: Set<MangaState> = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("comixextra.com")
|
||||
|
||||
override val userAgentKey = ConfigKey.UserAgent(UserAgents.CHROME_DESKTOP)
|
||||
|
||||
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),
|
||||
availableContentRating = emptySet(),
|
||||
)
|
||||
|
||||
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
keys.add(userAgentKey)
|
||||
}
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
@@ -103,7 +113,7 @@ internal class ComicExtra(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/popular-comic").parseHtml()
|
||||
return doc.select("li.tag-item a").mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
|
||||
@@ -25,13 +25,25 @@ internal class DynastyScans(context: MangaLoaderContext) :
|
||||
|
||||
override val userAgentKey = ConfigKey.UserAgent(UserAgents.CHROME_DESKTOP)
|
||||
|
||||
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<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
keys.add(userAgentKey)
|
||||
}
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
when {
|
||||
!filter.query.isNullOrEmpty() -> {
|
||||
@@ -120,7 +132,7 @@ internal class DynastyScans(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
return coroutineScope {
|
||||
(1..3).map { page ->
|
||||
async { getTags(page) }
|
||||
|
||||
@@ -19,7 +19,19 @@ internal class MangaGeko(context: MangaLoaderContext) : PagedMangaParser(context
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("www.mgeko.cc", "www.mgeko.com", "www.mangageko.com")
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
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<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
@@ -81,7 +93,7 @@ internal class MangaGeko(context: MangaLoaderContext) : PagedMangaParser(context
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/browse-comics/").parseHtml()
|
||||
return doc.select("label.checkbox-inline").mapNotNullToSet { label ->
|
||||
MangaTag(
|
||||
|
||||
@@ -20,6 +20,20 @@ internal class MangaKawaiiEn(context: MangaLoaderContext) :
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("www.mangakawaii.io")
|
||||
|
||||
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<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
keys.add(userAgentKey)
|
||||
@@ -29,8 +43,6 @@ internal class MangaKawaiiEn(context: MangaLoaderContext) :
|
||||
.add("Accept-Language", "en")
|
||||
.build()
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
@@ -155,7 +167,7 @@ internal class MangaKawaiiEn(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/manga-list/").parseHtml()
|
||||
return doc.select("ul li a.category").mapNotNullToSet { a ->
|
||||
val name = a.text()
|
||||
|
||||
@@ -28,12 +28,22 @@ internal class MangaTownParser(context: MangaLoaderContext) :
|
||||
SortOrder.UPDATED,
|
||||
)
|
||||
|
||||
override val availableStates: Set<MangaState> = EnumSet.of(
|
||||
MangaState.ONGOING,
|
||||
MangaState.FINISHED,
|
||||
)
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = MangaListFilterCapabilities(
|
||||
isMultipleTagsSupported = false,
|
||||
isTagsExclusionSupported = false,
|
||||
isSearchSupported = true,
|
||||
isSearchWithFiltersSupported = false,
|
||||
)
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
override suspend fun getFilterOptions() = MangaListFilterOptions(
|
||||
availableTags = fetchAvailableTags(),
|
||||
availableStates = EnumSet.of(
|
||||
MangaState.ONGOING,
|
||||
MangaState.FINISHED,
|
||||
),
|
||||
availableContentRating = emptySet(),
|
||||
)
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val url = buildString {
|
||||
@@ -220,7 +230,7 @@ internal class MangaTownParser(context: MangaLoaderContext) :
|
||||
return doc.requireElementById("image").attrAsAbsoluteUrl("src")
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("/directory/".toAbsoluteUrl(domain)).parseHtml()
|
||||
val root = doc.body().selectFirst("aside.right")
|
||||
?.getElementsContainingOwnText("Genres")
|
||||
|
||||
@@ -10,7 +10,7 @@ import org.koitharu.kotatsu.parsers.util.*
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("MANHWA18", "Manhwa18.net", "en", type = ContentType.HENTAI)
|
||||
class Manhwa18Parser(context: MangaLoaderContext) :
|
||||
internal class Manhwa18Parser(context: MangaLoaderContext) :
|
||||
PagedMangaParser(context, MangaParserSource.MANHWA18, pageSize = 18, searchPageSize = 18) {
|
||||
|
||||
override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("manhwa18.net")
|
||||
@@ -29,16 +29,26 @@ class Manhwa18Parser(context: MangaLoaderContext) :
|
||||
SortOrder.RATING,
|
||||
)
|
||||
|
||||
override val availableStates: Set<MangaState> = EnumSet.of(
|
||||
MangaState.ONGOING,
|
||||
MangaState.FINISHED,
|
||||
MangaState.PAUSED,
|
||||
)
|
||||
|
||||
override val isTagsExclusionSupported = true
|
||||
|
||||
private val tagsMap = SuspendLazy(::parseTags)
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = MangaListFilterCapabilities(
|
||||
isMultipleTagsSupported = true,
|
||||
isTagsExclusionSupported = true,
|
||||
isSearchSupported = true,
|
||||
isSearchWithFiltersSupported = false,
|
||||
)
|
||||
|
||||
override suspend fun getFilterOptions() = MangaListFilterOptions(
|
||||
availableTags = tagsMap.get().values.toSet(),
|
||||
availableStates = EnumSet.of(
|
||||
MangaState.ONGOING,
|
||||
MangaState.FINISHED,
|
||||
MangaState.PAUSED,
|
||||
),
|
||||
availableContentRating = emptySet(),
|
||||
)
|
||||
|
||||
override suspend fun getFavicons(): Favicons {
|
||||
return Favicons(
|
||||
listOf(
|
||||
@@ -218,10 +228,6 @@ class Manhwa18Parser(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return tagsMap.get().values.toSet()
|
||||
}
|
||||
|
||||
private suspend fun parseTags(): Map<String, MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/tim-kiem?q=").parseHtml()
|
||||
val list = doc.getElementsByAttribute("data-genre-id")
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("MANHWASMEN", "ManhwasMen", "en", type = ContentType.HENTAI)
|
||||
class ManhwasMen(context: MangaLoaderContext) :
|
||||
internal class ManhwasMen(context: MangaLoaderContext) :
|
||||
PagedMangaParser(context, MangaParserSource.MANHWASMEN, pageSize = 30, searchPageSize = 30) {
|
||||
|
||||
override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("manhwas.men")
|
||||
@@ -21,12 +21,22 @@ class ManhwasMen(context: MangaLoaderContext) :
|
||||
keys.add(userAgentKey)
|
||||
}
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.of(SortOrder.POPULARITY)
|
||||
|
||||
override val availableStates: Set<MangaState> = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED)
|
||||
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),
|
||||
availableContentRating = emptySet(),
|
||||
)
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
@@ -85,7 +95,7 @@ class ManhwasMen(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val tags = webClient.httpGet("https://$domain/manga-list").parseHtml()
|
||||
.selectLastOrThrow(".filter-bx .form-group select.custom-select").select("option").drop(1)
|
||||
return tags.mapNotNullToSet { option ->
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package org.koitharu.kotatsu.parsers.site.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaParser
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.SinglePageMangaParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
@@ -16,6 +15,20 @@ internal class Po2Scans(context: MangaLoaderContext) : SinglePageMangaParser(con
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
override val configKeyDomain = ConfigKey.Domain("po2scans.com")
|
||||
|
||||
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 fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
keys.add(userAgentKey)
|
||||
@@ -51,8 +64,6 @@ internal class Po2Scans(context: MangaLoaderContext) : SinglePageMangaParser(con
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga {
|
||||
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||
val dateFormat = SimpleDateFormat("dd MMM, yy", Locale.ENGLISH)
|
||||
|
||||
@@ -22,13 +22,25 @@ internal class Pururin(context: MangaLoaderContext) :
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("pururin.to")
|
||||
|
||||
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<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
keys.add(userAgentKey)
|
||||
}
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
@@ -84,7 +96,7 @@ internal class Pururin(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
return coroutineScope {
|
||||
(1..4).map { page ->
|
||||
async { getTags(page) }
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.text.SimpleDateFormat
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("VYMANGA", "VyManga", "en")
|
||||
class VyManga(context: MangaLoaderContext) :
|
||||
internal class VyManga(context: MangaLoaderContext) :
|
||||
PagedMangaParser(context, MangaParserSource.VYMANGA, pageSize = 36) {
|
||||
|
||||
override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("vymanga.net")
|
||||
@@ -21,8 +21,6 @@ class VyManga(context: MangaLoaderContext) :
|
||||
keys.add(userAgentKey)
|
||||
}
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.POPULARITY_ASC,
|
||||
@@ -34,7 +32,19 @@ class VyManga(context: MangaLoaderContext) :
|
||||
SortOrder.UPDATED_ASC,
|
||||
)
|
||||
|
||||
override val availableStates: Set<MangaState> = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED)
|
||||
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),
|
||||
availableContentRating = emptySet(),
|
||||
)
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val url = buildString {
|
||||
@@ -120,7 +130,7 @@ class VyManga(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/").parseHtml()
|
||||
return doc.select("div.dropdown-menu.custom-menu ul li a[href*=genre]").mapNotNullToSet {
|
||||
MangaTag(
|
||||
|
||||
@@ -73,7 +73,7 @@ internal class Manhwa18Com(context: MangaLoaderContext) :
|
||||
return parseMangaList(webClient.httpGet(url).parseHtml())
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||
return doc.select(selectBodyTag).mapNotNullToSet { label ->
|
||||
val key = label.attr("data-genre-id")
|
||||
|
||||
@@ -14,8 +14,12 @@ internal class OlimpoScans(context: MangaLoaderContext) :
|
||||
override val selectAlt = "ul.manga-info li:contains(Otros nombres)"
|
||||
override val selectTag = "ul.manga-info li:contains(Género) a"
|
||||
override val tagPrefix = "lista-de-comics-genero-"
|
||||
override val isMultipleTagsSupported = false
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isMultipleTagsSupported = false,
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val url = buildString {
|
||||
|
||||
@@ -37,16 +37,25 @@ internal class BentomangaParser(context: MangaLoaderContext) :
|
||||
keys.add(userAgentKey)
|
||||
}
|
||||
|
||||
override val availableStates: Set<MangaState> =
|
||||
EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED)
|
||||
|
||||
override val isTagsExclusionSupported: Boolean = true
|
||||
|
||||
init {
|
||||
paginator.firstPage = 0
|
||||
searchPaginator.firstPage = 0
|
||||
}
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = MangaListFilterCapabilities(
|
||||
isMultipleTagsSupported = true,
|
||||
isTagsExclusionSupported = true,
|
||||
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> {
|
||||
val url = urlBuilder()
|
||||
.host(domain)
|
||||
@@ -206,7 +215,7 @@ internal class BentomangaParser(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val root = webClient.httpGet(urlBuilder().addPathSegment("manga_list").build())
|
||||
.parseHtml()
|
||||
.requireElementById("search_options-form")
|
||||
|
||||
@@ -17,11 +17,22 @@ internal class LegacyScansParser(context: MangaLoaderContext) :
|
||||
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.POPULARITY)
|
||||
|
||||
override val availableStates: Set<MangaState> =
|
||||
EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.ABANDONED, MangaState.PAUSED)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("legacy-scans.com")
|
||||
|
||||
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.ABANDONED, MangaState.PAUSED),
|
||||
availableContentRating = emptySet(),
|
||||
)
|
||||
|
||||
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
keys.add(userAgentKey)
|
||||
@@ -163,7 +174,7 @@ internal class LegacyScansParser(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/comics").parseHtml()
|
||||
val script = doc.requireElementById("__NUXT_DATA__").data()
|
||||
.substringAfterLast("\"genres\"").substringBeforeLast("\"comics\"")
|
||||
|
||||
@@ -18,13 +18,25 @@ internal class LireScan(context: MangaLoaderContext) : PagedMangaParser(context,
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("lire-scan.me")
|
||||
|
||||
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<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
keys.add(userAgentKey)
|
||||
}
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val doc = when {
|
||||
!filter.query.isNullOrEmpty() -> {
|
||||
@@ -133,7 +145,7 @@ internal class LireScan(context: MangaLoaderContext) : PagedMangaParser(context,
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/").parseHtml()
|
||||
return doc.select(".nav-menu li a").mapNotNullToSet { a ->
|
||||
val key = a.attr("href").removeSuffix('/').substringAfterLast("manga/", "")
|
||||
|
||||
@@ -19,6 +19,20 @@ internal class MangaKawaii(context: MangaLoaderContext) : PagedMangaParser(conte
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("www.mangakawaii.io")
|
||||
|
||||
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<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
keys.add(userAgentKey)
|
||||
@@ -28,8 +42,6 @@ internal class MangaKawaii(context: MangaLoaderContext) : PagedMangaParser(conte
|
||||
.add("Accept-Language", "fr")
|
||||
.build()
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
@@ -154,7 +166,7 @@ internal class MangaKawaii(context: MangaLoaderContext) : PagedMangaParser(conte
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/manga-list/").parseHtml()
|
||||
return doc.select("ul li a.category").mapNotNullToSet { a ->
|
||||
val name = a.text()
|
||||
|
||||
@@ -32,18 +32,27 @@ internal class MangaMana(context: MangaLoaderContext) : PagedMangaParser(context
|
||||
SortOrder.NEWEST,
|
||||
)
|
||||
|
||||
override val availableStates: Set<MangaState> =
|
||||
EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.ABANDONED)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("www.manga-mana.com")
|
||||
|
||||
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.ABANDONED),
|
||||
availableContentRating = emptySet(),
|
||||
)
|
||||
|
||||
override fun onCreateConfig(keys: MutableCollection<ConfigKey<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
keys.add(userAgentKey)
|
||||
}
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val postData = buildString {
|
||||
append("page=")
|
||||
@@ -98,7 +107,7 @@ internal class MangaMana(context: MangaLoaderContext) : PagedMangaParser(context
|
||||
val doc = webClient.httpGet("https://$domain/?page=$page").parseHtml()
|
||||
return doc.select("div.row div.col_home").map { div ->
|
||||
val href = div.selectFirstOrThrow("h4 a").attrAsRelativeUrl("href")
|
||||
val isNsfw = div.selectFirst("img[data-adult]")?.attr("data-adult")?.isNotEmpty() ?: false
|
||||
val isNsfw = div.selectFirst("img[data-adult]")?.attr("data-adult")?.isNotEmpty() == true
|
||||
val img = if (isNsfw) {
|
||||
div.selectFirst("img")?.attr("data-adult")
|
||||
} else {
|
||||
@@ -159,7 +168,7 @@ internal class MangaMana(context: MangaLoaderContext) : PagedMangaParser(context
|
||||
|
||||
return doc.select("div.p-2 div.col").map { div ->
|
||||
val href = div.selectFirstOrThrow("a").attrAsRelativeUrl("href")
|
||||
val isNsfw = div.selectFirst("img[data-adult]")?.attr("data-adult")?.isNotEmpty() ?: false
|
||||
val isNsfw = div.selectFirst("img[data-adult]")?.attr("data-adult")?.isNotEmpty() == true
|
||||
val img = if (isNsfw) {
|
||||
div.selectFirst("img")?.attr("data-adult")
|
||||
} else {
|
||||
@@ -320,7 +329,7 @@ internal class MangaMana(context: MangaLoaderContext) : PagedMangaParser(context
|
||||
return pages
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/liste-mangas").parseHtml()
|
||||
return doc.select("select.selectpicker option").drop(1).mapNotNullToSet {
|
||||
MangaTag(
|
||||
|
||||
@@ -31,12 +31,6 @@ internal abstract class FuzzyDoodleParser(
|
||||
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.NEWEST)
|
||||
|
||||
override val availableStates: Set<MangaState> =
|
||||
EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED)
|
||||
|
||||
override val isMultipleTagsSupported = true
|
||||
|
||||
|
||||
@JvmField
|
||||
protected val ongoing = scatterSetOf(
|
||||
"en cours",
|
||||
@@ -73,7 +67,21 @@ internal abstract class FuzzyDoodleParser(
|
||||
protected open val pausedValue = "haitus"
|
||||
protected open val abandonedValue = "dropped"
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
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> {
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
append(domain)
|
||||
@@ -250,7 +258,7 @@ internal abstract class FuzzyDoodleParser(
|
||||
|
||||
protected open val selectTagsList = "div.mt-1 div.items-center:has(label)"
|
||||
|
||||
override suspend fun getAvailableTags(): 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
|
||||
|
||||
@@ -6,14 +6,17 @@ import org.koitharu.kotatsu.parsers.model.ContentType
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaState
|
||||
import org.koitharu.kotatsu.parsers.site.fuzzydoodle.FuzzyDoodleParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("HENTAISLAYER", "HentaiSlayer", "ar", ContentType.HENTAI)
|
||||
internal class HentaiSlayer(context: MangaLoaderContext) :
|
||||
FuzzyDoodleParser(context, MangaParserSource.HENTAISLAYER, "hentaislayer.net") {
|
||||
override val availableStates: Set<MangaState> =
|
||||
EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.ABANDONED)
|
||||
|
||||
override val ongoingValue = "مستمر"
|
||||
override val finishedValue = "مكتمل"
|
||||
override val abandonedValue = "متوقف"
|
||||
|
||||
override suspend fun getFilterOptions() = super.getFilterOptions().copy(
|
||||
availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.ABANDONED),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,12 +5,16 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaState
|
||||
import org.koitharu.kotatsu.parsers.site.fuzzydoodle.FuzzyDoodleParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("LELSCANVF", "LelScanFr", "fr")
|
||||
internal class LelScanVf(context: MangaLoaderContext) :
|
||||
FuzzyDoodleParser(context, MangaParserSource.LELSCANVF, "lelscanfr.com") {
|
||||
override val availableStates: Set<MangaState> = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED)
|
||||
|
||||
override val ongoingValue = "en-cours"
|
||||
override val finishedValue = "termin"
|
||||
|
||||
override suspend fun getFilterOptions() = super.getFilterOptions().copy(
|
||||
availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED),
|
||||
)
|
||||
}
|
||||
|
||||
@@ -18,7 +18,10 @@ internal class HentaiFox(context: MangaLoaderContext) :
|
||||
override val selectTag = "ul.tags"
|
||||
override val selectLanguageChapter = "ul.languages a.tag_btn"
|
||||
|
||||
override val isMultipleTagsSupported = true
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isMultipleTagsSupported = true,
|
||||
)
|
||||
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY)
|
||||
|
||||
|
||||
@@ -25,7 +25,19 @@ internal abstract class GattsuParser(
|
||||
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
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"
|
||||
|
||||
@@ -86,7 +98,7 @@ internal abstract class GattsuParser(
|
||||
|
||||
protected open val tagUrl = "generos"
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$tagUrl/").parseHtml()
|
||||
return doc.selectLastOrThrow(".meio-conteudo p, div.lista-tags ul").parseTags()
|
||||
}
|
||||
|
||||
@@ -13,7 +13,21 @@ internal class UniversoHentai(context: MangaLoaderContext) :
|
||||
|
||||
override val tagPrefix = "category"
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
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> {
|
||||
val doc = webClient.httpGet("https://$domain/tags/").parseHtml()
|
||||
return doc.requireElementById("menu-topo").parseTags()
|
||||
}
|
||||
|
||||
@@ -25,8 +25,19 @@ class DoujinDesuParser(context: MangaLoaderContext) :
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.of(SortOrder.UPDATED, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.POPULARITY)
|
||||
|
||||
override val availableStates: Set<MangaState> = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED)
|
||||
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()
|
||||
.add("X-Requested-With", "XMLHttpRequest")
|
||||
@@ -158,7 +169,7 @@ class DoujinDesuParser(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
return webClient.httpGet("/genre/".toAbsoluteUrl(domain)).parseHtml()
|
||||
.requireElementById("taxonomy")
|
||||
.selectFirstOrThrow(".entries")
|
||||
|
||||
@@ -17,13 +17,25 @@ internal class HentaiCrot(context: MangaLoaderContext) :
|
||||
)
|
||||
override val configKeyDomain = ConfigKey.Domain("hentaicrot.com")
|
||||
|
||||
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<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
keys.add(userAgentKey)
|
||||
}
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
@@ -71,7 +83,7 @@ internal class HentaiCrot(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||
return doc.select("ul.megamenu li").mapNotNullToSet { li ->
|
||||
val key = li.selectFirstOrThrow("a").attr("href").removeSuffix('/').substringAfterLast('/')
|
||||
|
||||
@@ -17,13 +17,25 @@ internal class PixHentai(context: MangaLoaderContext) :
|
||||
)
|
||||
override val configKeyDomain = ConfigKey.Domain("pixhentai.com")
|
||||
|
||||
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<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
keys.add(userAgentKey)
|
||||
}
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
@@ -71,7 +83,7 @@ internal class PixHentai(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||
return doc.select("ul.megamenu li").mapNotNullToSet { li ->
|
||||
val key = li.selectFirstOrThrow("a").attr("href").removeSuffix('/').substringAfterLast('/')
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
package org.koitharu.kotatsu.parsers.site.ja
|
||||
|
||||
import org.koitharu.kotatsu.parsers.*
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaParser
|
||||
import org.koitharu.kotatsu.parsers.MangaParserAuthProvider
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
import org.koitharu.kotatsu.parsers.exception.AuthRequiredException
|
||||
import org.koitharu.kotatsu.parsers.model.*
|
||||
@@ -12,12 +15,26 @@ private const val STATUS_ONGOING = "連載"
|
||||
private const val STATUS_FINISHED = "完結"
|
||||
|
||||
@MangaSourceParser("NICOVIDEO_SEIGA", "NicoVideo Seiga", "ja")
|
||||
class NicovideoSeigaParser(context: MangaLoaderContext) :
|
||||
internal class NicovideoSeigaParser(context: MangaLoaderContext) :
|
||||
MangaParser(context, MangaParserSource.NICOVIDEO_SEIGA),
|
||||
MangaParserAuthProvider {
|
||||
|
||||
override val userAgentKey = ConfigKey.UserAgent(UserAgents.CHROME_DESKTOP)
|
||||
|
||||
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<*>>) {
|
||||
super.onCreateConfig(keys)
|
||||
keys.add(userAgentKey)
|
||||
@@ -41,8 +58,6 @@ class NicovideoSeigaParser(context: MangaLoaderContext) :
|
||||
SortOrder.POPULARITY,
|
||||
)
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("nicovideo.jp")
|
||||
|
||||
override suspend fun getList(offset: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
@@ -139,7 +154,7 @@ class NicovideoSeigaParser(context: MangaLoaderContext) :
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
||||
val fullUrl = chapter.url.toAbsoluteUrl(getDomain("seiga"))
|
||||
val doc = webClient.httpGet(fullUrl).parseHtml()
|
||||
if (!doc.select("#login_manga").isEmpty())
|
||||
if (!doc.select("#login_manga").isEmpty)
|
||||
throw AuthRequiredException(source)
|
||||
val root = doc.body().select("#page_contents > li")
|
||||
return root.map { li ->
|
||||
@@ -153,7 +168,7 @@ class NicovideoSeigaParser(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://${getDomain("seiga")}/manga/list").parseHtml()
|
||||
val root = doc.body().selectOrThrow("#mg_category_list > ul > li").drop(1)
|
||||
return root.mapToSet { li ->
|
||||
|
||||
@@ -26,8 +26,6 @@ internal abstract class KeyoappParser(
|
||||
keys.add(userAgentKey)
|
||||
}
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.NEWEST,
|
||||
@@ -57,6 +55,19 @@ internal abstract class KeyoappParser(
|
||||
"dropped",
|
||||
)
|
||||
|
||||
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> {
|
||||
var query = ""
|
||||
@@ -160,7 +171,7 @@ internal abstract class KeyoappParser(
|
||||
}
|
||||
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||
return doc.requireElementById("series_tags_page").select("button").mapNotNullToSet { button ->
|
||||
val key = button.attr("tag") ?: return@mapNotNullToSet null
|
||||
|
||||
@@ -32,10 +32,19 @@ internal abstract class LikeMangaParser(
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST)
|
||||
|
||||
override val availableStates: Set<MangaState> =
|
||||
EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED)
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = MangaListFilterCapabilities(
|
||||
isMultipleTagsSupported = false,
|
||||
isTagsExclusionSupported = false,
|
||||
isSearchSupported = true,
|
||||
isSearchWithFiltersSupported = false,
|
||||
)
|
||||
|
||||
override val isMultipleTagsSupported = 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> {
|
||||
val url = buildString {
|
||||
@@ -113,7 +122,7 @@ internal abstract class LikeMangaParser(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/genres/").parseHtml()
|
||||
return doc.select("ul.nav-genres li:not(.text-center) a").mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
|
||||
@@ -82,7 +82,7 @@ internal class Manga18Fx(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||
val list = doc.body().selectFirstOrThrow("div.genre-menu").select("ul li").orEmpty()
|
||||
val keySet = HashSet<String>(list.size)
|
||||
|
||||
@@ -15,7 +15,6 @@ internal class Manhwa18Cc(context: MangaLoaderContext) :
|
||||
override val listUrl = "webtoons/"
|
||||
override val tagPrefix = "webtoon-genre/"
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
override val selectTestAsync = "ul.row-content-chapter"
|
||||
@@ -23,6 +22,11 @@ internal class Manhwa18Cc(context: MangaLoaderContext) :
|
||||
override val selectChapter = "li.a-h"
|
||||
override val selectBodyPage = "div.read-content"
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
|
||||
init {
|
||||
paginator.firstPage = 1
|
||||
searchPaginator.firstPage = 1
|
||||
@@ -91,7 +95,7 @@ internal class Manhwa18Cc(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||
val list = doc.body().selectFirstOrThrow("div.sub-menu").select("ul li").orEmpty()
|
||||
val keySet = HashSet<String>(list.size)
|
||||
|
||||
@@ -2,10 +2,11 @@ package org.koitharu.kotatsu.parsers.site.madara.ar
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("GATEMANGA", "GateManga", "ar")
|
||||
internal class GateManga(context: MangaLoaderContext) :
|
||||
@@ -14,7 +15,11 @@ internal class GateManga(context: MangaLoaderContext) :
|
||||
override val datePattern = "d MMMM، yyyy"
|
||||
override val listUrl = "ar/"
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
|
||||
|
||||
@@ -2,17 +2,21 @@ package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("BESTMANHUACOM", "BestManhua.com", "en")
|
||||
internal class BestManhuaCom(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.BESTMANHUACOM, "bestmanhua.com", 10) {
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
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,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,7 +3,10 @@ package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
import org.jsoup.nodes.Document
|
||||
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.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaState
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
|
||||
@@ -52,7 +55,7 @@ internal class FireScans(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/?s=&post_type=wp-manga").parseHtml()
|
||||
return doc.select("form.search-advanced-form div.form-group div.checkbox ").mapNotNullToSet { div ->
|
||||
val key = div.selectFirst("input")?.attr("value") ?: return@mapNotNullToSet null
|
||||
|
||||
@@ -4,17 +4,22 @@ import org.koitharu.kotatsu.parsers.Broken
|
||||
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.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@Broken // Redirect to @hentai20
|
||||
@MangaSourceParser("HENTAI3Z", "Hentai3z", "en", ContentType.HENTAI)
|
||||
internal class Hentai3z(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.HENTAI3Z, "manga18h.xyz", pageSize = 20) {
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.*
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("HENTAI_4FREE", "Hentai4Free", "en", ContentType.HENTAI)
|
||||
internal class Hentai4Free(context: MangaLoaderContext) :
|
||||
@@ -15,7 +15,11 @@ internal class Hentai4Free(context: MangaLoaderContext) :
|
||||
override val tagPrefix = "hentai-tag/"
|
||||
override val listUrl = ""
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
override val datePattern = "MMMM dd, yyyy"
|
||||
|
||||
@@ -5,7 +5,7 @@ import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.*
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("ISEKAISCAN_EU", "ParagonScans", "en")
|
||||
internal class IsekaiScanEuParser(context: MangaLoaderContext) :
|
||||
@@ -13,7 +13,11 @@ internal class IsekaiScanEuParser(context: MangaLoaderContext) :
|
||||
|
||||
override val datePattern = "MM/dd/yyyy"
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
override val listUrl = "mangax/"
|
||||
|
||||
@@ -4,17 +4,22 @@ import org.koitharu.kotatsu.parsers.Broken
|
||||
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.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@Broken
|
||||
@MangaSourceParser("MANGA1K", "Manga1k", "en", ContentType.HENTAI)
|
||||
internal class Manga1k(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.MANGA1K, "manga1k.com", 20) {
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
}
|
||||
|
||||
@@ -3,17 +3,22 @@ package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
import org.koitharu.kotatsu.parsers.Broken
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@Broken
|
||||
@MangaSourceParser("MANGA68", "Manga68", "en")
|
||||
internal class Manga68(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.MANGA68, "manga68.com") {
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
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,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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("MANGADASS", "MangaDass", "en", ContentType.HENTAI)
|
||||
internal class MangaDass(context: MangaLoaderContext) :
|
||||
@@ -17,12 +17,16 @@ internal class MangaDass(context: MangaLoaderContext) :
|
||||
|
||||
override val datePattern = "dd MMM yyyy"
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
override val selectChapter = "li.a-h"
|
||||
override val selectDesc = "div.ss-manga"
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
|
||||
init {
|
||||
paginator.firstPage = 1
|
||||
searchPaginator.firstPage = 1
|
||||
|
||||
@@ -3,10 +3,11 @@ package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
import org.koitharu.kotatsu.parsers.Broken
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@Broken
|
||||
@MangaSourceParser("MANGAEFFECT", "MangaEffect", "en")
|
||||
@@ -14,7 +15,10 @@ internal class MangaEffect(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.MANGAEFFECT, "mangaeffect.com") {
|
||||
override val datePattern = "dd.MM.yyyy"
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
}
|
||||
|
||||
@@ -2,16 +2,20 @@ package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("MANGAFASTNET", "MangaFast.net", "en")
|
||||
internal class MangaFastNet(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.MANGAFASTNET, "manhuafast.net") {
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
}
|
||||
|
||||
@@ -3,17 +3,21 @@ package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
import org.koitharu.kotatsu.parsers.Broken
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@Broken
|
||||
@MangaSourceParser("MANGAUS", "Mangaus", "en")
|
||||
internal class Mangaus(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.MANGAUS, "mangaus.xyz") {
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
}
|
||||
|
||||
@@ -3,20 +3,20 @@ package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.exception.ParseException
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.model.*
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("MANHUAPLUS", "ManhuaPlus", "en")
|
||||
internal class Manhuaplus(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.MANHUAPLUS, "manhuaplus.com") {
|
||||
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
|
||||
|
||||
@@ -2,16 +2,21 @@ package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("MANHUAUSS", "Manhuauss", "en")
|
||||
internal class Manhuauss(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.MANHUAUSS, "manhuauss.com") {
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
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,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -5,17 +5,11 @@ import kotlinx.coroutines.coroutineScope
|
||||
import org.jsoup.nodes.Document
|
||||
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.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaState
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
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("MANHWAHENTAI", "ManhwaHentai", "en", ContentType.HENTAI)
|
||||
internal class ManhwaHentai(context: MangaLoaderContext) :
|
||||
@@ -23,7 +17,11 @@ internal class ManhwaHentai(context: MangaLoaderContext) :
|
||||
override val tagPrefix = "webtoon-genre/"
|
||||
override val listUrl = "webtoon/"
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
override val postReq = true
|
||||
|
||||
@@ -3,10 +3,11 @@ package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
import org.koitharu.kotatsu.parsers.Broken
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@Broken
|
||||
@MangaSourceParser("MMSCANS", "MmScans", "en")
|
||||
@@ -15,7 +16,11 @@ internal class MmScans(context: MangaLoaderContext) :
|
||||
override val selectChapter = "li.chapter-li"
|
||||
override val selectDesc = "div.summary-text"
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@ package org.koitharu.kotatsu.parsers.site.madara.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.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("TOONGOD", "ToonGod", "en", ContentType.HENTAI)
|
||||
internal class ToonGod(context: MangaLoaderContext) :
|
||||
@@ -15,7 +16,10 @@ internal class ToonGod(context: MangaLoaderContext) :
|
||||
override val tagPrefix = "webtoon-genre/"
|
||||
override val datePattern = "d MMM yyyy"
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
}
|
||||
|
||||
@@ -2,17 +2,22 @@ package org.koitharu.kotatsu.parsers.site.madara.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("ZINMANGA", "ZinManga.net", "en")
|
||||
internal class Zinmanga(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.ZINMANGA, "zinmanga.net") {
|
||||
override val datePattern = "MM/dd/yyyy"
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
}
|
||||
|
||||
@@ -4,17 +4,22 @@ import org.koitharu.kotatsu.parsers.Broken
|
||||
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.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@Broken
|
||||
@MangaSourceParser("INDO18H", "Indo18h", "id", ContentType.HENTAI)
|
||||
internal class Indo18h(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.INDO18H, "indo18h.com", 24) {
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@ package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
import org.koitharu.kotatsu.parsers.Broken
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@Broken
|
||||
@MangaSourceParser("ANCIENTCOMICS", "AncientComics", "pt")
|
||||
@@ -14,7 +15,11 @@ internal class AncientComics(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.ANCIENTCOMICS, "ancientcomics.com.br") {
|
||||
override val datePattern: String = "dd/MM/yyyy"
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
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,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,17 +2,22 @@ package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("ATEMPORAL", "Atemporal", "pt")
|
||||
internal class Atemporal(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.ATEMPORAL, "atemporal.cloud") {
|
||||
override val datePattern: String = "d 'de' MMMM 'de' yyyy"
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
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,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,17 +2,22 @@ package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("GALINHASAMURAI", "GalinhaSamurai", "pt")
|
||||
internal class GalinhaSamurai(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.GALINHASAMURAI, "galinhasamurai.com") {
|
||||
override val datePattern = "dd/MM/yyyy"
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
}
|
||||
|
||||
@@ -2,17 +2,21 @@ package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("IMPERIODABRITANNIA", "ImperioDaBritannia", "pt")
|
||||
internal class ImperiodaBritannia(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.IMPERIODABRITANNIA, "imperiodabritannia.com", 10) {
|
||||
override val datePattern: String = "dd 'de' MMMMM 'de' yyyy"
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ internal class MrBenne(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.MRBENNE, "mrbenne.com", 10) {
|
||||
override val datePattern: String = "dd/MM/yyyy"
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
override suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/?s=&post_type=wp-manga").parseHtml()
|
||||
val body = doc.body()
|
||||
val root = body.selectFirst("div.form-group.checkbox-group")
|
||||
|
||||
@@ -2,17 +2,21 @@ package org.koitharu.kotatsu.parsers.site.madara.pt
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("NORTEROSE", "Norterose", "pt")
|
||||
internal class Norterose(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.NORTEROSE, "norterose.com.br", 10) {
|
||||
override val datePattern: String = "dd/MM/yyyy"
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
}
|
||||
|
||||
@@ -3,16 +3,21 @@ package org.koitharu.kotatsu.parsers.site.madara.th
|
||||
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.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.site.madara.MadaraParser
|
||||
import java.util.EnumSet
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("DOUJINZA", "Doujinza", "th", ContentType.HENTAI)
|
||||
internal class Doujinza(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaParserSource.DOUJINZA, "doujinza.com", 24) {
|
||||
override val withoutAjax = true
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.RATING)
|
||||
override val datePattern = "MMMM dd, yyyy"
|
||||
|
||||
@@ -31,8 +31,6 @@ internal abstract class Manga18Parser(
|
||||
SortOrder.ALPHABETICAL,
|
||||
)
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
protected open val listUrl = "list-manga/"
|
||||
protected open val tagUrl = "manga-list/"
|
||||
protected open val datePattern = "dd-MM-yyyy"
|
||||
@@ -54,6 +52,20 @@ internal abstract class Manga18Parser(
|
||||
"Completed",
|
||||
)
|
||||
|
||||
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> {
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
@@ -114,7 +126,7 @@ internal abstract class Manga18Parser(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl/").parseHtml()
|
||||
return doc.select("div.grid_cate li").mapNotNullToSet { li ->
|
||||
val a = li.selectFirst("a") ?: return@mapNotNullToSet null
|
||||
|
||||
@@ -35,5 +35,5 @@ internal class Hanman18(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet() // search by tag does not work
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> = emptySet() // search by tag does not work
|
||||
}
|
||||
|
||||
@@ -30,10 +30,6 @@ internal abstract class MangaboxParser(
|
||||
SortOrder.ALPHABETICAL,
|
||||
)
|
||||
|
||||
override val availableStates: Set<MangaState> = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED)
|
||||
|
||||
override val isTagsExclusionSupported = true
|
||||
|
||||
protected open val listUrl = "/advanced_search"
|
||||
protected open val searchUrl = "/search/story/"
|
||||
protected open val datePattern = "MMM dd,yy"
|
||||
@@ -44,7 +40,6 @@ internal abstract class MangaboxParser(
|
||||
searchPaginator.firstPage = 1
|
||||
}
|
||||
|
||||
|
||||
@JvmField
|
||||
protected val ongoing: Set<String> = setOf(
|
||||
"ongoing",
|
||||
@@ -55,6 +50,20 @@ internal abstract class MangaboxParser(
|
||||
"completed",
|
||||
)
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = MangaListFilterCapabilities(
|
||||
isMultipleTagsSupported = true,
|
||||
isTagsExclusionSupported = true,
|
||||
isSearchSupported = true,
|
||||
isSearchWithFiltersSupported = false,
|
||||
)
|
||||
|
||||
override suspend fun getFilterOptions() = MangaListFilterOptions(
|
||||
availableTags = fetchAvailableTags(),
|
||||
availableStates = EnumSet.of(MangaState.ONGOING, MangaState.FINISHED),
|
||||
availableContentRating = emptySet(),
|
||||
)
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val url = buildString {
|
||||
append("https://")
|
||||
@@ -139,7 +148,7 @@ internal abstract class MangaboxParser(
|
||||
|
||||
protected open val selectTagMap = "div.panel-genres-list a:not(.genres-select)"
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||
val tags = doc.select(selectTagMap).drop(1) // remove all tags
|
||||
return tags.mapNotNullToSet { a ->
|
||||
|
||||
@@ -31,8 +31,11 @@ internal class Mangairo(context: MangaLoaderContext) :
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.NEWEST,
|
||||
)
|
||||
override val isTagsExclusionSupported = false
|
||||
override val isMultipleTagsSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
isMultipleTagsSupported = false,
|
||||
)
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val url = buildString {
|
||||
@@ -105,7 +108,7 @@ internal class Mangairo(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl/type-latest/ctg-all/state-all/page-1").parseHtml()
|
||||
return doc.select("div.panel_category a:not(.ctg_select)").mapNotNullToSet { a ->
|
||||
val key = a.attr("href").substringAfterLast("ctg-").substringBefore("/")
|
||||
|
||||
@@ -19,8 +19,11 @@ internal class Mangakakalot(context: MangaLoaderContext) :
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.NEWEST,
|
||||
)
|
||||
override val isTagsExclusionSupported = false
|
||||
override val isMultipleTagsSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
isMultipleTagsSupported = false,
|
||||
)
|
||||
override val otherDomain = "chapmanganato.com"
|
||||
override val listUrl = "/manga_list"
|
||||
|
||||
@@ -94,7 +97,7 @@ internal class Mangakakalot(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||
val tags = doc.select("ul.tag li a").drop(1)
|
||||
return tags.mapNotNullToSet { a ->
|
||||
|
||||
@@ -22,8 +22,11 @@ internal class MangakakalotTv(context: MangaLoaderContext) :
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.NEWEST,
|
||||
)
|
||||
override val isMultipleTagsSupported = false
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
isMultipleTagsSupported = false,
|
||||
)
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val url = buildString {
|
||||
@@ -125,7 +128,7 @@ internal class MangakakalotTv(context: MangaLoaderContext) :
|
||||
|
||||
override val selectTagMap = "ul.tag li a"
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
private suspend fun fetchAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||
return doc.select(selectTagMap).mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
|
||||
@@ -3,8 +3,8 @@ package org.koitharu.kotatsu.parsers.site.mangadventure.en
|
||||
import androidx.collection.ArraySet
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterOptions
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.parsers.site.mangadventure.MangAdventureParser
|
||||
|
||||
@MangaSourceParser("ASSORTEDSCANS", "AssortedScans", "en")
|
||||
@@ -16,8 +16,10 @@ internal class AssortedScans(context: MangaLoaderContext) :
|
||||
"Shoujo Ai", "Shounen Ai", "Smut", "Yaoi",
|
||||
)
|
||||
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val tags = super.getAvailableTags()
|
||||
return tags.filterNotTo(ArraySet(tags.size)) { it.key in emptyTags }
|
||||
override suspend fun getFilterOptions(): MangaListFilterOptions {
|
||||
val options = super.getFilterOptions()
|
||||
return options.copy(
|
||||
availableTags = options.availableTags.filterNotTo(ArraySet(options.availableTags.size)) { it.key in emptyTags },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,11 +2,16 @@ package org.koitharu.kotatsu.parsers.site.mangareader.ar
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("ARAREASCANS", "ArAreaScans", "ar")
|
||||
internal class ArAreaScans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.ARAREASCANS, "ar.areascans.org", pageSize = 20, searchPageSize = 10) {
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,16 @@ package org.koitharu.kotatsu.parsers.site.mangareader.ar
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("AREASCANS", "AreaScans", "ar")
|
||||
internal class AreaScans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.AREASCANS, "www.areascans.net", pageSize = 20, searchPageSize = 10) {
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site.mangareader.ar
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@@ -10,5 +11,8 @@ internal class FlAres(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.FLARES, "fl-ares.com", pageSize = 20, searchPageSize = 10) {
|
||||
override val listUrl = "/series"
|
||||
override val encodedSrc = true
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,15 @@ package org.koitharu.kotatsu.parsers.site.mangareader.ar
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("MANGAPRO", "MangaPro", "ar")
|
||||
internal class MangaPro(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.MANGAPRO, "promanga.pro", pageSize = 20, searchPageSize = 10) {
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -16,7 +16,10 @@ internal class Normoyun(context: MangaLoaderContext) :
|
||||
override val selectMangaList = ".listupd .bs .bsx"
|
||||
override val selectMangaListImg = "img"
|
||||
override val isNetShieldProtected = true
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
|
||||
override suspend fun getListPage(page: Int, order: SortOrder, filter: MangaListFilterV2): List<Manga> {
|
||||
val url = buildString {
|
||||
|
||||
@@ -5,6 +5,7 @@ import org.koitharu.kotatsu.parsers.Broken
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
@@ -15,7 +16,10 @@ import org.koitharu.kotatsu.parsers.util.*
|
||||
internal class PotatoManga(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.POTATOMANGA, "potatomanga.xyz", pageSize = 30, searchPageSize = 10) {
|
||||
override val listUrl = "/series"
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
|
||||
override suspend fun getPages(chapter: MangaChapter): List<MangaPage> {
|
||||
val chapterUrl = chapter.url.toAbsoluteUrl(domain)
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site.mangareader.ar
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@@ -9,5 +10,8 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
internal class ScarManga(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.SCARMANGA, "scarmanga.com", pageSize = 20, searchPageSize = 10) {
|
||||
override val listUrl = "/series"
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site.mangareader.ar
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@@ -14,6 +15,9 @@ internal class ThunderScans(context: MangaLoaderContext) :
|
||||
pageSize = 32,
|
||||
searchPageSize = 10,
|
||||
) {
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val selectChapter = ".eplister > ul > li"
|
||||
}
|
||||
|
||||
@@ -2,11 +2,15 @@ package org.koitharu.kotatsu.parsers.site.mangareader.ar
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("UMIMANGA", "UmiManga", "ar")
|
||||
internal class UmiManga(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.UMIMANGA, "www.umimanga.com", pageSize = 20, searchPageSize = 10) {
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,10 +3,7 @@ package org.koitharu.kotatsu.parsers.site.mangareader.ar
|
||||
import org.koitharu.kotatsu.parsers.Broken
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.WordSet
|
||||
import org.koitharu.kotatsu.parsers.model.*
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
import java.text.DateFormat
|
||||
@@ -19,7 +16,10 @@ internal class VexManga(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.VEXMANGA, "vexmanga.com", pageSize = 10, searchPageSize = 10) {
|
||||
override val selectMangaList = ".listarchives .latest-recom"
|
||||
override val selectChapter = ".ulChapterList > a"
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga {
|
||||
val docs = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@@ -9,5 +10,9 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
internal class AgsComics(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.AGSCOMICS, "agscomics.com", pageSize = 20, searchPageSize = 10) {
|
||||
override val listUrl = "/series"
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,16 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("ALTAYSCANS", "AltayScans", "en")
|
||||
internal class AltayScans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.ALTAYSCANS, "altayscans.com", pageSize = 20, searchPageSize = 10) {
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@@ -9,5 +10,9 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
internal class AnigliScans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.ANIGLISCANS, "anigliscans.xyz", pageSize = 47, searchPageSize = 47) {
|
||||
override val listUrl = "/series"
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,16 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("ASCALONSCANS", "AscalonScans", "en")
|
||||
internal class AscalonScans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.ASCALONSCANS, "ascalonscans.com", pageSize = 20, searchPageSize = 10) {
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,12 +2,18 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("ASTRASCANS", "AstraScans", "en")
|
||||
internal class AstraScans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.ASTRASCANS, "astrascans.org", pageSize = 20, searchPageSize = 10) {
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val listUrl = "/series"
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@@ -9,5 +10,9 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
internal class BirdManga(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.BIRDMANGA, "birdmanga.com", pageSize = 20, searchPageSize = 10) {
|
||||
override val encodedSrc = true
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,10 +2,7 @@ package org.koitharu.kotatsu.parsers.site.mangareader.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.Manga
|
||||
import org.koitharu.kotatsu.parsers.model.MangaChapter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.*
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
|
||||
@@ -19,7 +16,11 @@ internal class Constellarcomic(context: MangaLoaderContext) :
|
||||
searchPageSize = 18,
|
||||
) {
|
||||
override val selectTestScript = "script:containsData(ts_rea_der_._run)"
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga {
|
||||
val docs = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
import org.koitharu.kotatsu.parsers.Broken
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@@ -11,5 +12,8 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
internal class CosmicScansParser(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.COSMICSCANS, "cosmic-scans.com", pageSize = 20, searchPageSize = 10) {
|
||||
override val datePattern = "MMM d, yyyy"
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@@ -15,5 +16,9 @@ internal class EnThunderScans(context: MangaLoaderContext) :
|
||||
searchPageSize = 10,
|
||||
) {
|
||||
override val listUrl = "/comics"
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,16 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("ENRYUMANGA", "EnryuManga", "en")
|
||||
internal class EnryuManga(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.ENRYUMANGA, "enryumanga.net", pageSize = 20, searchPageSize = 10) {
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
|
||||
import org.koitharu.kotatsu.parsers.Broken
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
@@ -18,7 +19,11 @@ import org.koitharu.kotatsu.parsers.util.toTitleCase
|
||||
@MangaSourceParser("FREAKCOMIC", "FreakComic", "en")
|
||||
internal class FreakComic(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.FREAKCOMIC, "freakcomic.com", pageSize = 20, searchPageSize = 10) {
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
override val selectMangaList = ".listupd .lastest-serie"
|
||||
override val selectMangaListImg = "img"
|
||||
override val selectChapter = ".chapter-li a:not(:has(svg))"
|
||||
|
||||
@@ -3,6 +3,7 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
import org.koitharu.kotatsu.parsers.Broken
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@@ -11,5 +12,9 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
internal class FreakScans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.FREAKSCANS, "freakscans.com", pageSize = 20, searchPageSize = 20) {
|
||||
override val datePattern = "MMM d, yyyy"
|
||||
override val isTagsExclusionSupported = false
|
||||
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@@ -9,5 +10,8 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
@MangaSourceParser("KAISCANS", "KaiScans", "en")
|
||||
internal class KaiScans(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.KAISCANS, "ponvi.online", pageSize = 20, searchPageSize = 10) {
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@@ -9,5 +10,8 @@ import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
internal class KomikLabParser(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.KOMIKLAB, "komiklab.com", pageSize = 20, searchPageSize = 10) {
|
||||
override val datePattern = "MMM d, yyyy"
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,11 +2,15 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@MangaSourceParser("LUACOMIC_COM", "luaComic.com", "en")
|
||||
internal class LuaComicCom(context: MangaLoaderContext) :
|
||||
MangaReaderParser(context, MangaParserSource.LUACOMIC_COM, "ponvi.online", pageSize = 20, searchPageSize = 10) {
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ package org.koitharu.kotatsu.parsers.site.mangareader.en
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.model.MangaListFilterCapabilities
|
||||
import org.koitharu.kotatsu.parsers.model.MangaParserSource
|
||||
import org.koitharu.kotatsu.parsers.site.mangareader.MangaReaderParser
|
||||
|
||||
@@ -16,5 +17,8 @@ internal class LuminousScans(context: MangaLoaderContext) :
|
||||
) {
|
||||
|
||||
override val listUrl = "/series"
|
||||
override val isTagsExclusionSupported = false
|
||||
override val filterCapabilities: MangaListFilterCapabilities
|
||||
get() = super.filterCapabilities.copy(
|
||||
isTagsExclusionSupported = false,
|
||||
)
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user