mirror of https://github.com/kiwix/libkiwix.git
Allow user to select multiple books when doing search.
This commit is contained in:
parent
98c54b2279
commit
22996e4a6b
|
@ -109,8 +109,7 @@ SearchInfo::SearchInfo(const std::string& pattern, GeoQuery geoQuery)
|
||||||
|
|
||||||
SearchInfo::SearchInfo(const RequestContext& request)
|
SearchInfo::SearchInfo(const RequestContext& request)
|
||||||
: pattern(request.get_optional_param<std::string>("pattern", "")),
|
: pattern(request.get_optional_param<std::string>("pattern", "")),
|
||||||
geoQuery(),
|
geoQuery()
|
||||||
bookName(request.get_optional_param<std::string>("content", ""))
|
|
||||||
{
|
{
|
||||||
/* Retrive geo search */
|
/* Retrive geo search */
|
||||||
try {
|
try {
|
||||||
|
@ -124,6 +123,11 @@ SearchInfo::SearchInfo(const RequestContext& request)
|
||||||
if (!geoQuery && pattern.empty()) {
|
if (!geoQuery && pattern.empty()) {
|
||||||
throw std::invalid_argument("No query provided.");
|
throw std::invalid_argument("No query provided.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
auto content_vector = request.get_arguments("content");
|
||||||
|
bookNames = std::set<std::string>(content_vector.begin(), content_vector.end());
|
||||||
|
} catch (const std::out_of_range&) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
zim::Query SearchInfo::getZimQuery(bool verbose) const {
|
zim::Query SearchInfo::getZimQuery(bool verbose) const {
|
||||||
|
@ -580,16 +584,6 @@ std::unique_ptr<Response> InternalServer::handle_search(const RequestContext& re
|
||||||
try {
|
try {
|
||||||
auto searchInfo = SearchInfo(request);
|
auto searchInfo = SearchInfo(request);
|
||||||
|
|
||||||
std::string bookId;
|
|
||||||
if (!searchInfo.bookName.empty()) {
|
|
||||||
try {
|
|
||||||
bookId = mp_nameMapper->getIdForName(searchInfo.bookName);
|
|
||||||
} catch (const std::out_of_range&) {
|
|
||||||
throw std::invalid_argument("The requested book doesn't exist.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Make the search */
|
/* Make the search */
|
||||||
// Try to get a search from the searchInfo, else build it
|
// Try to get a search from the searchInfo, else build it
|
||||||
std::shared_ptr<zim::Search> search;
|
std::shared_ptr<zim::Search> search;
|
||||||
|
@ -597,8 +591,15 @@ std::unique_ptr<Response> InternalServer::handle_search(const RequestContext& re
|
||||||
search = searchCache.getOrPut(searchInfo,
|
search = searchCache.getOrPut(searchInfo,
|
||||||
[=](){
|
[=](){
|
||||||
Library::BookIdSet bookIds;
|
Library::BookIdSet bookIds;
|
||||||
if(!bookId.empty()) {
|
if(!searchInfo.bookNames.empty()) {
|
||||||
bookIds.insert(bookId);
|
for(const auto& bookName: searchInfo.bookNames) {
|
||||||
|
try {
|
||||||
|
auto bookId = mp_nameMapper->getIdForName(bookName);
|
||||||
|
bookIds.insert(bookId);
|
||||||
|
} catch(const std::out_of_range&) {
|
||||||
|
throw std::invalid_argument("The requested book doesn't exist.");
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
for (auto& bookId: mp_library->filter(kiwix::Filter().local(true).valid(true))) {
|
for (auto& bookId: mp_library->filter(kiwix::Filter().local(true).valid(true))) {
|
||||||
bookIds.insert(bookId);
|
bookIds.insert(bookId);
|
||||||
|
@ -613,15 +614,18 @@ std::unique_ptr<Response> InternalServer::handle_search(const RequestContext& re
|
||||||
// (in case of zim file not containing a index)
|
// (in case of zim file not containing a index)
|
||||||
const auto cssUrl = renderUrl(m_root, RESOURCE::templates::url_of_search_results_css);
|
const auto cssUrl = renderUrl(m_root, RESOURCE::templates::url_of_search_results_css);
|
||||||
HTTPErrorHtmlResponse response(*this, request, MHD_HTTP_NOT_FOUND,
|
HTTPErrorHtmlResponse response(*this, request, MHD_HTTP_NOT_FOUND,
|
||||||
"fulltext-search-unavailable",
|
"fulltext-search-unavailable",
|
||||||
"404-page-heading",
|
"404-page-heading",
|
||||||
cssUrl);
|
cssUrl);
|
||||||
response += nonParameterizedMessage("no-search-results");
|
response += nonParameterizedMessage("no-search-results");
|
||||||
response += TaskbarInfo(searchInfo.bookName, bookId.empty()?nullptr:mp_library->getArchiveById(bookId).get());
|
if(searchInfo.bookNames.size() == 1) {
|
||||||
|
auto bookName =*searchInfo.bookNames.begin();
|
||||||
|
auto bookId = mp_nameMapper->getIdForName(bookName);
|
||||||
|
response += TaskbarInfo(bookName, mp_library->getArchiveById(bookId).get());
|
||||||
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
auto start = 0;
|
auto start = 0;
|
||||||
try {
|
try {
|
||||||
start = request.get_argument<unsigned int>("start");
|
start = request.get_argument<unsigned int>("start");
|
||||||
|
@ -642,12 +646,17 @@ std::unique_ptr<Response> InternalServer::handle_search(const RequestContext& re
|
||||||
SearchRenderer renderer(search->getResults(start, pageLength), mp_nameMapper, mp_library, start,
|
SearchRenderer renderer(search->getResults(start, pageLength), mp_nameMapper, mp_library, start,
|
||||||
search->getEstimatedMatches());
|
search->getEstimatedMatches());
|
||||||
renderer.setSearchPattern(searchInfo.pattern);
|
renderer.setSearchPattern(searchInfo.pattern);
|
||||||
renderer.setSearchContent(searchInfo.bookName);
|
//[TODO]
|
||||||
|
//renderer.setSearchContent(searchInfo.bookNames);
|
||||||
renderer.setProtocolPrefix(m_root + "/");
|
renderer.setProtocolPrefix(m_root + "/");
|
||||||
renderer.setSearchProtocolPrefix(m_root + "/search");
|
renderer.setSearchProtocolPrefix(m_root + "/search");
|
||||||
renderer.setPageLength(pageLength);
|
renderer.setPageLength(pageLength);
|
||||||
auto response = ContentResponse::build(*this, renderer.getHtml(), "text/html; charset=utf-8");
|
auto response = ContentResponse::build(*this, renderer.getHtml(), "text/html; charset=utf-8");
|
||||||
response->set_taskbar(searchInfo.bookName, bookId.empty()?nullptr:mp_library->getArchiveById(bookId).get());
|
if(searchInfo.bookNames.size() == 1) {
|
||||||
|
auto bookName = *searchInfo.bookNames.begin();
|
||||||
|
auto bookId = mp_nameMapper->getIdForName(bookName);
|
||||||
|
response->set_taskbar(bookName, mp_library->getArchiveById(bookId).get());
|
||||||
|
}
|
||||||
return std::move(response);
|
return std::move(response);
|
||||||
} catch (const std::invalid_argument& e) {
|
} catch (const std::invalid_argument& e) {
|
||||||
return HTTP400HtmlResponse(*this, request)
|
return HTTP400HtmlResponse(*this, request)
|
||||||
|
|
|
@ -76,14 +76,14 @@ class SearchInfo {
|
||||||
|
|
||||||
friend bool operator<(const SearchInfo& l, const SearchInfo& r)
|
friend bool operator<(const SearchInfo& l, const SearchInfo& r)
|
||||||
{
|
{
|
||||||
return std::tie(l.bookName, l.pattern, l.geoQuery)
|
return std::tie(l.bookNames, l.pattern, l.geoQuery)
|
||||||
< std::tie(r.bookName, r.pattern, r.geoQuery); // keep the same order
|
< std::tie(r.bookNames, r.pattern, r.geoQuery); // keep the same order
|
||||||
}
|
}
|
||||||
|
|
||||||
public: //data
|
public: //data
|
||||||
std::string pattern;
|
std::string pattern;
|
||||||
GeoQuery geoQuery;
|
GeoQuery geoQuery;
|
||||||
std::string bookName;
|
std::set<std::string> bookNames;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue