From c2a9820fc11f38263590a45dd7c1c73ca603bc89 Mon Sep 17 00:00:00 2001 From: Valter Martinek Date: Sat, 5 Nov 2022 18:18:20 +0100 Subject: [PATCH] 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 --- .../suwayomi/tachidesk/manga/MangaAPI.kt | 1 + .../manga/controller/SourceController.kt | 20 ++++++++++++++++ .../suwayomi/tachidesk/manga/impl/Search.kt | 23 +++++++++++++++++++ 3 files changed, 44 insertions(+) diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt index 29bf03e7..9c329e47 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/MangaAPI.kt @@ -48,6 +48,7 @@ object MangaAPI { post("{sourceId}/filters", SourceController.setFilters) get("{sourceId}/search", SourceController.searchSingle) + post("{sourceId}/quick-search", SourceController.quickSearchSingle) // get("all/search", SourceController.searchGlobal) // TODO } diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/controller/SourceController.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/controller/SourceController.kt index a5d4e3d8..55e9de41 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/controller/SourceController.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/controller/SourceController.kt @@ -16,6 +16,7 @@ import org.kodein.di.instance import suwayomi.tachidesk.manga.impl.MangaList import suwayomi.tachidesk.manga.impl.Search 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.SourcePreferenceChange import suwayomi.tachidesk.manga.model.dataclass.PagedMangaListDataClass @@ -202,6 +203,25 @@ object SourceController { } ) + /** quick search single source filter */ + val quickSearchSingle = handler( + pathParam("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(ctx.body()) + ctx.future(future { Search.sourceFilter(sourceId, pageNum, filter) }) + }, + withResults = { + json(HttpCode.OK) + } + ) + /** all source search */ val searchAll = handler( pathParam("searchTerm"), diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Search.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Search.kt index ad8407e2..cc3bdf5c 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Search.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/Search.kt @@ -27,6 +27,13 @@ object Search { 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() private fun getFilterListOf(source: CatalogueSource, reset: Boolean = false): FilterList { @@ -84,7 +91,10 @@ object Search { fun setFilter(sourceId: Long, changes: List) { val source = getCatalogueSourceOrStub(sourceId) val filterList = getFilterListOf(source, false) + updateFilterList(filterList, changes) + } + private fun updateFilterList(filterList: FilterList, changes: List): FilterList { changes.forEach { change -> when (val filter = filterList[change.position]) { is Filter.Header -> { @@ -112,6 +122,13 @@ object Search { } } } + return filterList + } + + private fun buildFilterList(sourceId: Long, changes: List): FilterList { + val source = getCatalogueSourceOrStub(sourceId) + val filterList = source.getFilterList() + return updateFilterList(filterList, changes) } private val jsonMapper by DI.global.instance() @@ -122,6 +139,12 @@ object Search { val state: String ) + @Serializable + data class FilterData( + val searchTerm: String?, + val filter: List? + ) + @Suppress("UNUSED_PARAMETER") fun sourceGlobalSearch(searchTerm: String) { // TODO