From 72d4c19e6c7c3d71a3025a07adb350ada3a1c859 Mon Sep 17 00:00:00 2001 From: Maneesh P M Date: Sun, 25 Jul 2021 12:24:44 +0530 Subject: [PATCH] Allow kiwix-serve to get suggestions of custom range This will allow handle_suggest API to accept two arguments `start` and `suggestionLength` that will allow handle_suggest to retrieve suggestions in the given range rather than the default 0-10 range. --- src/server/internalServer.cpp | 24 +++++++++---- test/server.cpp | 64 +++++++++++++++++++++++++++++++++++ 2 files changed, 81 insertions(+), 7 deletions(-) diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp index 957b128f8..ec8761068 100644 --- a/src/server/internalServer.cpp +++ b/src/server/internalServer.cpp @@ -334,7 +334,7 @@ std::unique_ptr InternalServer::build_homepage(const RequestContext& r // TODO: retrieve searcher from caching mechanism SuggestionsList_t getSuggestions(const zim::Archive* const archive, - const std::string& queryString, int suggestionCount) + const std::string& queryString, int start, int suggestionCount) { SuggestionsList_t suggestions; if (archive->hasTitleIndex()) { @@ -342,8 +342,7 @@ SuggestionsList_t getSuggestions(const zim::Archive* const archive, zim::Query suggestionQuery; suggestionQuery.setQuery(queryString, true); auto suggestionSearch = searcher.search(suggestionQuery); - auto suggestionResult = suggestionSearch.getResults(0, suggestionCount); - + auto suggestionResult = suggestionSearch.getResults(start, suggestionCount); for (auto it = suggestionResult.begin(); it != suggestionResult.end(); it++) { SuggestionItem suggestion(it.getTitle(), kiwix::normalize(it.getTitle()), it.getPath(), it.getSnippet()); @@ -426,8 +425,6 @@ std::unique_ptr InternalServer::handle_suggest(const RequestContext& r std::string content; std::string mimeType; - unsigned int maxSuggestionCount = 10; - unsigned int suggestionCount = 0; std::string bookName; std::string bookId; @@ -442,6 +439,20 @@ std::unique_ptr InternalServer::handle_suggest(const RequestContext& r return Response::build_404(*this, request, bookName, ""); } + auto start = 0; + try { + start = request.get_argument("start"); + } catch (const std::exception&) {} + + unsigned int suggestionLength = 10; + try { + suggestionLength = request.get_argument("suggestionLength"); + } catch (const std::exception&) {} + + if (suggestionLength == 0) { + suggestionLength = 10; + } + if (archive == nullptr) { return Response::build_404(*this, request, bookName, ""); } @@ -455,7 +466,7 @@ std::unique_ptr InternalServer::handle_suggest(const RequestContext& r bool first = true; /* Get the suggestions */ - SuggestionsList_t suggestions = getSuggestions(archive.get(), queryString, maxSuggestionCount); + SuggestionsList_t suggestions = getSuggestions(archive.get(), queryString, start, suggestionLength); for(auto& suggestion:suggestions) { MustacheData result; result.set("label", suggestion.getTitle()); @@ -470,7 +481,6 @@ std::unique_ptr InternalServer::handle_suggest(const RequestContext& r result.set("first", first); first = false; results.push_back(result); - suggestionCount++; } diff --git a/test/server.cpp b/test/server.cpp index f900cd938..ecc2015e4 100644 --- a/test/server.cpp +++ b/test/server.cpp @@ -1168,3 +1168,67 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_search_terms) "\n" ); } + +TEST_F(LibraryServerTest, suggestions_in_range) +{ + /** + * Attempt to get 50 suggestions in steps of 5 + * The suggestions are returned in the json format + * [{sugg1}, {sugg2}, ... , {suggN}, {suggest ft search}] + * Assuming the number of suggestions = (occurance of "{" - 1) + */ + { + int suggCount = 0; + for (int i = 0; i < 10; i++) { + std::string url = "/suggest?content=zimfile&term=ray&start=" + std::to_string(i*5) + "&suggestionLength=5"; + const auto r = zfs1_->GET(url.c_str()); + std::string body = r->body; + int currCount = std::count(body.begin(), body.end(), '{') - 1; + ASSERT_EQ(currCount, 5); + suggCount += currCount; + } + ASSERT_EQ(suggCount, 50); + } + + // Attempt to get 10 suggestions in steps of 5 even though there are only 8 + { + std::string url = "/suggest?content=zimfile&term=song+for+you&start=0&suggestionLength=5"; + const auto r1 = zfs1_->GET(url.c_str()); + std::string body = r1->body; + int currCount = std::count(body.begin(), body.end(), '{') - 1; + ASSERT_EQ(currCount, 5); + + url = "/suggest?content=zimfile&term=song+for+you&start=5&suggestionLength=5"; + const auto r2 = zfs1_->GET(url.c_str()); + body = r2->body; + currCount = std::count(body.begin(), body.end(), '{') - 1; + ASSERT_EQ(currCount, 3); + } + + // Attempt to get 10 suggestions even though there is only 1 + { + std::string url = "/suggest?content=zimfile&term=strong&start=0&suggestionLength=5"; + const auto r = zfs1_->GET(url.c_str()); + std::string body = r->body; + int currCount = std::count(body.begin(), body.end(), '{') - 1; + ASSERT_EQ(currCount, 1); + } + + // No Suggestion + { + std::string url = "/suggest?content=zimfile&term=oops&start=0&suggestionLength=5"; + const auto r = zfs1_->GET(url.c_str()); + std::string body = r->body; + int currCount = std::count(body.begin(), body.end(), '{') - 1; + ASSERT_EQ(currCount, 0); + } + + // Out of bound value + { + std::string url = "/suggest?content=zimfile&term=ray&start=-2&suggestionLength=-1"; + const auto r = zfs1_->GET(url.c_str()); + std::string body = r->body; + int currCount = std::count(body.begin(), body.end(), '{') - 1; + ASSERT_EQ(currCount, 0); + } +} \ No newline at end of file