Merge pull request #591 from kiwix/suggestion_range

Allow kiwix-serve to get suggestions of custom range
This commit is contained in:
Kelson 2021-08-20 08:09:35 +02:00 committed by GitHub
commit ea6413ff88
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 81 additions and 6 deletions

View File

@ -345,13 +345,13 @@ std::unique_ptr<Response> InternalServer::build_homepage(const RequestContext& r
// TODO: retrieve searcher from caching mechanism // TODO: retrieve searcher from caching mechanism
SuggestionsList_t getSuggestions(const zim::Archive* const archive, 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; SuggestionsList_t suggestions;
auto searcher = zim::SuggestionSearcher(*archive); auto searcher = zim::SuggestionSearcher(*archive);
if (archive->hasTitleIndex()) { if (archive->hasTitleIndex()) {
auto search = searcher.suggest(queryString); auto search = searcher.suggest(queryString);
auto srs = search.getResults(0, suggestionCount); auto srs = search.getResults(start, suggestionCount);
for (auto it : srs) { for (auto it : srs) {
SuggestionItem suggestion(it.getTitle(), kiwix::normalize(it.getTitle()), SuggestionItem suggestion(it.getTitle(), kiwix::normalize(it.getTitle()),
@ -439,8 +439,6 @@ std::unique_ptr<Response> InternalServer::handle_suggest(const RequestContext& r
std::string content; std::string content;
std::string mimeType; std::string mimeType;
unsigned int maxSuggestionCount = 10;
unsigned int suggestionCount = 0;
std::string bookName; std::string bookName;
std::string bookId; std::string bookId;
@ -455,6 +453,20 @@ std::unique_ptr<Response> InternalServer::handle_suggest(const RequestContext& r
return Response::build_404(*this, request, bookName, ""); return Response::build_404(*this, request, bookName, "");
} }
auto start = 0;
try {
start = request.get_argument<unsigned int>("start");
} catch (const std::exception&) {}
unsigned int count = 10;
try {
count = request.get_argument<unsigned int>("count");
} catch (const std::exception&) {}
if (count == 0) {
count = 10;
}
if (archive == nullptr) { if (archive == nullptr) {
return Response::build_404(*this, request, bookName, ""); return Response::build_404(*this, request, bookName, "");
} }
@ -468,7 +480,7 @@ std::unique_ptr<Response> InternalServer::handle_suggest(const RequestContext& r
bool first = true; bool first = true;
/* Get the suggestions */ /* Get the suggestions */
SuggestionsList_t suggestions = getSuggestions(archive.get(), queryString, maxSuggestionCount); SuggestionsList_t suggestions = getSuggestions(archive.get(), queryString, start, count);
for(auto& suggestion:suggestions) { for(auto& suggestion:suggestions) {
MustacheData result; MustacheData result;
result.set("label", suggestion.getTitle()); result.set("label", suggestion.getTitle());
@ -483,7 +495,6 @@ std::unique_ptr<Response> InternalServer::handle_suggest(const RequestContext& r
result.set("first", first); result.set("first", first);
first = false; first = false;
results.push_back(result); results.push_back(result);
suggestionCount++;
} }

View File

@ -1176,3 +1176,67 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_search_terms)
"</feed>\n" "</feed>\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) + "&count=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&count=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&count=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&count=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&count=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&count=-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);
}
}