Drop usage of Reader from InternalServer::handle_suggest

This commit is contained in:
Maneesh P M 2021-05-23 11:44:39 +05:30
parent 7d68926539
commit a236751c74
5 changed files with 97 additions and 55 deletions

View File

@ -41,11 +41,11 @@ namespace kiwix
* The SuggestionItem is a helper class that contains the info about a single * The SuggestionItem is a helper class that contains the info about a single
* suggestion item. * suggestion item.
*/ */
class SuggestionItem class SuggestionItem
{ {
// Functions // Functions
private: // Temporarily making the constructor public until the code move is complete
public:
// Create a sugggestion item. // Create a sugggestion item.
explicit SuggestionItem(std::string title, std::string normalizedTitle, explicit SuggestionItem(std::string title, std::string normalizedTitle,
std::string path, std::string snippet = "") : std::string path, std::string snippet = "") :

View File

@ -70,5 +70,7 @@ T extractFromString(const std::string& str) {
} }
bool startsWith(const std::string& base, const std::string& start); bool startsWith(const std::string& base, const std::string& start);
std::vector<std::string> getTitleVariants(const std::string& title);
} //namespace kiwix } //namespace kiwix
#endif #endif

View File

@ -438,12 +438,7 @@ bool Reader::searchSuggestions(const string& prefix,
std::vector<std::string> Reader::getTitleVariants( std::vector<std::string> Reader::getTitleVariants(
const std::string& title) const const std::string& title) const
{ {
std::vector<std::string> variants; return kiwix::getTitleVariants(title);
variants.push_back(title);
variants.push_back(kiwix::ucFirst(title));
variants.push_back(kiwix::lcFirst(title));
variants.push_back(kiwix::toTitle(title));
return variants;
} }

View File

@ -57,6 +57,7 @@ extern "C" {
#include <zim/uuid.h> #include <zim/uuid.h>
#include <zim/error.h> #include <zim/error.h>
#include <zim/search.h>
#include <mustache.hpp> #include <mustache.hpp>
@ -329,6 +330,61 @@ std::unique_ptr<Response> InternalServer::build_homepage(const RequestContext& r
* Archive and Zim handlers begin * Archive and Zim handlers begin
**/ **/
// TODO: retrieve searcher from caching mechanism
SuggestionsList_t getSuggestions(const zim::Archive* const archive,
const std::string& queryString, int suggestionCount)
{
SuggestionsList_t suggestions;
if (archive->hasTitleIndex()) {
auto searcher = zim::Searcher(*archive);
zim::Query suggestionQuery;
suggestionQuery.setQuery(queryString, true);
auto suggestionSearch = searcher.search(suggestionQuery);
auto suggestionResult = suggestionSearch.getResults(0, suggestionCount);
for (auto it = suggestionResult.begin(); it != suggestionResult.end(); it++) {
SuggestionItem suggestion(it.getTitle(), kiwix::normalize(it.getTitle()),
it.getPath(), it.getSnippet());
suggestions.push_back(suggestion);
}
} else {
// TODO: This case should be handled by libzim
std::vector<std::string> variants = getTitleVariants(queryString);
int currCount = 0;
for (auto it = variants.begin(); it != variants.end() && currCount < suggestionCount; it++) {
for (auto& entry: archive->findByTitle(*it)) {
SuggestionItem suggestion(entry.getTitle(), kiwix::normalize(entry.getTitle()),
entry.getPath());
suggestions.push_back(suggestion);
currCount++;
}
}
}
return suggestions;
}
zim::Entry getFinalEntry(const zim::Archive* const archive, const zim::Entry& entry)
{
int loopCounter = 42;
auto final_entry = entry;
while (final_entry.isRedirect() && loopCounter--) {
final_entry = final_entry.getRedirectEntry();
}
// Prevent infinite loops.
if (final_entry.isRedirect()) {
throw zim::EntryNotFound("Unable to resolve entry redirects.");
}
return final_entry;
}
zim::Entry getEntryFromPath(const zim::Archive* const archive, const std::string& path)
{
if (path.empty() || path == "/") {
return archive->getMainEntry();
}
return archive->getEntryByPath(path);
}
std::vector<std::string> getTitleVariants(const std::string& title) std::vector<std::string> getTitleVariants(const std::string& title)
{ {
std::vector<std::string> variants; std::vector<std::string> variants;
@ -372,28 +428,6 @@ SuggestionsList_t getSuggestions(const zim::Archive* const archive,
return suggestions; return suggestions;
} }
zim::Entry getFinalEntry(const zim::Archive* const archive, const zim::Entry& entry)
{
int loopCounter = 42;
auto final_entry = entry;
while (final_entry.isRedirect() && loopCounter--) {
final_entry = final_entry.getRedirectEntry();
}
// Prevent infinite loops.
if (final_entry.isRedirect()) {
throw zim::EntryNotFound("Unable to resolve entry redirects.");
}
return final_entry;
}
zim::Entry getEntryFromPath(const zim::Archive* const archive, const std::string& path)
{
if (path.empty() || path == "/") {
return archive->getMainEntry();
}
return archive->getEntryByPath(path);
}
/** /**
* Archive and Zim handlers end * Archive and Zim handlers end
**/ **/
@ -460,51 +494,54 @@ std::unique_ptr<Response> InternalServer::handle_suggest(const RequestContext& r
std::string bookName; std::string bookName;
std::string bookId; std::string bookId;
std::string term; std::string queryString;
std::shared_ptr<Reader> reader; std::shared_ptr<zim::Archive> archive;
try { try {
bookName = request.get_argument("content"); bookName = request.get_argument("content");
bookId = mp_nameMapper->getIdForName(bookName); bookId = mp_nameMapper->getIdForName(bookName);
term = request.get_argument("term"); queryString = request.get_argument("term");
reader = mp_library->getReaderById(bookId); archive = mp_library->getArchiveById(bookId);
} catch (const std::out_of_range&) { } catch (const std::out_of_range&) {
return Response::build_404(*this, request, bookName, ""); return Response::build_404(*this, request, bookName, "");
} }
if (archive == nullptr) {
return Response::build_404(*this, request, bookName, "");
}
if (m_verbose.load()) { if (m_verbose.load()) {
printf("Searching suggestions for: \"%s\"\n", term.c_str()); printf("Searching suggestions for: \"%s\"\n", queryString.c_str());
} }
MustacheData results{MustacheData::type::list}; MustacheData results{MustacheData::type::list};
bool first = true; bool first = true;
if (reader != nullptr) {
/* Get the suggestions */
SuggestionsList_t suggestions;
reader->searchSuggestionsSmart(term, maxSuggestionCount, suggestions);
for(auto& suggestion:suggestions) {
MustacheData result;
result.set("label", suggestion.getTitle());
if (suggestion.hasSnippet()) { /* Get the suggestions */
result.set("label", suggestion.getSnippet()); SuggestionsList_t suggestions = getSuggestions(archive.get(), queryString, maxSuggestionCount);
} for(auto& suggestion:suggestions) {
MustacheData result;
result.set("label", suggestion.getTitle());
result.set("value", suggestion.getTitle()); if (suggestion.hasSnippet()) {
result.set("kind", "path"); result.set("label", suggestion.getSnippet());
result.set("path", suggestion.getPath());
result.set("first", first);
first = false;
results.push_back(result);
suggestionCount++;
} }
result.set("value", suggestion.getTitle());
result.set("kind", "path");
result.set("path", suggestion.getPath());
result.set("first", first);
first = false;
results.push_back(result);
suggestionCount++;
} }
/* Propose the fulltext search if possible */ /* Propose the fulltext search if possible */
if (reader->hasFulltextIndex()) { if (archive->hasFulltextIndex()) {
MustacheData result; MustacheData result;
result.set("label", "containing '" + term + "'..."); result.set("label", "containing '" + queryString + "'...");
result.set("value", term + " "); result.set("value", queryString + " ");
result.set("kind", "pattern"); result.set("kind", "pattern");
result.set("first", first); result.set("first", first);
results.push_back(result); results.push_back(result);

View File

@ -395,3 +395,11 @@ bool kiwix::startsWith(const std::string& base, const std::string& start)
&& std::equal(start.begin(), start.end(), base.begin()); && std::equal(start.begin(), start.end(), base.begin());
} }
std::vector<std::string> kiwix::getTitleVariants(const std::string& title) {
std::vector<std::string> variants;
variants.push_back(title);
variants.push_back(kiwix::ucFirst(title));
variants.push_back(kiwix::lcFirst(title));
variants.push_back(kiwix::toTitle(title));
return variants;
}