Improve filtering
This commit is contained in:
@@ -47,6 +47,11 @@ abstract class MangaParser @InternalParsersApi constructor(
|
||||
*/
|
||||
open val isTagsExclusionSupported: Boolean = false
|
||||
|
||||
/**
|
||||
* Whether parser supports searching by string query using [MangaListFilter.Search]
|
||||
*/
|
||||
open val isSearchSupported: Boolean = true
|
||||
|
||||
@Deprecated(
|
||||
message = "Use availableSortOrders instead",
|
||||
replaceWith = ReplaceWith("availableSortOrders"),
|
||||
@@ -149,21 +154,42 @@ abstract class MangaParser @InternalParsersApi constructor(
|
||||
return getList(
|
||||
offset,
|
||||
MangaListFilter.Advanced(
|
||||
sortOrder ?: defaultSortOrder,
|
||||
tags.orEmpty(),
|
||||
tagsExclude.orEmpty(),
|
||||
null,
|
||||
emptySet(),
|
||||
emptySet(),
|
||||
sortOrder = sortOrder ?: defaultSortOrder,
|
||||
tags = tags.orEmpty(),
|
||||
tagsExclude = tagsExclude.orEmpty(),
|
||||
locale = null,
|
||||
states = emptySet(),
|
||||
contentRating = emptySet(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
||||
@Suppress("DEPRECATION")
|
||||
open suspend fun getList(offset: Int, filter: MangaListFilter?): List<Manga> {
|
||||
return when (filter) {
|
||||
is MangaListFilter.Advanced -> getList(offset, null, filter.tags, filter.tagsExclude, filter.sortOrder)
|
||||
is MangaListFilter.Search -> getList(offset, filter.query, null, null, defaultSortOrder)
|
||||
null -> getList(offset, null, null, null, defaultSortOrder)
|
||||
is MangaListFilter.Advanced -> getList(
|
||||
offset = offset,
|
||||
query = null,
|
||||
tags = filter.tags,
|
||||
tagsExclude = filter.tagsExclude,
|
||||
sortOrder = filter.sortOrder,
|
||||
)
|
||||
|
||||
is MangaListFilter.Search -> getList(
|
||||
offset = offset,
|
||||
query = filter.query,
|
||||
tags = null,
|
||||
tagsExclude = null,
|
||||
sortOrder = defaultSortOrder,
|
||||
)
|
||||
|
||||
null -> getList(
|
||||
offset = offset,
|
||||
query = null,
|
||||
tags = null,
|
||||
tagsExclude = null,
|
||||
sortOrder = defaultSortOrder,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -50,9 +50,29 @@ abstract class PagedMangaParser(
|
||||
|
||||
open suspend fun getListPage(page: Int, filter: MangaListFilter?): List<Manga> {
|
||||
return when (filter) {
|
||||
is MangaListFilter.Advanced -> getListPage(page, null, filter.tags, filter.tagsExclude, filter.sortOrder)
|
||||
is MangaListFilter.Search -> getListPage(page, filter.query, null, null, defaultSortOrder)
|
||||
null -> getListPage(page, null, null, null, defaultSortOrder)
|
||||
is MangaListFilter.Advanced -> getListPage(
|
||||
page = page,
|
||||
query = null,
|
||||
tags = filter.tags,
|
||||
tagsExclude = filter.tagsExclude,
|
||||
sortOrder = filter.sortOrder,
|
||||
)
|
||||
|
||||
is MangaListFilter.Search -> getListPage(
|
||||
page = page,
|
||||
query = filter.query,
|
||||
tags = null,
|
||||
tagsExclude = null,
|
||||
sortOrder = defaultSortOrder,
|
||||
)
|
||||
|
||||
null -> getListPage(
|
||||
page = page,
|
||||
query = null,
|
||||
tags = null,
|
||||
tagsExclude = null,
|
||||
sortOrder = defaultSortOrder,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.koitharu.kotatsu.parsers.model
|
||||
|
||||
import org.koitharu.kotatsu.parsers.MangaParser
|
||||
import java.util.*
|
||||
|
||||
sealed interface MangaListFilter {
|
||||
@@ -8,6 +9,16 @@ sealed interface MangaListFilter {
|
||||
|
||||
val sortOrder: SortOrder?
|
||||
|
||||
fun isValid(parser: MangaParser): Boolean = when (this) {
|
||||
is Advanced -> (sortOrder in parser.availableSortOrders) &&
|
||||
(tags.size <= 1 || parser.isMultipleTagsSupported) &&
|
||||
(tagsExclude.isEmpty() || parser.isTagsExclusionSupported) &&
|
||||
(contentRating.isEmpty() || parser.availableContentRating.containsAll(contentRating)) &&
|
||||
(states.isEmpty() || parser.availableStates.containsAll(states))
|
||||
|
||||
is Search -> parser.isSearchSupported
|
||||
}
|
||||
|
||||
data class Search(
|
||||
@JvmField val query: String,
|
||||
) : MangaListFilter {
|
||||
@@ -26,6 +37,57 @@ sealed interface MangaListFilter {
|
||||
@JvmField val contentRating: Set<ContentRating>,
|
||||
) : MangaListFilter {
|
||||
|
||||
override fun isEmpty(): Boolean = tags.isEmpty() && tagsExclude.isEmpty() && locale == null && states.isEmpty() && contentRating.isEmpty()
|
||||
override fun isEmpty(): Boolean =
|
||||
tags.isEmpty() && tagsExclude.isEmpty() && locale == null && states.isEmpty() && contentRating.isEmpty()
|
||||
|
||||
fun newBuilder() = Builder(sortOrder)
|
||||
.tags(tags)
|
||||
.tagsExclude(tagsExclude)
|
||||
.locale(locale)
|
||||
.states(states)
|
||||
.contentRatings(contentRating)
|
||||
|
||||
class Builder(sortOrder: SortOrder) {
|
||||
|
||||
private var _sortOrder: SortOrder = sortOrder
|
||||
private var _tags: Set<MangaTag>? = null
|
||||
private var _tagsExclude: Set<MangaTag>? = null
|
||||
private var _locale: Locale? = null
|
||||
private var _states: Set<MangaState>? = null
|
||||
private var _contentRating: Set<ContentRating>? = null
|
||||
|
||||
fun sortOrder(order: SortOrder) = apply {
|
||||
_sortOrder = order
|
||||
}
|
||||
|
||||
fun tags(tags: Set<MangaTag>?) = apply {
|
||||
_tags = tags
|
||||
}
|
||||
|
||||
fun tagsExclude(tags: Set<MangaTag>?) = apply {
|
||||
_tagsExclude = tags
|
||||
}
|
||||
|
||||
fun locale(locale: Locale?) = apply {
|
||||
_locale = locale
|
||||
}
|
||||
|
||||
fun states(states: Set<MangaState>?) = apply {
|
||||
_states = states
|
||||
}
|
||||
|
||||
fun contentRatings(rating: Set<ContentRating>?) = apply {
|
||||
_contentRating = rating
|
||||
}
|
||||
|
||||
fun build() = Advanced(
|
||||
sortOrder = _sortOrder,
|
||||
tags = _tags.orEmpty(),
|
||||
tagsExclude = _tagsExclude.orEmpty(),
|
||||
locale = _locale,
|
||||
states = _states.orEmpty(),
|
||||
contentRating = _contentRating.orEmpty(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,30 +9,14 @@ import org.koitharu.kotatsu.parsers.MangaLoaderContext
|
||||
import org.koitharu.kotatsu.parsers.MangaSourceParser
|
||||
import org.koitharu.kotatsu.parsers.PagedMangaParser
|
||||
import org.koitharu.kotatsu.parsers.config.ConfigKey
|
||||
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.MangaListFilter
|
||||
import org.koitharu.kotatsu.parsers.model.MangaPage
|
||||
import org.koitharu.kotatsu.parsers.model.MangaSource
|
||||
import org.koitharu.kotatsu.parsers.model.MangaTag
|
||||
import org.koitharu.kotatsu.parsers.model.RATING_UNKNOWN
|
||||
import org.koitharu.kotatsu.parsers.model.SortOrder
|
||||
import org.koitharu.kotatsu.parsers.util.SuspendLazy
|
||||
import org.koitharu.kotatsu.parsers.util.domain
|
||||
import org.koitharu.kotatsu.parsers.util.generateUid
|
||||
import org.koitharu.kotatsu.parsers.model.*
|
||||
import org.koitharu.kotatsu.parsers.util.*
|
||||
import org.koitharu.kotatsu.parsers.util.json.getStringOrNull
|
||||
import org.koitharu.kotatsu.parsers.util.json.mapJSON
|
||||
import org.koitharu.kotatsu.parsers.util.json.mapJSONToSet
|
||||
import org.koitharu.kotatsu.parsers.util.json.toJSONList
|
||||
import org.koitharu.kotatsu.parsers.util.mapToSet
|
||||
import org.koitharu.kotatsu.parsers.util.oneOrThrowIfMany
|
||||
import org.koitharu.kotatsu.parsers.util.parseHtml
|
||||
import org.koitharu.kotatsu.parsers.util.toAbsoluteUrl
|
||||
import org.koitharu.kotatsu.parsers.util.toCamelCase
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.EnumSet
|
||||
import java.util.Locale
|
||||
import java.util.*
|
||||
|
||||
@MangaSourceParser("NINENINENINEHENTAI", "999Hentai", type = ContentType.HENTAI)
|
||||
internal class NineNineNineHentaiParser(context: MangaLoaderContext) :
|
||||
|
||||
@@ -19,6 +19,7 @@ internal class FlixScansOrg(context: MangaLoaderContext) : PagedMangaParser(cont
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
override val availableStates: Set<MangaState> = EnumSet.allOf(MangaState::class.java)
|
||||
override val configKeyDomain = ConfigKey.Domain("flixscans.org")
|
||||
override val isSearchSupported = false
|
||||
|
||||
override suspend fun getListPage(page: Int, filter: MangaListFilter?): List<Manga> {
|
||||
|
||||
|
||||
@@ -22,6 +22,8 @@ internal class ReaperComics(context: MangaLoaderContext) :
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("reaperscans.com")
|
||||
|
||||
override val isSearchSupported = false
|
||||
|
||||
override val headers: Headers = Headers.Builder()
|
||||
.add("User-Agent", UserAgents.CHROME_DESKTOP)
|
||||
.build()
|
||||
|
||||
@@ -21,6 +21,8 @@ internal class TempleScanEsp(context: MangaLoaderContext) :
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("templescanesp.net")
|
||||
|
||||
override val isSearchSupported = false
|
||||
|
||||
override val headers: Headers = Headers.Builder()
|
||||
.add("User-Agent", UserAgents.CHROME_DESKTOP)
|
||||
.build()
|
||||
|
||||
@@ -23,6 +23,8 @@ internal class FuryoSociety(context: MangaLoaderContext) :
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("furyosociety.com")
|
||||
|
||||
override val isSearchSupported = false
|
||||
|
||||
override val headers: Headers = Headers.Builder()
|
||||
.add("User-Agent", UserAgents.CHROME_DESKTOP)
|
||||
.build()
|
||||
|
||||
@@ -25,6 +25,8 @@ internal class LugnicaScans(context: MangaLoaderContext) : PagedMangaParser(cont
|
||||
override val availableStates: Set<MangaState> =
|
||||
EnumSet.of(MangaState.ONGOING, MangaState.FINISHED, MangaState.PAUSED, MangaState.ABANDONED)
|
||||
|
||||
override val isSearchSupported = false
|
||||
|
||||
override val configKeyDomain = ConfigKey.Domain("lugnica-scans.com")
|
||||
|
||||
override val headers: Headers = Headers.Builder()
|
||||
|
||||
@@ -23,6 +23,8 @@ internal abstract class HeanCmsAlt(
|
||||
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.UPDATED)
|
||||
|
||||
override val isSearchSupported = false
|
||||
|
||||
protected open val listUrl = "/comics"
|
||||
protected open val datePattern = "MMMM d, yyyy"
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ internal class RizzComic(context: MangaLoaderContext) :
|
||||
override val availableSortOrders: Set<SortOrder> = EnumSet.of(SortOrder.ALPHABETICAL)
|
||||
override val availableStates: Set<MangaState> = emptySet()
|
||||
override val isMultipleTagsSupported = false
|
||||
override val isSearchSupported = false
|
||||
|
||||
// TODO Query created in json
|
||||
override suspend fun getListPage(page: Int, filter: MangaListFilter?): List<Manga> {
|
||||
|
||||
@@ -25,6 +25,7 @@ class LerManga(context: MangaLoaderContext) : PagedMangaParser(context, MangaSou
|
||||
override val configKeyDomain = ConfigKey.Domain("lermanga.org")
|
||||
|
||||
override val isMultipleTagsSupported = false
|
||||
override val isSearchSupported = false
|
||||
|
||||
override suspend fun getListPage(page: Int, filter: MangaListFilter?): List<Manga> {
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ internal abstract class ScanParser(
|
||||
|
||||
override val availableSortOrders: Set<SortOrder> =
|
||||
EnumSet.of(SortOrder.ALPHABETICAL, SortOrder.UPDATED, SortOrder.POPULARITY, SortOrder.RATING)
|
||||
|
||||
override val isSearchSupported = false
|
||||
override val configKeyDomain = ConfigKey.Domain(domain)
|
||||
|
||||
override suspend fun getListPage(page: Int, filter: MangaListFilter?): List<Manga> {
|
||||
|
||||
Reference in New Issue
Block a user