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'
pkgNameSuffix = 'all.pixiv'
extClass = '.PixivFactory'
extVersionCode = 6
extVersionCode = 7
isNsfw = true
}

View File

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

View File

@ -1,72 +1,61 @@
package eu.kanade.tachiyomi.extension.all.pixiv
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() {
class Type : Filter.Select<String>("Type", values, 2) {
companion object {
private val values: Array<String> =
arrayOf("All", "Illustrations", "Manga")
private val typeFilter = object : Filter.Select<String>("Type", TYPE_VALUES, 2) {}.also(::add)
private val tagsFilter = object : Filter.Text("Tags") {}.also(::add)
private val tagsModeFilter = object : Filter.Select<String>("Tags mode", TAGS_MODE_VALUES, 0) {}.also(::add)
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?> =
arrayOf(null, "illust", "manga")
}
init { add(Filter.Header("(the following are ignored when the users filter is in use)")) }
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") {
fun toPredicate(): ((PixivIllust) -> Boolean)? {
if (state.isBlank()) return null
val tags: String by tagsFilter::state
val searchMode: String get() = TAGS_MODE_PARAMS[tagsModeFilter.state]
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 }
}
}
val tags = Tags().also(::add)
val users: String by usersFilter::state
class Users : Filter.Text("Users") {
fun toPredicate(): ((PixivIllust) -> Boolean)? {
if (state.isBlank()) return null
val regex = Regex(state.split(' ').joinToString("|") { Regex.escape(it) })
fun makeUsersPredicate(): ((PixivIllust) -> Boolean)? {
val users = users.ifBlank { return null }
val regex = Regex(users.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) {
companion object {
private val searchParams: Array<String?> =
arrayOf(null, "all", "r18")
val order: String? get() = orderFilter.state?.ascending?.let { "date" }
private val values: Array<String> =
arrayOf("All", "All ages", "R-18")
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)
val dateBefore: String by dateBeforeFilter::state
val dateAfter: String by dateAfterFilter::state
}