Drop Reader and Entry wrappers from handle_content

This commit is contained in:
Maneesh P M 2021-05-24 12:08:56 +05:30
parent 75b4d311d7
commit c046f64d83
5 changed files with 78 additions and 130 deletions

View File

@ -29,18 +29,19 @@
namespace kiwix namespace kiwix
{ {
std::string getMetadata(const zim::Archive* const archive, const std::string& name); std::string getMetadata(const zim::Archive& archive, const std::string& name);
std::string getArchiveTitle(const zim::Archive* const archive); std::string getArchiveTitle(const zim::Archive& archive);
std::string getMetaDescription(const zim::Archive* const archive); std::string getMetaDescription(const zim::Archive& archive);
std::string getMetaTags(const zim::Archive* const archive, bool original = false); std::string getMetaTags(const zim::Archive& archive, bool original = false);
bool getArchiveFavicon(const zim::Archive* const archive, bool getArchiveFavicon(const zim::Archive& archive,
std::string& content, std::string& mimeType); std::string& content, std::string& mimeType);
std::string getMetaLanguage(const zim::Archive* const archive); std::string getMetaLanguage(const zim::Archive& archive);
std::string getMetaName(const zim::Archive* const archive); std::string getMetaName(const zim::Archive& archive);
std::string getMetaDate(const zim::Archive* const archive); std::string getMetaDate(const zim::Archive& archive);
std::string getMetaCreator(const zim::Archive* const archive); std::string getMetaCreator(const zim::Archive& archive);
std::string getMetaPublisher(const zim::Archive* const archive); std::string getMetaPublisher(const zim::Archive& archive);
zim::Entry getFinalEntry(const zim::Archive* const archive, const zim::Entry& entry); zim::Item getFinalItem(const zim::Archive& archive, const zim::Entry& entry);
zim::Entry getEntryFromPath(const zim::Archive& archive, const std::string& path);
} }
#endif #endif

View File

@ -189,7 +189,7 @@ Entry Reader::getMainPage() const
bool Reader::getFavicon(string& content, string& mimeType) const bool Reader::getFavicon(string& content, string& mimeType) const
{ {
return kiwix::getArchiveFavicon(zimArchive.get(), content, mimeType); return kiwix::getArchiveFavicon(*zimArchive, content, mimeType);
} }
string Reader::getZimFilePath() const string Reader::getZimFilePath() const
@ -211,32 +211,32 @@ bool Reader::getMetadata(const string& name, string& value) const
string Reader::getName() const string Reader::getName() const
{ {
return kiwix::getMetaName(zimArchive.get()); return kiwix::getMetaName(*zimArchive);
} }
string Reader::getTitle() const string Reader::getTitle() const
{ {
return kiwix::getArchiveTitle(zimArchive.get()); return kiwix::getArchiveTitle(*zimArchive);
} }
string Reader::getCreator() const string Reader::getCreator() const
{ {
return kiwix::getMetaCreator(zimArchive.get()); return kiwix::getMetaCreator(*zimArchive);
} }
string Reader::getPublisher() const string Reader::getPublisher() const
{ {
return kiwix::getMetaPublisher(zimArchive.get()); return kiwix::getMetaPublisher(*zimArchive);
} }
string Reader::getDate() const string Reader::getDate() const
{ {
return kiwix::getMetaDate(zimArchive.get()); return kiwix::getMetaDate(*zimArchive);
} }
string Reader::getDescription() const string Reader::getDescription() const
{ {
return kiwix::getMetaDescription(zimArchive.get()); return kiwix::getMetaDescription(*zimArchive);
} }
string Reader::getLongDescription() const string Reader::getLongDescription() const
@ -246,7 +246,7 @@ string Reader::getLongDescription() const
string Reader::getLanguage() const string Reader::getLanguage() const
{ {
return kiwix::getMetaLanguage(zimArchive.get()); return kiwix::getMetaLanguage(*zimArchive);
} }
string Reader::getLicense() const string Reader::getLicense() const
@ -256,7 +256,7 @@ string Reader::getLicense() const
string Reader::getTags(bool original) const string Reader::getTags(bool original) const
{ {
return kiwix::getMetaTags(zimArchive.get(), original); return kiwix::getMetaTags(*zimArchive, original);
} }
@ -320,12 +320,8 @@ string Reader::getOrigId() const
Entry Reader::getEntryFromPath(const std::string& path) const Entry Reader::getEntryFromPath(const std::string& path) const
{ {
if (path.empty() || path == "/") {
return getMainPage();
}
try { try {
return zimArchive->getEntryByPath(path); return kiwix::getEntryFromPath(*zimArchive, path);
} catch (zim::EntryNotFound& e) { } catch (zim::EntryNotFound& e) {
throw NoEntry(); throw NoEntry();
} }

View File

@ -365,71 +365,6 @@ SuggestionsList_t getSuggestions(const zim::Archive* const archive,
return suggestions; return suggestions;
} }
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> 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;
}
// 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(), it.getPath(),
kiwix::normalize(it.getTitle()), 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(), entry.getPath(),
kiwix::normalize(entry.getTitle()));
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;
}
/** /**
* Archive and Zim handlers end * Archive and Zim handlers end
**/ **/
@ -457,23 +392,23 @@ std::unique_ptr<Response> InternalServer::handle_meta(const RequestContext& requ
std::string mimeType = "text"; std::string mimeType = "text";
if (meta_name == "title") { if (meta_name == "title") {
content = getArchiveTitle(archive.get()); content = getArchiveTitle(*archive);
} else if (meta_name == "description") { } else if (meta_name == "description") {
content = getMetaDescription(archive.get()); content = getMetaDescription(*archive);
} else if (meta_name == "language") { } else if (meta_name == "language") {
content = getMetaLanguage(archive.get()); content = getMetaLanguage(*archive);
} else if (meta_name == "name") { } else if (meta_name == "name") {
content = getMetaName(archive.get()); content = getMetaName(*archive);
} else if (meta_name == "tags") { } else if (meta_name == "tags") {
content = getMetaTags(archive.get()); content = getMetaTags(*archive);
} else if (meta_name == "date") { } else if (meta_name == "date") {
content = getMetaDate(archive.get()); content = getMetaDate(*archive);
} else if (meta_name == "creator") { } else if (meta_name == "creator") {
content = getMetaCreator(archive.get()); content = getMetaCreator(*archive);
} else if (meta_name == "publisher") { } else if (meta_name == "publisher") {
content = getMetaPublisher(archive.get()); content = getMetaPublisher(*archive);
} else if (meta_name == "favicon") { } else if (meta_name == "favicon") {
getArchiveFavicon(archive.get(), content, mimeType); getArchiveFavicon(*archive, content, mimeType);
} else { } else {
return Response::build_404(*this, request, bookName, ""); return Response::build_404(*this, request, bookName, "");
} }
@ -617,7 +552,7 @@ std::unique_ptr<Response> InternalServer::handle_search(const RequestContext& re
auto data = get_default_data(); auto data = get_default_data();
data.set("pattern", encodeDiples(patternString)); data.set("pattern", encodeDiples(patternString));
auto response = ContentResponse::build(*this, RESOURCE::templates::no_search_result_html, data, "text/html; charset=utf-8"); auto response = ContentResponse::build(*this, RESOURCE::templates::no_search_result_html, data, "text/html; charset=utf-8");
response->set_taskbar(bookName, reader ? reader->getTitle() : ""); response->set_taskbar(bookName, archive ? getArchiveTitle(*archive) : "");
response->set_code(MHD_HTTP_NOT_FOUND); response->set_code(MHD_HTTP_NOT_FOUND);
return std::move(response); return std::move(response);
} }
@ -668,7 +603,7 @@ std::unique_ptr<Response> InternalServer::handle_search(const RequestContext& re
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(bookName, reader ? reader->getTitle() : ""); response->set_taskbar(bookName, archive ? getArchiveTitle(*archive) : "");
return std::move(response); return std::move(response);
} catch (const std::exception& e) { } catch (const std::exception& e) {
@ -700,7 +635,7 @@ std::unique_ptr<Response> InternalServer::handle_random(const RequestContext& re
try { try {
auto entry = archive->getRandomEntry(); auto entry = archive->getRandomEntry();
return build_redirect(bookName, getFinalEntry(archive.get(), entry)); return build_redirect(bookName, getFinalItem(*archive, entry));
} catch(zim::EntryNotFound& e) { } catch(zim::EntryNotFound& e) {
return Response::build_404(*this, request, bookName, ""); return Response::build_404(*this, request, bookName, "");
} }
@ -861,9 +796,9 @@ InternalServer::get_reader(const std::string& bookName) const
} }
std::unique_ptr<Response> std::unique_ptr<Response>
InternalServer::build_redirect(const std::string& bookName, const kiwix::Entry& entry) const InternalServer::build_redirect(const std::string& bookName, const zim::Item& item) const
{ {
auto redirectUrl = m_root + "/" + bookName + "/" + kiwix::urlEncode(entry.getPath()); auto redirectUrl = m_root + "/" + bookName + "/" + kiwix::urlEncode(item.getPath());
return Response::build_redirect(*this, redirectUrl); return Response::build_redirect(*this, redirectUrl);
} }
@ -879,8 +814,13 @@ std::unique_ptr<Response> InternalServer::handle_content(const RequestContext& r
if (bookName.empty()) if (bookName.empty())
return build_homepage(request); return build_homepage(request);
const std::shared_ptr<Reader> reader = get_reader(bookName); std::shared_ptr<zim::Archive> archive;
if (reader == nullptr) { try {
const std::string bookId = mp_nameMapper->getIdForName(bookName);
archive = mp_library->getArchiveById(bookId);
} catch (const std::out_of_range& e) {}
if (archive == nullptr) {
std::string searchURL = m_root+"/search?pattern="+pattern; // Make a full search on the entire library. std::string searchURL = m_root+"/search?pattern="+pattern; // Make a full search on the entire library.
const std::string details = searchSuggestionHTML(searchURL, kiwix::urlDecode(pattern)); const std::string details = searchSuggestionHTML(searchURL, kiwix::urlDecode(pattern));
@ -893,31 +833,31 @@ std::unique_ptr<Response> InternalServer::handle_content(const RequestContext& r
} }
try { try {
auto entry = reader->getEntryFromPath(urlStr); auto entry = getEntryFromPath(*archive, urlStr);
if (entry.isRedirect() || urlStr.empty()) { if (entry.isRedirect() || urlStr.empty()) {
// If urlStr is empty, we want to mainPage. // If urlStr is empty, we want to mainPage.
// We must do a redirection to the real page. // We must do a redirection to the real page.
return build_redirect(bookName, entry.getFinalEntry()); return build_redirect(bookName, getFinalItem(*archive, entry));
} }
auto response = ItemResponse::build(*this, request, entry.getZimEntry().getItem()); auto response = ItemResponse::build(*this, request, entry.getItem());
try { try {
dynamic_cast<ContentResponse&>(*response).set_taskbar(bookName, reader->getTitle()); dynamic_cast<ContentResponse&>(*response).set_taskbar(bookName, getArchiveTitle(*archive));
} catch (std::bad_cast& e) {} } catch (std::bad_cast& e) {}
if (m_verbose.load()) { if (m_verbose.load()) {
printf("Found %s\n", entry.getPath().c_str()); printf("Found %s\n", entry.getPath().c_str());
printf("mimeType: %s\n", entry.getMimetype().c_str()); printf("mimeType: %s\n", entry.getItem(true).getMimetype().c_str());
} }
return response; return response;
} catch(kiwix::NoEntry& e) { } catch(zim::EntryNotFound& e) {
if (m_verbose.load()) if (m_verbose.load())
printf("Failed to find %s\n", urlStr.c_str()); printf("Failed to find %s\n", urlStr.c_str());
std::string searchURL = m_root+"/search?content="+bookName+"&pattern="+pattern; // Make a search on this specific book only. std::string searchURL = m_root+"/search?content="+bookName+"&pattern="+pattern; // Make a search on this specific book only.
const std::string details = searchSuggestionHTML(searchURL, kiwix::urlDecode(pattern)); const std::string details = searchSuggestionHTML(searchURL, kiwix::urlDecode(pattern));
return Response::build_404(*this, request, bookName, reader->getTitle(), details); return Response::build_404(*this, request, bookName, getArchiveTitle(*archive), details);
} }
} }

View File

@ -69,7 +69,7 @@ class InternalServer {
private: // functions private: // functions
std::unique_ptr<Response> handle_request(const RequestContext& request); std::unique_ptr<Response> handle_request(const RequestContext& request);
std::unique_ptr<Response> build_redirect(const std::string& bookName, const kiwix::Entry& entry) const; std::unique_ptr<Response> build_redirect(const std::string& bookName, const zim::Item& item) const;
std::unique_ptr<Response> build_homepage(const RequestContext& request); std::unique_ptr<Response> build_homepage(const RequestContext& request);
std::unique_ptr<Response> handle_skin(const RequestContext& request); std::unique_ptr<Response> handle_skin(const RequestContext& request);
std::unique_ptr<Response> handle_catalog(const RequestContext& request); std::unique_ptr<Response> handle_catalog(const RequestContext& request);

View File

@ -27,18 +27,18 @@
namespace kiwix namespace kiwix
{ {
std::string getMetadata(const zim::Archive* const archive, const std::string& name) { std::string getMetadata(const zim::Archive& archive, const std::string& name) {
try { try {
return archive->getMetadata(name); return archive.getMetadata(name);
} catch (zim::EntryNotFound& e) { } catch (zim::EntryNotFound& e) {
return ""; return "";
} }
} }
std::string getArchiveTitle(const zim::Archive* const archive) { std::string getArchiveTitle(const zim::Archive& archive) {
std::string value = getMetadata(archive, "Title"); std::string value = getMetadata(archive, "Title");
if (value.empty()) { if (value.empty()) {
value = getLastPathElement(archive->getFilename()); value = getLastPathElement(archive.getFilename());
std::replace(value.begin(), value.end(), '_', ' '); std::replace(value.begin(), value.end(), '_', ' ');
size_t pos = value.find(".zim"); size_t pos = value.find(".zim");
value = value.substr(0, pos); value = value.substr(0, pos);
@ -46,7 +46,7 @@ std::string getArchiveTitle(const zim::Archive* const archive) {
return value; return value;
} }
std::string getMetaDescription(const zim::Archive* const archive) { std::string getMetaDescription(const zim::Archive& archive) {
std::string value; std::string value;
value = getMetadata(archive, "Description"); value = getMetadata(archive, "Description");
@ -58,7 +58,7 @@ std::string getMetaDescription(const zim::Archive* const archive) {
return value; return value;
} }
std::string getMetaTags(const zim::Archive* const archive, bool original) { std::string getMetaTags(const zim::Archive& archive, bool original) {
std::string tags_str = getMetadata(archive, "Tags"); std::string tags_str = getMetadata(archive, "Tags");
if (original) { if (original) {
return tags_str; return tags_str;
@ -67,11 +67,10 @@ std::string getMetaTags(const zim::Archive* const archive, bool original) {
return join(tags, ";"); return join(tags, ";");
} }
bool getArchiveFavicon(const zim::Archive* const archive, bool getArchiveFavicon(const zim::Archive& archive,
std::string& content, std::string& mimeType){ std::string& content, std::string& mimeType){
try { try {
auto entry = archive->getFaviconEntry(); auto item = archive.getIllustrationItem();
auto item = entry.getItem(true);
content = item.getData(); content = item.getData();
mimeType = item.getMimetype(); mimeType = item.getMimetype();
return true; return true;
@ -80,29 +79,41 @@ bool getArchiveFavicon(const zim::Archive* const archive,
return false; return false;
} }
std::string getMetaLanguage(const zim::Archive* const archive) { std::string getMetaLanguage(const zim::Archive& archive) {
return getMetadata(archive, "Language"); return getMetadata(archive, "Language");
} }
std::string getMetaName(const zim::Archive* const archive) { std::string getMetaName(const zim::Archive& archive) {
return getMetadata(archive, "Name"); return getMetadata(archive, "Name");
} }
std::string getMetaDate(const zim::Archive* const archive) { std::string getMetaDate(const zim::Archive& archive) {
return getMetadata(archive, "Date"); return getMetadata(archive, "Date");
} }
std::string getMetaCreator(const zim::Archive* const archive) { std::string getMetaCreator(const zim::Archive& archive) {
return getMetadata(archive, "Creator"); return getMetadata(archive, "Creator");
} }
std::string getMetaPublisher(const zim::Archive* const archive) { std::string getMetaPublisher(const zim::Archive& archive) {
return getMetadata(archive, "Publisher"); return getMetadata(archive, "Publisher");
} }
zim::Entry getFinalEntry(const zim::Archive* const archive, const zim::Entry& entry) zim::Item getFinalItem(const zim::Archive& archive, const zim::Entry& entry)
{ {
return archive->getEntryByPath(entry.getItem(true).getPath()); return entry.getItem(true);
}
zim::Entry getEntryFromPath(const zim::Archive& archive, const std::string& path)
{
try {
return archive.getEntryByPath(path);
} catch (zim::EntryNotFound& e) {
if (path.empty() || path == "/") {
return archive.getMainEntry();
}
}
throw zim::EntryNotFound("Cannot find entry for non empty path");
} }
} // kiwix } // kiwix