mirror of
https://github.com/Suwayomi/Suwayomi-Server.git
synced 2026-07-04 03:14:40 -05:00
POST variant for /{sourceId}/search endpoint (#434)
* Add POST variant for `/{sourceId}/search` endpoint which handles body data as list of FilterChanges
* Revert changes to existing endpoint and create new route and change the interface
* Update doc
* Rename api endpoint
This commit is contained in:
@@ -48,6 +48,7 @@ object MangaAPI {
|
|||||||
post("{sourceId}/filters", SourceController.setFilters)
|
post("{sourceId}/filters", SourceController.setFilters)
|
||||||
|
|
||||||
get("{sourceId}/search", SourceController.searchSingle)
|
get("{sourceId}/search", SourceController.searchSingle)
|
||||||
|
post("{sourceId}/quick-search", SourceController.quickSearchSingle)
|
||||||
// get("all/search", SourceController.searchGlobal) // TODO
|
// get("all/search", SourceController.searchGlobal) // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import org.kodein.di.instance
|
|||||||
import suwayomi.tachidesk.manga.impl.MangaList
|
import suwayomi.tachidesk.manga.impl.MangaList
|
||||||
import suwayomi.tachidesk.manga.impl.Search
|
import suwayomi.tachidesk.manga.impl.Search
|
||||||
import suwayomi.tachidesk.manga.impl.Search.FilterChange
|
import suwayomi.tachidesk.manga.impl.Search.FilterChange
|
||||||
|
import suwayomi.tachidesk.manga.impl.Search.FilterData
|
||||||
import suwayomi.tachidesk.manga.impl.Source
|
import suwayomi.tachidesk.manga.impl.Source
|
||||||
import suwayomi.tachidesk.manga.impl.Source.SourcePreferenceChange
|
import suwayomi.tachidesk.manga.impl.Source.SourcePreferenceChange
|
||||||
import suwayomi.tachidesk.manga.model.dataclass.PagedMangaListDataClass
|
import suwayomi.tachidesk.manga.model.dataclass.PagedMangaListDataClass
|
||||||
@@ -202,6 +203,25 @@ object SourceController {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
/** quick search single source filter */
|
||||||
|
val quickSearchSingle = handler(
|
||||||
|
pathParam<Long>("sourceId"),
|
||||||
|
queryParam("pageNum", 1),
|
||||||
|
documentWith = {
|
||||||
|
withOperation {
|
||||||
|
summary("Source manga quick search")
|
||||||
|
description("Returns list of manga from source matching posted searchTerm and filter")
|
||||||
|
}
|
||||||
|
},
|
||||||
|
behaviorOf = { ctx, sourceId, pageNum ->
|
||||||
|
var filter = json.decodeFromString<FilterData>(ctx.body())
|
||||||
|
ctx.future(future { Search.sourceFilter(sourceId, pageNum, filter) })
|
||||||
|
},
|
||||||
|
withResults = {
|
||||||
|
json<PagedMangaListDataClass>(HttpCode.OK)
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
/** all source search */
|
/** all source search */
|
||||||
val searchAll = handler(
|
val searchAll = handler(
|
||||||
pathParam<String>("searchTerm"),
|
pathParam<String>("searchTerm"),
|
||||||
|
|||||||
@@ -27,6 +27,13 @@ object Search {
|
|||||||
return searchManga.processEntries(sourceId)
|
return searchManga.processEntries(sourceId)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
suspend fun sourceFilter(sourceId: Long, pageNum: Int, filter: FilterData): PagedMangaListDataClass {
|
||||||
|
val source = getCatalogueSourceOrStub(sourceId)
|
||||||
|
val filterList = if (filter.filter != null) buildFilterList(sourceId, filter.filter) else source.getFilterList()
|
||||||
|
val searchManga = source.fetchSearchManga(pageNum, filter.searchTerm ?: "", filterList).awaitSingle()
|
||||||
|
return searchManga.processEntries(sourceId)
|
||||||
|
}
|
||||||
|
|
||||||
private val filterListCache = mutableMapOf<Long, FilterList>()
|
private val filterListCache = mutableMapOf<Long, FilterList>()
|
||||||
|
|
||||||
private fun getFilterListOf(source: CatalogueSource, reset: Boolean = false): FilterList {
|
private fun getFilterListOf(source: CatalogueSource, reset: Boolean = false): FilterList {
|
||||||
@@ -84,7 +91,10 @@ object Search {
|
|||||||
fun setFilter(sourceId: Long, changes: List<FilterChange>) {
|
fun setFilter(sourceId: Long, changes: List<FilterChange>) {
|
||||||
val source = getCatalogueSourceOrStub(sourceId)
|
val source = getCatalogueSourceOrStub(sourceId)
|
||||||
val filterList = getFilterListOf(source, false)
|
val filterList = getFilterListOf(source, false)
|
||||||
|
updateFilterList(filterList, changes)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateFilterList(filterList: FilterList, changes: List<FilterChange>): FilterList {
|
||||||
changes.forEach { change ->
|
changes.forEach { change ->
|
||||||
when (val filter = filterList[change.position]) {
|
when (val filter = filterList[change.position]) {
|
||||||
is Filter.Header -> {
|
is Filter.Header -> {
|
||||||
@@ -112,6 +122,13 @@ object Search {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return filterList
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun buildFilterList(sourceId: Long, changes: List<FilterChange>): FilterList {
|
||||||
|
val source = getCatalogueSourceOrStub(sourceId)
|
||||||
|
val filterList = source.getFilterList()
|
||||||
|
return updateFilterList(filterList, changes)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val jsonMapper by DI.global.instance<JsonMapper>()
|
private val jsonMapper by DI.global.instance<JsonMapper>()
|
||||||
@@ -122,6 +139,12 @@ object Search {
|
|||||||
val state: String
|
val state: String
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
data class FilterData(
|
||||||
|
val searchTerm: String?,
|
||||||
|
val filter: List<FilterChange>?
|
||||||
|
)
|
||||||
|
|
||||||
@Suppress("UNUSED_PARAMETER")
|
@Suppress("UNUSED_PARAMETER")
|
||||||
fun sourceGlobalSearch(searchTerm: String) {
|
fun sourceGlobalSearch(searchTerm: String) {
|
||||||
// TODO
|
// TODO
|
||||||
|
|||||||
Reference in New Issue
Block a user