Advanced filtering support
This commit is contained in:
@@ -23,7 +23,27 @@ abstract class MangaParser @InternalParsersApi constructor(
|
||||
*
|
||||
* For better performance use [EnumSet] for more than one item.
|
||||
*/
|
||||
abstract val sortOrders: Set<SortOrder>
|
||||
abstract val availableSortOrders: Set<SortOrder>
|
||||
|
||||
/**
|
||||
* Supported [MangaState] variants for filtering. May be empty.
|
||||
*
|
||||
* For better performance use [EnumSet] for more than one item.
|
||||
*/
|
||||
open val availableStates: Set<MangaState>
|
||||
get() = emptySet()
|
||||
|
||||
/**
|
||||
* Whether parser supports filtering by more than one tag
|
||||
*/
|
||||
open val isMultipleTagsSupported: Boolean = true
|
||||
|
||||
@Deprecated(
|
||||
message = "Use availableSortOrders instead",
|
||||
replaceWith = ReplaceWith("availableSortOrders"),
|
||||
)
|
||||
val sortOrders: Set<SortOrder>
|
||||
get() = availableSortOrders
|
||||
|
||||
val config by lazy { context.getConfig(source) }
|
||||
|
||||
@@ -49,7 +69,7 @@ abstract class MangaParser @InternalParsersApi constructor(
|
||||
*/
|
||||
protected open val defaultSortOrder: SortOrder
|
||||
get() {
|
||||
val supported = sortOrders
|
||||
val supported = availableSortOrders
|
||||
return SortOrder.entries.first { it in supported }
|
||||
}
|
||||
|
||||
@@ -62,11 +82,15 @@ abstract class MangaParser @InternalParsersApi constructor(
|
||||
* @param offset starting from 0 and used for pagination.
|
||||
* Note than passed value may not be divisible by internal page size, so you should adjust it manually.
|
||||
* @param query search query, may be null or empty if no search needed
|
||||
* @param tags genres for filtering, values from [getTags] and [Manga.tags]. May be null or empty
|
||||
* @param sortOrder one of [sortOrders] or null for default value
|
||||
* @param tags genres for filtering, values from [getAvailableTags] and [Manga.tags]. May be null or empty
|
||||
* @param sortOrder one of [availableSortOrders] or null for default value
|
||||
*/
|
||||
@JvmSynthetic
|
||||
@InternalParsersApi
|
||||
@Deprecated(
|
||||
"Use getList with filter instead",
|
||||
replaceWith = ReplaceWith("getList(offset, filter)"),
|
||||
)
|
||||
abstract suspend fun getList(
|
||||
offset: Int,
|
||||
query: String?,
|
||||
@@ -80,8 +104,15 @@ abstract class MangaParser @InternalParsersApi constructor(
|
||||
* @param offset starting from 0 and used for pagination.
|
||||
* @param query search query
|
||||
*/
|
||||
@Deprecated(
|
||||
"Use getList with filter instead",
|
||||
ReplaceWith(
|
||||
"getList(offset, MangaListFilter.Search(query))",
|
||||
"org.koitharu.kotatsu.parsers.model.MangaListFilter",
|
||||
),
|
||||
)
|
||||
open suspend fun getList(offset: Int, query: String): List<Manga> {
|
||||
return getList(offset, query, null, defaultSortOrder)
|
||||
return getList(offset, MangaListFilter.Search(query))
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -89,11 +120,29 @@ abstract class MangaParser @InternalParsersApi constructor(
|
||||
*
|
||||
* @param offset starting from 0 and used for pagination.
|
||||
* Note than passed value may not be divisible by internal page size, so you should adjust it manually.
|
||||
* @param tags genres for filtering, values from [getTags] and [Manga.tags]. May be null or empty
|
||||
* @param sortOrder one of [sortOrders] or null for default value
|
||||
* @param tags genres for filtering, values from [getAvailableTags] and [Manga.tags]. May be null or empty
|
||||
* @param sortOrder one of [availableSortOrders] or null for default value
|
||||
*/
|
||||
@Deprecated(
|
||||
"Use getList with filter instead",
|
||||
ReplaceWith(
|
||||
"getList(offset, MangaListFilter.Advanced(sortOrder, tags, null, emptySet()))",
|
||||
"org.koitharu.kotatsu.parsers.model.MangaListFilter",
|
||||
),
|
||||
)
|
||||
open suspend fun getList(offset: Int, tags: Set<MangaTag>?, sortOrder: SortOrder?): List<Manga> {
|
||||
return getList(offset, null, tags, sortOrder ?: defaultSortOrder)
|
||||
return getList(
|
||||
offset,
|
||||
MangaListFilter.Advanced(sortOrder ?: defaultSortOrder, tags.orEmpty(), null, emptySet()),
|
||||
)
|
||||
}
|
||||
|
||||
open suspend fun getList(offset: Int, filter: MangaListFilter?): List<Manga> {
|
||||
return when (filter) {
|
||||
is MangaListFilter.Advanced -> getList(offset, null, filter.tags, filter.sortOrder)
|
||||
is MangaListFilter.Search -> getList(offset, filter.query, null, defaultSortOrder)
|
||||
null -> getList(offset, null, null, defaultSortOrder)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -117,7 +166,18 @@ abstract class MangaParser @InternalParsersApi constructor(
|
||||
/**
|
||||
* Fetch available tags (genres) for source
|
||||
*/
|
||||
abstract suspend fun getTags(): Set<MangaTag>
|
||||
abstract suspend fun getAvailableTags(): Set<MangaTag>
|
||||
|
||||
/**
|
||||
* Fetch available locales for multilingual sources
|
||||
*/
|
||||
open suspend fun getAvailableLocales(): Set<Locale> = emptySet()
|
||||
|
||||
@Deprecated(
|
||||
message = "Use getAvailableTags instead",
|
||||
replaceWith = ReplaceWith("getAvailableTags()"),
|
||||
)
|
||||
suspend fun getTags(): Set<MangaTag> = getAvailableTags()
|
||||
|
||||
/**
|
||||
* Parse favicons from the main page of the source`s website
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
package org.koitharu.kotatsu.parsers.model
|
||||
|
||||
import java.util.*
|
||||
|
||||
sealed interface MangaListFilter {
|
||||
|
||||
fun isEmpty(): Boolean
|
||||
|
||||
val sortOrder: SortOrder?
|
||||
|
||||
data class Search(
|
||||
@JvmField val query: String,
|
||||
) : MangaListFilter {
|
||||
|
||||
override val sortOrder: SortOrder? = null
|
||||
|
||||
override fun isEmpty() = query.isBlank()
|
||||
}
|
||||
|
||||
data class Advanced(
|
||||
override val sortOrder: SortOrder,
|
||||
@JvmField val tags: Set<MangaTag>,
|
||||
@JvmField val locale: Locale?,
|
||||
@JvmField val states: Set<MangaState>,
|
||||
) : MangaListFilter {
|
||||
|
||||
override fun isEmpty(): Boolean = tags.isEmpty() && locale == null && states.isEmpty()
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
package org.koitharu.kotatsu.parsers.model
|
||||
|
||||
enum class MangaState {
|
||||
ONGOING, FINISHED, ABANDONED
|
||||
ONGOING, FINISHED, ABANDONED, PAUSED
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser(
|
||||
searchPageSize = 20,
|
||||
) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.NEWEST,
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.POPULARITY,
|
||||
@@ -159,7 +159,7 @@ internal class BatoToParser(context: MangaLoaderContext) : PagedMangaParser(
|
||||
throw ParseException("Cannot find images list", fullUrl)
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val scripts = webClient.httpGet(
|
||||
"https://${domain}/browse",
|
||||
).parseHtml().selectOrThrow("script")
|
||||
|
||||
@@ -25,7 +25,7 @@ internal class ComickFunParser(context: MangaLoaderContext) : MangaParser(contex
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("comick.app")
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.RATING,
|
||||
@@ -137,7 +137,7 @@ internal class ComickFunParser(context: MangaLoaderContext) : MangaParser(contex
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val sparseArray = cachedTags ?: loadTags()
|
||||
val set = ArraySet<MangaTag>(sparseArray.size())
|
||||
for (i in 0 until sparseArray.size()) {
|
||||
|
||||
@@ -23,7 +23,7 @@ internal class ExHentaiParser(
|
||||
context: MangaLoaderContext,
|
||||
) : PagedMangaParser(context, MangaSource.EXHENTAI, pageSize = 25), MangaParserAuthProvider {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = Collections.singleton(
|
||||
override val availableSortOrders: Set<SortOrder> = Collections.singleton(
|
||||
SortOrder.NEWEST,
|
||||
)
|
||||
|
||||
@@ -213,7 +213,7 @@ internal class ExHentaiParser(
|
||||
return doc.body().requireElementById("img").attrAsAbsoluteUrl("src")
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://${domain}").parseHtml()
|
||||
val root = doc.body().requireElementById("searchbox").selectFirstOrThrow("table")
|
||||
return root.select("div.cs").mapNotNullToSet { div ->
|
||||
|
||||
@@ -17,11 +17,13 @@ import java.util.*
|
||||
internal class ImHentai(context: MangaLoaderContext) :
|
||||
PagedMangaParser(context, MangaSource.IMHENTAI, pageSize = 20) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> =
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.RATING)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("imhentai.xxx")
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
query: String?,
|
||||
@@ -83,7 +85,7 @@ internal class ImHentai(context: MangaLoaderContext) :
|
||||
|
||||
//Tags are deliberately reduced because there are too many and this slows down the application.
|
||||
//only the most popular ones are taken.
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return coroutineScope {
|
||||
(1..3).map { page ->
|
||||
async { getTags(page) }
|
||||
|
||||
@@ -24,6 +24,8 @@ internal abstract class LineWebtoonsParser(
|
||||
source: MangaSource,
|
||||
) : MangaParser(context, source) {
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
private val signer by lazy {
|
||||
WebtoonsUrlSigner("gUtPzJFZch4ZyAGviiyH94P99lQ3pFdRTwpJWDlSGFfwgpr6ses5ALOxWHOIT7R1")
|
||||
}
|
||||
@@ -39,7 +41,7 @@ internal abstract class LineWebtoonsParser(
|
||||
private val apiDomain = "global.apis.naver.com"
|
||||
private val staticDomain = "webtoon-phinf.pstatic.net"
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.POPULARITY,
|
||||
// doesn't actually sort by rating, but by likes
|
||||
// this should be fine though
|
||||
@@ -235,7 +237,7 @@ internal abstract class LineWebtoonsParser(
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return makeRequest("/lineWebtoon/webtoon/challengeGenreList.json")
|
||||
.getJSONObject("genreList")
|
||||
.getJSONArray("challengeGenres")
|
||||
|
||||
@@ -30,7 +30,7 @@ internal class MangaDexParser(context: MangaLoaderContext) : MangaParser(context
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("mangadex.org")
|
||||
|
||||
override val sortOrders: EnumSet<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: EnumSet<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.ALPHABETICAL,
|
||||
SortOrder.NEWEST,
|
||||
@@ -159,7 +159,7 @@ internal class MangaDexParser(context: MangaLoaderContext) : MangaParser(context
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val tags = webClient.httpGet("https://api.${domain}/manga/tag").parseJson()
|
||||
.getJSONArray("data")
|
||||
return tags.mapJSONToSet { jo ->
|
||||
|
||||
@@ -31,7 +31,7 @@ internal abstract class NineMangaParser(
|
||||
.add("Accept-Language", "en-US;q=0.7,en;q=0.3")
|
||||
.build()
|
||||
|
||||
override val sortOrders: Set<SortOrder> = Collections.singleton(
|
||||
override val availableSortOrders: Set<SortOrder> = Collections.singleton(
|
||||
SortOrder.POPULARITY,
|
||||
)
|
||||
|
||||
@@ -158,7 +158,7 @@ internal abstract class NineMangaParser(
|
||||
private var tagCache: ArrayMap<String, MangaTag>? = null
|
||||
private val mutex = Mutex()
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return getOrCreateTagMap().values.toSet()
|
||||
}
|
||||
|
||||
|
||||
@@ -22,7 +22,9 @@ internal abstract class AnimeBootstrapParser(
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.ALPHABETICAL,
|
||||
@@ -93,7 +95,7 @@ internal abstract class AnimeBootstrapParser(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain$listUrl").parseHtml()
|
||||
return doc.select("div.product__page__filter div:contains(Genre:) option ").mapNotNullToSet { option ->
|
||||
val key = option.attr("value") ?: return@mapNotNullToSet null
|
||||
|
||||
@@ -20,6 +20,8 @@ internal class PapScan(context: MangaLoaderContext) :
|
||||
|
||||
override val sourceLocale: Locale = Locale.ENGLISH
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override val listUrl = "/liste-manga"
|
||||
|
||||
override val selectState = "div.anime__details__widget li:contains(En cours)"
|
||||
@@ -27,7 +29,7 @@ internal class PapScan(context: MangaLoaderContext) :
|
||||
|
||||
override val selectChapter = "ul.chapters li"
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.ALPHABETICAL,
|
||||
)
|
||||
@@ -85,7 +87,7 @@ internal class PapScan(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain$listUrl").parseHtml()
|
||||
return doc.select("a.category ").mapNotNullToSet { a ->
|
||||
val key = a.attr("href").substringAfterLast('=')
|
||||
|
||||
@@ -18,7 +18,7 @@ import java.util.*
|
||||
@MangaSourceParser("FLIXSCANS", "FlixScans", "ar")
|
||||
internal class FlixScans(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.FLIXSCANS, 18) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val configKeyDomain = ConfigKey.Domain("flixscans.com")
|
||||
|
||||
override suspend fun getListPage(
|
||||
@@ -70,7 +70,7 @@ internal class FlixScans(context: MangaLoaderContext) : PagedMangaParser(context
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/search/advance").parseHtml()
|
||||
val json = JSONArray(doc.requireElementById("__NUXT_DATA__").data())
|
||||
val tagsList = json.getJSONArray(3).toString().replace("[", "").replace("]", "").split(",")
|
||||
|
||||
@@ -13,8 +13,9 @@ import java.util.*
|
||||
@MangaSourceParser("MANGASTORM", "MangaStorm", "ar")
|
||||
internal class MangaStorm(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.MANGASTORM, 30) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.POPULARITY)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.POPULARITY)
|
||||
override val configKeyDomain = ConfigKey.Domain("mangastorm.org")
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override val headers: Headers = Headers.Builder()
|
||||
.add("User-Agent", UserAgents.CHROME_DESKTOP)
|
||||
@@ -69,7 +70,7 @@ internal class MangaStorm(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga {
|
||||
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||
|
||||
@@ -16,8 +16,9 @@ import java.util.*
|
||||
@MangaSourceParser("TEAMXNOVEL", "TeamXNovel", "ar")
|
||||
internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.TEAMXNOVEL, 10) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY)
|
||||
override val configKeyDomain = ConfigKey.Domain("team11x11.com")
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
@@ -82,7 +83,7 @@ internal class TeamXNovel(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/series").parseHtml()
|
||||
return doc.requireElementById("select_genre").select("option").mapNotNullToSet {
|
||||
MangaTag(
|
||||
|
||||
@@ -23,7 +23,7 @@ internal class AnibelParser(context: MangaLoaderContext) : MangaParser(context,
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("anibel.net")
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.NEWEST,
|
||||
)
|
||||
|
||||
@@ -176,7 +176,7 @@ internal class AnibelParser(context: MangaLoaderContext) : MangaParser(context,
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val json = apiCall(
|
||||
"""
|
||||
getFilters(mediaType: manga) {
|
||||
|
||||
@@ -13,10 +13,12 @@ import java.util.*
|
||||
internal class BeeToon(context: MangaLoaderContext) :
|
||||
PagedMangaParser(context, MangaSource.BEETOON, pageSize = 30) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("ww7.beetoon.net")
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
query: String?,
|
||||
@@ -80,7 +82,7 @@ internal class BeeToon(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/").parseHtml()
|
||||
return doc.requireElementById("menu-item-3").select("ul.sub-menu li a").mapNotNullToSet {
|
||||
MangaTag(
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.*
|
||||
@MangaSourceParser("CLONEMANGA", "CloneManga", "en")
|
||||
internal class CloneMangaParser(context: MangaLoaderContext) : MangaParser(context, MangaSource.CLONEMANGA) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = Collections.singleton(
|
||||
override val availableSortOrders: Set<SortOrder> = Collections.singleton(
|
||||
SortOrder.POPULARITY,
|
||||
)
|
||||
|
||||
@@ -89,5 +89,5 @@ internal class CloneMangaParser(context: MangaLoaderContext) : MangaParser(conte
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
}
|
||||
|
||||
@@ -14,10 +14,13 @@ import java.util.*
|
||||
@MangaSourceParser("COMICEXTRA", "ComicExtra", "en")
|
||||
internal class ComicExtra(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.COMICEXTRA, 25) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.POPULARITY, SortOrder.UPDATED, SortOrder.NEWEST)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.POPULARITY, SortOrder.UPDATED, SortOrder.NEWEST)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("comicextra.me")
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override val headers: Headers = Headers.Builder()
|
||||
.add("User-Agent", UserAgents.CHROME_DESKTOP)
|
||||
.build()
|
||||
@@ -80,7 +83,7 @@ internal class ComicExtra(context: MangaLoaderContext) : PagedMangaParser(contex
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/popular-comic").parseHtml()
|
||||
return doc.select("li.tag-item a").mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.util.*
|
||||
|
||||
@MangaSourceParser("DYNASTYSCANS", "DynastyScans", "en")
|
||||
internal class DynastyScans(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.DYNASTYSCANS, 117) {
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
override val configKeyDomain = ConfigKey.Domain("dynasty-scans.com")
|
||||
|
||||
override val headers: Headers = Headers.Builder()
|
||||
@@ -100,7 +100,7 @@ internal class DynastyScans(context: MangaLoaderContext) : PagedMangaParser(cont
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga {
|
||||
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||
|
||||
@@ -15,11 +15,13 @@ import java.util.*
|
||||
internal class Fakku(context: MangaLoaderContext) :
|
||||
PagedMangaParser(context, MangaSource.FAKKU, pageSize = 25) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> =
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.ALPHABETICAL, SortOrder.NEWEST, SortOrder.UPDATED)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("fakku.cc")
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
query: String?,
|
||||
@@ -77,7 +79,7 @@ internal class Fakku(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val root = webClient.httpGet("https://$domain/tags").parseHtml()
|
||||
return root.select("div.entries .entry a").mapToSet {
|
||||
MangaTag(
|
||||
|
||||
@@ -20,9 +20,10 @@ import java.util.*
|
||||
@MangaSourceParser("KSKMOE", "Ksk.moe", "en", ContentType.HENTAI)
|
||||
internal class KskMoe(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.KSKMOE, 35) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> =
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.ALPHABETICAL)
|
||||
override val configKeyDomain = ConfigKey.Domain("ksk.moe")
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
@@ -91,7 +92,7 @@ internal class KskMoe(context: MangaLoaderContext) : PagedMangaParser(context, M
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return coroutineScope {
|
||||
(1..2).map { page ->
|
||||
async { getTags(page) }
|
||||
|
||||
@@ -14,10 +14,13 @@ import java.util.*
|
||||
@MangaSourceParser("MANGAGEKO", "MangaGeko", "en")
|
||||
internal class MangaGeko(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.MANGAGEKO, 30) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.POPULARITY, SortOrder.UPDATED, SortOrder.NEWEST)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.POPULARITY, SortOrder.UPDATED, SortOrder.NEWEST)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("www.mangageko.com")
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override val headers: Headers = Headers.Builder()
|
||||
.add("User-Agent", UserAgents.CHROME_DESKTOP)
|
||||
.build()
|
||||
@@ -77,7 +80,7 @@ internal class MangaGeko(context: MangaLoaderContext) : PagedMangaParser(context
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/browse-comics/").parseHtml()
|
||||
return doc.select("label.checkbox-inline").mapNotNullToSet { label ->
|
||||
MangaTag(
|
||||
|
||||
@@ -15,7 +15,7 @@ internal class MangaTownParser(context: MangaLoaderContext) : MangaParser(contex
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("www.mangatown.com")
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.ALPHABETICAL,
|
||||
SortOrder.RATING,
|
||||
SortOrder.POPULARITY,
|
||||
@@ -157,7 +157,7 @@ internal class MangaTownParser(context: MangaLoaderContext) : MangaParser(contex
|
||||
return doc.requireElementById("image").attrAsAbsoluteUrl("src")
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("/directory/".toAbsoluteUrl(domain)).parseHtml()
|
||||
val root = doc.body().selectFirst("aside.right")
|
||||
?.getElementsContainingOwnText("Genres")
|
||||
|
||||
@@ -18,7 +18,7 @@ import java.util.*
|
||||
internal class Mangaowl(context: MangaLoaderContext) :
|
||||
PagedMangaParser(context, MangaSource.MANGAOWL, pageSize = 24) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.NEWEST,
|
||||
SortOrder.UPDATED,
|
||||
@@ -94,7 +94,7 @@ internal class Mangaowl(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/8-genres").parseHtml()
|
||||
return doc.select("div.genres-container span.genre-item a").mapNotNullToSet { a ->
|
||||
val key = a.attr("href").substringAfterLast("/")
|
||||
|
||||
@@ -15,7 +15,7 @@ class Manhwa18Parser(context: MangaLoaderContext) :
|
||||
|
||||
override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("manhwa18.net")
|
||||
|
||||
override val sortOrders: Set<SortOrder>
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.ALPHABETICAL, SortOrder.NEWEST)
|
||||
|
||||
private val tagsMap = SuspendLazy(::parseTags)
|
||||
@@ -169,7 +169,7 @@ class Manhwa18Parser(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return tagsMap.get().values.toSet()
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,9 @@ class ManhwasMen(context: MangaLoaderContext) :
|
||||
|
||||
override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("manhwas.men")
|
||||
|
||||
override val sortOrders: Set<SortOrder>
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.of(SortOrder.POPULARITY)
|
||||
|
||||
override suspend fun getListPage(
|
||||
@@ -64,7 +66,7 @@ class ManhwasMen(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): 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 ->
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.*
|
||||
@MangaSourceParser("PO2SCANS", "Po2Scans", "en")
|
||||
internal class Po2Scans(context: MangaLoaderContext) : MangaParser(context, MangaSource.PO2SCANS) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
override val configKeyDomain = ConfigKey.Domain("po2scans.com")
|
||||
|
||||
override suspend fun getList(offset: Int, query: String?, tags: Set<MangaTag>?, sortOrder: SortOrder): List<Manga> {
|
||||
@@ -46,7 +46,7 @@ internal class Po2Scans(context: MangaLoaderContext) : MangaParser(context, Mang
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga {
|
||||
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||
|
||||
@@ -17,11 +17,13 @@ import java.util.*
|
||||
internal class Pururin(context: MangaLoaderContext) :
|
||||
PagedMangaParser(context, MangaSource.PURURIN, pageSize = 20) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> =
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.RATING, SortOrder.ALPHABETICAL)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("pururin.to")
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
query: String?,
|
||||
@@ -76,7 +78,7 @@ internal class Pururin(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return coroutineScope {
|
||||
(1..4).map { page ->
|
||||
async { getTags(page) }
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.util.*
|
||||
internal class TempleScanEsp(context: MangaLoaderContext) :
|
||||
PagedMangaParser(context, MangaSource.TEMPLESCANESP, pageSize = 15) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.NEWEST, SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.NEWEST, SortOrder.UPDATED)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("templescanesp.net")
|
||||
|
||||
@@ -66,7 +66,7 @@ internal class TempleScanEsp(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
|
||||
val fullUrl = manga.url.toAbsoluteUrl(domain)
|
||||
|
||||
@@ -24,7 +24,7 @@ class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaParser(
|
||||
|
||||
private val chapterDateFormat = SimpleDateFormat("yyyy-MM-dd", sourceLocale)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.ALPHABETICAL,
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.NEWEST,
|
||||
@@ -207,7 +207,7 @@ class TuMangaOnlineParser(context: MangaLoaderContext) : PagedMangaParser(
|
||||
return document
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/library", headers).parseHtml()
|
||||
val elements = doc.body().select("div#books-genders > div > div")
|
||||
return elements.mapNotNullToSet { element ->
|
||||
|
||||
@@ -21,12 +21,14 @@ internal abstract class FmreaderParser(
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.ALPHABETICAL,
|
||||
)
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
protected open val listUrl = "/manga-list.html"
|
||||
protected open val datePattern = "MMMM d, yyyy"
|
||||
protected open val tagPrefix = "manga-list-genre-"
|
||||
@@ -113,7 +115,7 @@ internal abstract class FmreaderParser(
|
||||
|
||||
protected open val selectBodyTag = "ul.filter-type li a"
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||
return doc.select(selectBodyTag).mapNotNullToSet { a ->
|
||||
val href = a.attr("href").substringAfter(tagPrefix).substringBeforeLast(".html")
|
||||
|
||||
@@ -86,7 +86,7 @@ internal class Manhwa18Com(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||
return doc.select(selectBodyTag).mapNotNullToSet { a ->
|
||||
val href = a.attr("href").substringAfterLast("/")
|
||||
|
||||
@@ -20,7 +20,7 @@ internal abstract class FoolSlideParser(
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
|
||||
protected open val listUrl = "directory/"
|
||||
protected open val searchUrl = "search/"
|
||||
@@ -81,7 +81,7 @@ internal abstract class FoolSlideParser(
|
||||
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
|
||||
protected open val selectInfo = "div.info"
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ import java.util.*
|
||||
@MangaSourceParser("BENTOMANGA", "BentoManga", "fr")
|
||||
internal class BentomangaParser(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.BENTOMANGA, 10) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.RATING,
|
||||
@@ -156,7 +156,7 @@ internal class BentomangaParser(context: MangaLoaderContext) : PagedMangaParser(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val root = webClient.httpGet(urlBuilder().addPathSegment("manga_list").build())
|
||||
.parseHtml()
|
||||
.requireElementById("search_options-form")
|
||||
|
||||
@@ -17,7 +17,7 @@ import java.util.*
|
||||
internal class FmTeam(context: MangaLoaderContext) :
|
||||
PagedMangaParser(context, MangaSource.FMTEAM, 0) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
override val configKeyDomain = ConfigKey.Domain("fmteam.fr")
|
||||
|
||||
override suspend fun getListPage(
|
||||
@@ -99,7 +99,7 @@ internal class FmTeam(context: MangaLoaderContext) :
|
||||
}
|
||||
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
|
||||
val fullUrl = manga.url.toAbsoluteUrl(domain)
|
||||
|
||||
@@ -18,7 +18,7 @@ import java.util.*
|
||||
internal class FuryoSociety(context: MangaLoaderContext) :
|
||||
PagedMangaParser(context, MangaSource.FURYOSOCIETY, 0) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL, SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL, SortOrder.UPDATED)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("furyosociety.com")
|
||||
|
||||
@@ -76,7 +76,7 @@ internal class FuryoSociety(context: MangaLoaderContext) :
|
||||
}
|
||||
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga = coroutineScope {
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.util.*
|
||||
internal class LegacyScansParser(context: MangaLoaderContext) :
|
||||
PagedMangaParser(context, MangaSource.LEGACY_SCANS, 18) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.POPULARITY,
|
||||
)
|
||||
|
||||
@@ -151,7 +151,7 @@ internal class LegacyScansParser(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/comics").parseHtml()
|
||||
val script = doc.requireElementById("__NUXT_DATA__").data()
|
||||
.substringAfterLast("\"genres\"").substringBeforeLast("\"comics\"")
|
||||
|
||||
@@ -14,10 +14,12 @@ import java.util.*
|
||||
@MangaSourceParser("LIRESCAN", "LireScan", "fr")
|
||||
internal class LireScan(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.LIRESCAN, 20) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("lire-scan.me")
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override val headers: Headers = Headers.Builder()
|
||||
.add("User-Agent", UserAgents.CHROME_MOBILE)
|
||||
.build()
|
||||
@@ -130,7 +132,7 @@ internal class LireScan(context: MangaLoaderContext) : PagedMangaParser(context,
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): 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/", "")
|
||||
|
||||
@@ -16,7 +16,7 @@ import java.util.*
|
||||
@MangaSourceParser("LUGNICASCANS", "LugnicaScans", "fr")
|
||||
internal class LugnicaScans(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.LUGNICASCANS, 10) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.ALPHABETICAL,
|
||||
SortOrder.UPDATED,
|
||||
)
|
||||
@@ -176,6 +176,6 @@ internal class LugnicaScans(context: MangaLoaderContext) : PagedMangaParser(cont
|
||||
return pages
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ import java.util.*
|
||||
internal class ScansMangasMe(context: MangaLoaderContext) :
|
||||
PagedMangaParser(context, MangaSource.SCANS_MANGAS_ME, 0) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.ALPHABETICAL,
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.NEWEST,
|
||||
@@ -91,7 +91,7 @@ internal class ScansMangasMe(context: MangaLoaderContext) :
|
||||
}
|
||||
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/tous-nos-mangas/").parseHtml()
|
||||
return doc.select("ul.genre li").mapNotNullToSet { li ->
|
||||
val key = li.selectFirstOrThrow("a").attr("href").removeSuffix('/').substringAfterLast('/')
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.util.*
|
||||
@MangaSourceParser("SCANTRADUNION", "ScantradUnion", "fr")
|
||||
internal class ScantradUnion(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.SCANTRADUNION, 10) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.ALPHABETICAL,
|
||||
SortOrder.UPDATED,
|
||||
)
|
||||
@@ -174,7 +174,7 @@ internal class ScantradUnion(context: MangaLoaderContext) : PagedMangaParser(con
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/").parseHtml()
|
||||
val body = doc.body()
|
||||
val root = body.select(".asp_gochosen")[1]
|
||||
|
||||
@@ -20,8 +20,9 @@ internal abstract class GalleryAdultsParser(
|
||||
pageSize: Int = 20,
|
||||
) : PagedMangaParser(context, source, pageSize) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
@@ -87,7 +88,7 @@ internal abstract class GalleryAdultsParser(
|
||||
|
||||
//Tags are deliberately reduced because there are too many and this slows down the application.
|
||||
//only the most popular ones are taken.
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return coroutineScope {
|
||||
(1..3).map { page ->
|
||||
async { getTags(page) }
|
||||
|
||||
@@ -20,7 +20,7 @@ internal abstract class HeanCms(
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.ALPHABETICAL,
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.NEWEST,
|
||||
@@ -159,7 +159,7 @@ internal abstract class HeanCms(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/comics").parseHtml()
|
||||
|
||||
val tags = doc.selectFirstOrThrow("script:containsData(Genres)").data()
|
||||
|
||||
@@ -20,7 +20,7 @@ internal abstract class HeanCmsAlt(
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
|
||||
protected open val listUrl = "/comics"
|
||||
protected open val datePattern = "MMMM d, yyyy"
|
||||
@@ -73,7 +73,7 @@ internal abstract class HeanCmsAlt(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
|
||||
protected open val selectDesc = "div.description-container"
|
||||
protected open val selectAlt = "div.series-alternative-names"
|
||||
|
||||
@@ -15,7 +15,7 @@ class DoujinDesuParser(context: MangaLoaderContext) : PagedMangaParser(context,
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("doujindesu.tv")
|
||||
|
||||
override val sortOrders: Set<SortOrder>
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.of(SortOrder.UPDATED, SortOrder.NEWEST, SortOrder.ALPHABETICAL, SortOrder.POPULARITY)
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga {
|
||||
@@ -125,7 +125,7 @@ class DoujinDesuParser(context: MangaLoaderContext) : PagedMangaParser(context,
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return webClient.httpGet("/genre/".toAbsoluteUrl(domain)).parseHtml()
|
||||
.requireElementById("taxonomy")
|
||||
.selectFirstOrThrow(".entries")
|
||||
|
||||
@@ -34,7 +34,7 @@ class NicovideoSeigaParser(context: MangaLoaderContext) :
|
||||
return body.selectFirst("#userinfo > div > div > strong")?.text() ?: throw AuthRequiredException(source)
|
||||
}
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.POPULARITY,
|
||||
)
|
||||
@@ -143,7 +143,7 @@ class NicovideoSeigaParser(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://${getDomain("seiga")}/manga/list").parseHtml()
|
||||
val root = doc.body().selectOrThrow("#mg_category_list > ul > li")
|
||||
return root.mapToSet { li ->
|
||||
|
||||
@@ -20,8 +20,10 @@ internal abstract class LikeMangaParser(
|
||||
pageSize: Int = 36,
|
||||
) : PagedMangaParser(context, source, pageSize) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST)
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
@@ -79,7 +81,7 @@ internal abstract class LikeMangaParser(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/genres/").parseHtml()
|
||||
return doc.select("ul.nav-genres li:not(.text-center) a").mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
|
||||
@@ -23,7 +23,9 @@ internal abstract class MadaraParser(
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val isMultipleTagsSupported = false
|
||||
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.NEWEST,
|
||||
@@ -245,7 +247,7 @@ internal abstract class MadaraParser(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||
val body = doc.body()
|
||||
val root1 = body.selectFirst("header")?.selectFirst("ul.second-menu")
|
||||
|
||||
@@ -5,9 +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.HashSet
|
||||
import java.util.Locale
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("MANGA18FX", "Manga18Fx", "", ContentType.HENTAI)
|
||||
internal class Manga18Fx(context: MangaLoaderContext) :
|
||||
@@ -15,7 +13,7 @@ internal class Manga18Fx(context: MangaLoaderContext) :
|
||||
|
||||
override val sourceLocale: Locale = Locale.ENGLISH
|
||||
override val datePattern = "dd MMM yy"
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val listUrl = ""
|
||||
override val selectTestAsync = "ul.row-content-chapter"
|
||||
override val selectDate = "span.chapter-time"
|
||||
@@ -79,7 +77,7 @@ internal class Manga18Fx(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): 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)
|
||||
|
||||
@@ -90,7 +90,7 @@ internal class Manhwa18Cc(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): 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)
|
||||
|
||||
@@ -17,7 +17,7 @@ internal class InstaManhwa(context: MangaLoaderContext) :
|
||||
override val postReq = true
|
||||
override val datePattern = "d MMMM, yyyy"
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.ALPHABETICAL,
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.NEWEST,
|
||||
|
||||
@@ -17,7 +17,7 @@ internal class IsekaiScan(context: MangaLoaderContext) :
|
||||
override val listUrl = "latest-manga/"
|
||||
override val datePattern = "MMMM d, HH:mm"
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.UPDATED,
|
||||
)
|
||||
|
||||
@@ -16,7 +16,7 @@ internal class MangaPure(context: MangaLoaderContext) :
|
||||
override val listUrl = "latest-manga/"
|
||||
override val datePattern = "MMMM d, HH:mm"
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.UPDATED,
|
||||
)
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.util.*
|
||||
internal class DragonTranslationParser(context: MangaLoaderContext) :
|
||||
MadaraParser(context, MangaSource.DRAGONTRANSLATION, "dragontranslation.net", 30) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
|
||||
override val selectPage = "div#chapter_imgs img"
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ internal class TmoManga(context: MangaLoaderContext) :
|
||||
searchPaginator.firstPage = 1
|
||||
}
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.POPULARITY)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.POPULARITY)
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
query: String?,
|
||||
|
||||
@@ -105,7 +105,7 @@ internal class ManhwaHub(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||
return doc.select("div.genres li").mapNotNullToSet { li ->
|
||||
val a = li.selectFirst("a") ?: return@mapNotNullToSet null
|
||||
|
||||
@@ -21,7 +21,7 @@ internal abstract class MadthemeParser(
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.ALPHABETICAL,
|
||||
@@ -115,7 +115,7 @@ internal abstract class MadthemeParser(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||
return doc.select("div.genres label.checkbox").mapNotNullToSet { checkbox ->
|
||||
val key = checkbox.selectFirstOrThrow("input").attr("value") ?: return@mapNotNullToSet null
|
||||
|
||||
@@ -20,7 +20,7 @@ internal abstract class Manga18Parser(
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.ALPHABETICAL,
|
||||
@@ -109,7 +109,7 @@ internal abstract class Manga18Parser(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): 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
|
||||
|
||||
@@ -34,5 +34,5 @@ internal class Hanman18(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet() // search by tag does not work
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet() // search by tag does not work
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ internal abstract class MangaboxParser(
|
||||
pageSize: Int = 24,
|
||||
) : PagedMangaParser(context, source, pageSize) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.NEWEST,
|
||||
@@ -107,7 +107,7 @@ internal abstract class MangaboxParser(
|
||||
|
||||
protected open val selectTagMap = "div.panel-genres-list a:not(.genres-select)"
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||
return doc.select(selectTagMap).mapNotNullToSet { a ->
|
||||
val key = a.attr("href").removeSuffix('/').substringAfterLast('/')
|
||||
|
||||
@@ -99,7 +99,7 @@ internal class Mangairo(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): 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("/")
|
||||
|
||||
@@ -73,7 +73,7 @@ internal class MangakakalotTv(context: MangaLoaderContext) :
|
||||
|
||||
override val selectTagMap = "ul.tag li a"
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||
return doc.select(selectTagMap).mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
|
||||
@@ -29,7 +29,7 @@ internal abstract class MangaReaderParser(
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
|
||||
override val sortOrders: Set<SortOrder>
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.ALPHABETICAL, SortOrder.NEWEST)
|
||||
|
||||
protected open val listUrl = "/manga"
|
||||
@@ -283,7 +283,7 @@ internal abstract class MangaReaderParser(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return getOrCreateTagMap().values.toSet()
|
||||
}
|
||||
|
||||
|
||||
@@ -75,7 +75,7 @@ internal class ManhwaFreak(context: MangaLoaderContext) :
|
||||
return parseMangaList(webClient.httpGet(url).parseHtml())
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/genres/").parseHtml()
|
||||
return doc.select("ul.genre-list li a").mapNotNullToSet { a ->
|
||||
val href = a.attr("href").substringAfterLast("=")
|
||||
|
||||
@@ -19,7 +19,7 @@ internal class RizzComic(context: MangaLoaderContext) :
|
||||
override val datePattern = "dd MMM yyyy"
|
||||
override val listUrl = "/series"
|
||||
|
||||
override val sortOrders: Set<SortOrder>
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
|
||||
override suspend fun getListPage(
|
||||
|
||||
@@ -21,7 +21,7 @@ internal class Zahard(context: MangaLoaderContext) :
|
||||
override val selectPage = "div#chapter_imgs img"
|
||||
|
||||
|
||||
override val sortOrders: Set<SortOrder>
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.of(SortOrder.NEWEST)
|
||||
|
||||
|
||||
|
||||
@@ -19,10 +19,10 @@ internal class TuManhwas(context: MangaLoaderContext) :
|
||||
override val selectPage = "div#readerarea img"
|
||||
|
||||
|
||||
override val sortOrders: Set<SortOrder>
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.of(SortOrder.NEWEST)
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getListPage(
|
||||
page: Int,
|
||||
query: String?,
|
||||
|
||||
@@ -77,7 +77,7 @@ internal class ManhwaFreakFr(context: MangaLoaderContext) :
|
||||
return parseMangaList(webClient.httpGet(url).parseHtml())
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/genres/").parseHtml()
|
||||
return doc.select("ul.genre-list li a").mapNotNullToSet { a ->
|
||||
val href = a.attr("href").substringAfterLast("=")
|
||||
|
||||
@@ -18,7 +18,7 @@ internal class Komikcast(context: MangaLoaderContext) :
|
||||
override val listUrl = "/daftar-komik"
|
||||
override val datePattern = "MMM d, yyyy"
|
||||
override val sourceLocale: Locale = Locale.ENGLISH
|
||||
override val sortOrders: Set<SortOrder>
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.ALPHABETICAL)
|
||||
|
||||
override suspend fun getListPage(
|
||||
|
||||
@@ -20,7 +20,7 @@ internal abstract class MmrcmsParser(
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.ALPHABETICAL,
|
||||
@@ -138,7 +138,7 @@ internal abstract class MmrcmsParser(
|
||||
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$tagUrl/").parseHtml()
|
||||
return doc.select("ul.list-category li").mapNotNullToSet { li ->
|
||||
val a = li.selectFirst("a") ?: return@mapNotNullToSet null
|
||||
|
||||
@@ -22,7 +22,7 @@ internal class Animaregia(context: MangaLoaderContext) :
|
||||
override val sourceLocale: Locale = Locale.ENGLISH
|
||||
|
||||
//temporary
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.ALPHABETICAL,
|
||||
)
|
||||
|
||||
@@ -23,7 +23,7 @@ internal abstract class NepnepParser(
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
|
||||
override val headers: Headers = Headers.Builder()
|
||||
.add("User-Agent", UserAgents.CHROME_DESKTOP)
|
||||
@@ -104,7 +104,7 @@ internal abstract class NepnepParser(
|
||||
)
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/search/").parseHtml()
|
||||
val tags = doc.selectFirstOrThrow("script:containsData(vm.AvailableFilters)").data()
|
||||
.substringAfter("\"Genre\"")
|
||||
|
||||
@@ -20,7 +20,7 @@ internal abstract class OtakuSanctuaryParser(
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.NEWEST,
|
||||
)
|
||||
@@ -114,7 +114,7 @@ internal abstract class OtakuSanctuaryParser(
|
||||
|
||||
protected open val selectBodyTag = "div#genre-table a"
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/Home/LoadingGenresMenu").parseHtml()
|
||||
return doc.select(selectBodyTag).mapNotNullToSet { a ->
|
||||
val href = a.attr("href").substringAfterLast("/").substringBefore("?")
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.*
|
||||
@MangaSourceParser("BAKAI", "Bakai", "pt", ContentType.HENTAI)
|
||||
internal class Bakai(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.BAKAI, 15) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val configKeyDomain = ConfigKey.Domain("bakai.org")
|
||||
override val headers: Headers = Headers.Builder()
|
||||
.add("User-Agent", UserAgents.CHROME_MOBILE)
|
||||
@@ -89,7 +89,7 @@ internal class Bakai(context: MangaLoaderContext) : PagedMangaParser(context, Ma
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||
return doc.requireElementById("elNavigation_17_menu").select("li.ipsMenu_item a").mapNotNullToSet { a ->
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.*
|
||||
@MangaSourceParser("BRMANGAS", "BrMangas", "pt")
|
||||
internal class BrMangas(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.BRMANGAS, 25) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.POPULARITY, SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.POPULARITY, SortOrder.UPDATED)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("www.brmangas.net")
|
||||
|
||||
@@ -81,7 +81,7 @@ internal class BrMangas(context: MangaLoaderContext) : PagedMangaParser(context,
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/lista-de-generos-de-manga/").parseHtml()
|
||||
return doc.select(".genres_page a").mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.util.*
|
||||
@MangaSourceParser("LERMANGAONLINE", "LerMangaOnline", "pt")
|
||||
class LerMangaOnline(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.LERMANGAONLINE, 20) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("lermangaonline.com.br")
|
||||
|
||||
@@ -67,7 +67,7 @@ class LerMangaOnline(context: MangaLoaderContext) : PagedMangaParser(context, Ma
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/").parseHtml().requireElementById("sub-menu")
|
||||
return doc.select("ul.container li a").mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.*
|
||||
@MangaSourceParser("MANGAONLINE", "MangaOnline.biz", "pt")
|
||||
class MangaOnline(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.MANGAONLINE, 20) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("mangaonline.biz")
|
||||
|
||||
@@ -71,7 +71,7 @@ class MangaOnline(context: MangaLoaderContext) : PagedMangaParser(context, Manga
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/generos/").parseHtml()
|
||||
return doc.select(".wp-content p a").mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.*
|
||||
@MangaSourceParser("YUGENMANGAS", "YugenMangas.org", "pt")
|
||||
class YugenMangas(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.YUGENMANGAS, 28) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL, SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL, SortOrder.UPDATED)
|
||||
override val configKeyDomain = ConfigKey.Domain("yugenmangas.org")
|
||||
|
||||
override suspend fun getListPage(
|
||||
@@ -142,5 +142,5 @@ class YugenMangas(context: MangaLoaderContext) : PagedMangaParser(context, Manga
|
||||
return pages
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ internal class DesuMeParser(context: MangaLoaderContext) : PagedMangaParser(cont
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("desu.me", "desu.win")
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.NEWEST,
|
||||
@@ -148,7 +148,7 @@ internal class DesuMeParser(context: MangaLoaderContext) : PagedMangaParser(cont
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return tagsCache.get().values.toSet()
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ internal class NudeMoonParser(
|
||||
}
|
||||
}
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.NEWEST,
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.RATING,
|
||||
@@ -144,7 +144,7 @@ internal class NudeMoonParser(
|
||||
return page.url.toAbsoluteUrl("img.$domain")
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val domain = domain
|
||||
val doc = webClient.httpGet("https://$domain/tags").parseHtml()
|
||||
val root = doc.body().getElementsByAttributeValue("name", "multitags").first()
|
||||
|
||||
@@ -47,7 +47,7 @@ internal class RemangaParser(
|
||||
override val authUrl: String
|
||||
get() = "https://${domain}/user/login"
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.RATING,
|
||||
@@ -221,7 +221,7 @@ internal class RemangaParser(
|
||||
return result
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val domain = domain
|
||||
val content = webClient.httpGet("https://api.$domain/api/forms/titles/?get=genres")
|
||||
.parseJson().getJSONObject("content").getJSONArray("genres")
|
||||
|
||||
@@ -46,7 +46,7 @@ internal abstract class GroupleParser(
|
||||
|
||||
override val headers: Headers = Headers.Builder().add("User-Agent", config[userAgentKey]).build()
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.NEWEST,
|
||||
@@ -218,7 +218,7 @@ internal abstract class GroupleParser(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://${domain}/list/genres/sort_name").parseHtml()
|
||||
val root = doc.body().getElementById("mangaBox")?.selectFirst("div.leftContent")?.selectFirst("table.table")
|
||||
?: doc.parseFailed("Cannot find root")
|
||||
|
||||
@@ -15,7 +15,7 @@ internal abstract class ChanParser(
|
||||
source: MangaSource,
|
||||
) : MangaParser(context, source), MangaParserAuthProvider {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.NEWEST,
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.ALPHABETICAL,
|
||||
@@ -126,7 +126,7 @@ internal abstract class ChanParser(
|
||||
doc.parseFailed("Pages list not found at ${chapter.url}")
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val domain = domain
|
||||
val doc = webClient.httpGet("https://$domain/mostfavorites&sort=manga").parseHtml()
|
||||
val root = doc.body().selectFirst("div.main_fon")?.getElementById("side")
|
||||
|
||||
@@ -21,7 +21,7 @@ internal class HenChanParser(context: MangaLoaderContext) : ChanParser(context,
|
||||
"hentaichan.pro",
|
||||
)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.NEWEST,
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.RATING,
|
||||
|
||||
@@ -17,7 +17,7 @@ internal class YaoiChanParser(context: MangaLoaderContext) : ChanParser(context,
|
||||
"yaoi-chan.me",
|
||||
)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = setOf(SortOrder.NEWEST)
|
||||
override val availableSortOrders: Set<SortOrder> = setOf(SortOrder.NEWEST)
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga {
|
||||
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||
|
||||
@@ -32,7 +32,7 @@ internal open class MangaLibParser(
|
||||
override val authUrl: String
|
||||
get() = "https://$domain/login"
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.RATING,
|
||||
SortOrder.ALPHABETICAL,
|
||||
SortOrder.POPULARITY,
|
||||
@@ -232,7 +232,7 @@ internal open class MangaLibParser(
|
||||
} ?: concatUrl(defaultServer, pageUrl)
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val url = "https://$domain/manga-list"
|
||||
val doc = webClient.httpGet(url).parseHtml()
|
||||
val scripts = doc.body().select("script")
|
||||
|
||||
@@ -18,7 +18,7 @@ internal abstract class SinmhParser(
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.POPULARITY,
|
||||
)
|
||||
@@ -101,7 +101,7 @@ internal abstract class SinmhParser(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/$listUrl").parseHtml()
|
||||
return doc.select(".filter-item:contains(按剧情) li a:not(.active)").mapNotNullToSet { a ->
|
||||
val href = a.attr("href").removeSuffix('/').substringAfterLast('/')
|
||||
|
||||
@@ -15,7 +15,7 @@ import java.util.*
|
||||
@MangaSourceParser("MANGAAY", "MangaAy", "tr")
|
||||
class MangaAy(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.MANGAAY, 45) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("manga-ay.com")
|
||||
|
||||
@@ -93,7 +93,7 @@ class MangaAy(context: MangaLoaderContext) : PagedMangaParser(context, MangaSour
|
||||
private var tagCache: ArrayMap<String, MangaTag>? = null
|
||||
private val mutex = Mutex()
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return getOrCreateTagMap().values.toSet()
|
||||
}
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.*
|
||||
@MangaSourceParser("SADSCANS", "SadScans", "tr")
|
||||
internal class SadScans(context: MangaLoaderContext) : MangaParser(context, MangaSource.SADSCANS) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
override val configKeyDomain = ConfigKey.Domain("sadscans.com")
|
||||
|
||||
override suspend fun getList(offset: Int, query: String?, tags: Set<MangaTag>?, sortOrder: SortOrder): List<Manga> {
|
||||
@@ -46,7 +46,7 @@ internal class SadScans(context: MangaLoaderContext) : MangaParser(context, Mang
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> = emptySet()
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> = emptySet()
|
||||
|
||||
override suspend fun getDetails(manga: Manga): Manga {
|
||||
val doc = webClient.httpGet(manga.url.toAbsoluteUrl(domain)).parseHtml()
|
||||
|
||||
@@ -16,7 +16,7 @@ class TrWebtoon(context: MangaLoaderContext) :
|
||||
|
||||
override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("trwebtoon.com")
|
||||
|
||||
override val sortOrders: Set<SortOrder>
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.of(SortOrder.POPULARITY, SortOrder.ALPHABETICAL, SortOrder.UPDATED)
|
||||
|
||||
override suspend fun getListPage(
|
||||
@@ -112,7 +112,7 @@ class TrWebtoon(context: MangaLoaderContext) :
|
||||
return mangas
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val tags =
|
||||
webClient.httpGet("https://$domain/webtoon-listesi").parseHtml().requireElementById("collapseExample")
|
||||
.select(".pt-12 a").drop(1)
|
||||
|
||||
@@ -12,7 +12,7 @@ import java.util.*
|
||||
@MangaSourceParser("YAOIFLIX", "YaoiFlix", "tr", ContentType.HENTAI)
|
||||
class YaoiFlix(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.YAOIFLIX, 8) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("www.yaoiflix.pro")
|
||||
|
||||
@@ -79,7 +79,7 @@ class YaoiFlix(context: MangaLoaderContext) : PagedMangaParser(context, MangaSou
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain").parseHtml()
|
||||
return doc.select(".tags .cat-item a").mapNotNullToSet { a ->
|
||||
MangaTag(
|
||||
|
||||
@@ -33,7 +33,7 @@ class HentaiUkrParser(context: MangaLoaderContext) : MangaParser(context, MangaS
|
||||
|
||||
override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("hentaiukr.com")
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.NEWEST,
|
||||
)
|
||||
|
||||
@@ -119,7 +119,7 @@ class HentaiUkrParser(context: MangaLoaderContext) : MangaParser(context, MangaS
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return allManga.get().flatMapTo(HashSet()) { x ->
|
||||
x.getJSONArray("tags").mapJSON { t ->
|
||||
MangaTag(
|
||||
|
||||
@@ -37,7 +37,7 @@ class HoneyMangaParser(context: MangaLoaderContext) : PagedMangaParser(context,
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("honey-manga.com.ua")
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.NEWEST,
|
||||
)
|
||||
@@ -166,7 +166,7 @@ class HoneyMangaParser(context: MangaLoaderContext) : PagedMangaParser(context,
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
// https://data.api.honey-manga.com.ua/genres-tags/genres-list
|
||||
val content = webClient.httpGet(genresListApi).parseJsonArray()
|
||||
val tagsSet = ArraySet<MangaTag>(content.length())
|
||||
|
||||
@@ -19,7 +19,7 @@ class MangaInUaParser(context: MangaLoaderContext) : PagedMangaParser(
|
||||
searchPageSize = 10,
|
||||
) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = setOf(SortOrder.UPDATED)
|
||||
override val availableSortOrders: Set<SortOrder> = setOf(SortOrder.UPDATED)
|
||||
|
||||
override val configKeyDomain: ConfigKey.Domain = ConfigKey.Domain("manga.in.ua")
|
||||
|
||||
@@ -151,7 +151,7 @@ class MangaInUaParser(context: MangaLoaderContext) : PagedMangaParser(
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val domain = domain
|
||||
val doc = webClient.httpGet("https://$domain/mangas").parseHtml()
|
||||
val root = doc.body().requireElementById("menu_1").selectFirstOrThrow("div.menu__wrapper")
|
||||
|
||||
@@ -22,7 +22,7 @@ class BlogTruyenParser(context: MangaLoaderContext) :
|
||||
override val configKeyDomain: ConfigKey.Domain
|
||||
get() = ConfigKey.Domain("blogtruyenmoi.com")
|
||||
|
||||
override val sortOrders: Set<SortOrder>
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.of(SortOrder.UPDATED)
|
||||
|
||||
override val headers: Headers = Headers.Builder()
|
||||
@@ -219,7 +219,7 @@ class BlogTruyenParser(context: MangaLoaderContext) :
|
||||
return pages
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return cacheTags.get().values.toSet()
|
||||
}
|
||||
|
||||
|
||||
@@ -28,7 +28,7 @@ class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaSo
|
||||
// hentaivn has created 2 different interfaces for mobile and desktop, and Cloudflare detects whether it's mobile or not even with a desktop user agent.
|
||||
override val headers: Headers = Headers.Builder().add("User-Agent", UserAgents.CHROME_MOBILE).build()
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.POPULARITY,
|
||||
SortOrder.RATING,
|
||||
@@ -137,7 +137,7 @@ class HentaiVNParser(context: MangaLoaderContext) : MangaParser(context, MangaSo
|
||||
private var tagCache: ArrayMap<String, MangaTag>? = null
|
||||
private val mutex = Mutex()
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
return getOrCreateTagMap().values.toSet()
|
||||
}
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.util.*
|
||||
@MangaSourceParser("LXMANGA", "LxManga", "vi")
|
||||
internal class LxManga(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.LXMANGA, 60) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(
|
||||
SortOrder.ALPHABETICAL,
|
||||
SortOrder.UPDATED,
|
||||
SortOrder.NEWEST,
|
||||
@@ -150,7 +150,7 @@ internal class LxManga(context: MangaLoaderContext) : PagedMangaParser(context,
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/").parseHtml()
|
||||
val body = doc.body()
|
||||
return body.select("ul.absolute.w-full a").mapToSet { a ->
|
||||
|
||||
@@ -26,7 +26,7 @@ class NetTruyenParser(context: MangaLoaderContext) :
|
||||
"nettruyenin.com",
|
||||
)
|
||||
|
||||
override val sortOrders: Set<SortOrder>
|
||||
override val availableSortOrders: Set<SortOrder>
|
||||
get() = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST, SortOrder.RATING)
|
||||
|
||||
private val mutex = Mutex()
|
||||
@@ -194,7 +194,7 @@ class NetTruyenParser(context: MangaLoaderContext) :
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val map = getOrCreateTagMap()
|
||||
val tagSet = ArraySet<MangaTag>(map.size)
|
||||
for (entry in map) {
|
||||
|
||||
@@ -12,7 +12,8 @@ import java.util.*
|
||||
@MangaSourceParser("TRUYENQQ", "Truyenqq", "vi")
|
||||
internal class Truyenqq(context: MangaLoaderContext) : PagedMangaParser(context, MangaSource.TRUYENQQ, 42) {
|
||||
|
||||
override val sortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST)
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.NEWEST)
|
||||
override val configKeyDomain = ConfigKey.Domain("truyenqqvn.com")
|
||||
|
||||
override suspend fun getListPage(
|
||||
@@ -67,7 +68,7 @@ internal class Truyenqq(context: MangaLoaderContext) : PagedMangaParser(context,
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun getTags(): Set<MangaTag> {
|
||||
override suspend fun getAvailableTags(): Set<MangaTag> {
|
||||
val doc = webClient.httpGet("https://$domain/tim-kiem-nang-cao.html").parseHtml()
|
||||
return doc.select(".advsearch-form div.genre-item").mapNotNullToSet {
|
||||
MangaTag(
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user