Pixiv: support partial tag matches (#17330)

This commit is contained in:
Solitai7e 2023-07-31 17:38:05 +00:00 committed by GitHub
parent 37a4b20ef2
commit 31ae3fc43a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 61 additions and 72 deletions

View File

@ -6,7 +6,7 @@ ext {
extName = 'Pixiv' extName = 'Pixiv'
pkgNameSuffix = 'all.pixiv' pkgNameSuffix = 'all.pixiv'
extClass = '.PixivFactory' extClass = '.PixivFactory'
extVersionCode = 6 extVersionCode = 7
isNsfw = true isNsfw = true
} }

View File

@ -97,37 +97,37 @@ class Pixiv(override val lang: String) : HttpSource() {
if (query.isNotBlank()) { if (query.isNotBlank()) {
searchSequence = makeIllustSearchSequence( searchSequence = makeIllustSearchSequence(
word = query, word = query,
order = filters.order.toSearchParameter(), order = filters.order,
mode = filters.rating.toSearchParameter(), mode = filters.rating,
sMode = "s_tc", sMode = "s_tc",
type = filters.type.toSearchParameter(), type = filters.type,
dateBefore = filters.dateBefore.state.ifBlank { null }, dateBefore = filters.dateBefore.ifBlank { null },
dateAfter = filters.dateAfter.state.ifBlank { null }, dateAfter = filters.dateAfter.ifBlank { null },
) )
predicates = buildList { predicates = buildList {
filters.tags.toPredicate()?.let(::add) filters.makeTagsPredicate()?.let(::add)
filters.users.toPredicate()?.let(::add) filters.makeUsersPredicate()?.let(::add)
} }
} else if (filters.users.state.isNotBlank()) { } else if (filters.users.isNotBlank()) {
searchSequence = makeUserIllustSearchSequence( searchSequence = makeUserIllustSearchSequence(
nick = filters.users.state, nick = filters.users,
type = filters.type.toSearchParameter(), type = filters.type,
) )
predicates = buildList { predicates = buildList {
filters.tags.toPredicate()?.let(::add) filters.makeTagsPredicate()?.let(::add)
filters.rating.toPredicate()?.let(::add) filters.makeRatingPredicate()?.let(::add)
} }
} else { } else {
searchSequence = makeIllustSearchSequence( searchSequence = makeIllustSearchSequence(
word = filters.tags.state.ifBlank { "漫画" }, word = filters.tags.ifBlank { "漫画" },
order = filters.order.toSearchParameter(), order = filters.order,
mode = filters.rating.toSearchParameter(), mode = filters.rating,
sMode = "s_tag_full", sMode = filters.searchMode,
type = filters.type.toSearchParameter(), type = filters.type,
dateBefore = filters.dateBefore.state.ifBlank { null }, dateBefore = filters.dateBefore.ifBlank { null },
dateAfter = filters.dateAfter.state.ifBlank { null }, dateAfter = filters.dateAfter.ifBlank { null },
) )
predicates = emptyList() predicates = emptyList()

View File

@ -1,72 +1,61 @@
package eu.kanade.tachiyomi.extension.all.pixiv package eu.kanade.tachiyomi.extension.all.pixiv
import eu.kanade.tachiyomi.source.model.Filter import eu.kanade.tachiyomi.source.model.Filter
private val TYPE_VALUES = arrayOf("All", "Illustrations", "Manga")
private val TYPE_PARAMS = arrayOf(null, "illust", "manga")
private val TAGS_MODE_VALUES = arrayOf("Partial", "Full")
private val TAGS_MODE_PARAMS = arrayOf("s_tag", "s_tag_full")
private val RATING_VALUES = arrayOf("All", "All ages", "R-18")
private val RATING_PARAMS = arrayOf(null, "all", "r18")
private val RATING_PREDICATES: Array<((PixivIllust) -> Boolean)?> =
arrayOf(null, { it.x_restrict == "0" }, { it.x_restrict == "1" })
internal class PixivFilters : MutableList<Filter<*>> by mutableListOf() { internal class PixivFilters : MutableList<Filter<*>> by mutableListOf() {
class Type : Filter.Select<String>("Type", values, 2) { private val typeFilter = object : Filter.Select<String>("Type", TYPE_VALUES, 2) {}.also(::add)
companion object { private val tagsFilter = object : Filter.Text("Tags") {}.also(::add)
private val values: Array<String> = private val tagsModeFilter = object : Filter.Select<String>("Tags mode", TAGS_MODE_VALUES, 0) {}.also(::add)
arrayOf("All", "Illustrations", "Manga") private val usersFilter = object : Filter.Text("Users") {}.also(::add)
private val ratingFilter = object : Filter.Select<String>("Rating", RATING_VALUES, 0) {}.also(::add)
private val searchParams: Array<String?> = init { add(Filter.Header("(the following are ignored when the users filter is in use)")) }
arrayOf(null, "illust", "manga")
}
fun toSearchParameter(): String? = searchParams[state] private val orderFilter = object : Filter.Sort("Order", arrayOf("Date posted")) {}.also(::add)
} private val dateBeforeFilter = object : Filter.Text("Posted before") {}.also(::add)
private val dateAfterFilter = object : Filter.Text("Posted after") {}.also(::add)
val type = Type().also(::add) val type: String? get() = TYPE_PARAMS[typeFilter.state]
class Tags : Filter.Text("Tags") { val tags: String by tagsFilter::state
fun toPredicate(): ((PixivIllust) -> Boolean)? { val searchMode: String get() = TAGS_MODE_PARAMS[tagsModeFilter.state]
if (state.isBlank()) return null
val tags = state.split(' ') fun makeTagsPredicate(): ((PixivIllust) -> Boolean)? {
val tags = tags.ifBlank { return null }.split(' ')
if (tagsModeFilter.state == 0) {
val regex = Regex(tags.joinToString("|") { Regex.escape(it) })
return { it.tags?.any(regex::containsMatchIn) == true }
} else {
return { it.tags?.containsAll(tags) == true } return { it.tags?.containsAll(tags) == true }
} }
} }
val tags = Tags().also(::add) val users: String by usersFilter::state
class Users : Filter.Text("Users") { fun makeUsersPredicate(): ((PixivIllust) -> Boolean)? {
fun toPredicate(): ((PixivIllust) -> Boolean)? { val users = users.ifBlank { return null }
if (state.isBlank()) return null val regex = Regex(users.split(' ').joinToString("|") { Regex.escape(it) })
val regex = Regex(state.split(' ').joinToString("|") { Regex.escape(it) })
return { it.author_details?.user_name?.contains(regex) == true } return { it.author_details?.user_name?.contains(regex) == true }
} }
}
val users = Users().also(::add) val rating: String? get() = RATING_PARAMS[ratingFilter.state]
fun makeRatingPredicate() = RATING_PREDICATES[ratingFilter.state]
class Rating : Filter.Select<String>("Rating", values, 0) { val order: String? get() = orderFilter.state?.ascending?.let { "date" }
companion object {
private val searchParams: Array<String?> =
arrayOf(null, "all", "r18")
private val values: Array<String> = val dateBefore: String by dateBeforeFilter::state
arrayOf("All", "All ages", "R-18") val dateAfter: String by dateAfterFilter::state
private val predicates: Array<((PixivIllust) -> Boolean)?> =
arrayOf(null, { it.x_restrict == "0" }, { it.x_restrict == "1" })
}
fun toPredicate(): ((PixivIllust) -> Boolean)? = predicates[state]
fun toSearchParameter(): String? = searchParams[state]
}
val rating = Rating().also(::add)
init { add(Filter.Header("(the following are ignored when the users filter is in use)")) }
class Order : Filter.Sort("Order", arrayOf("Date posted")) {
fun toSearchParameter(): String? = state?.ascending?.let { "date" }
}
val order = Order().also(::add)
class DateBefore : Filter.Text("Posted before")
val dateBefore = DateBefore().also(::add)
class DateAfter : Filter.Text("Posted after")
val dateAfter = DateAfter().also(::add)
} }