mirror of https://github.com/kiwix/libkiwix.git
Drop usage of Reader from InternalServer::handle_meta
This is essentially a code move of meta handlers from using Reader functions to directly using Archive.
This commit is contained in:
parent
940368b8ac
commit
7d68926539
|
@ -7,6 +7,7 @@ files=(
|
||||||
"include/common/otherTools.h"
|
"include/common/otherTools.h"
|
||||||
"include/common/regexTools.h"
|
"include/common/regexTools.h"
|
||||||
"include/common/networkTools.h"
|
"include/common/networkTools.h"
|
||||||
|
"include/common/archiveTools.h"
|
||||||
"include/manager.h"
|
"include/manager.h"
|
||||||
"include/reader.h"
|
"include/reader.h"
|
||||||
"include/kiwix.h"
|
"include/kiwix.h"
|
||||||
|
@ -22,6 +23,7 @@ files=(
|
||||||
"src/common/pathTools.cpp"
|
"src/common/pathTools.cpp"
|
||||||
"src/common/regexTools.cpp"
|
"src/common/regexTools.cpp"
|
||||||
"src/common/otherTools.cpp"
|
"src/common/otherTools.cpp"
|
||||||
|
"src/common/archiveTools.cpp"
|
||||||
"src/common/networkTools.cpp"
|
"src/common/networkTools.cpp"
|
||||||
"src/common/stringTools.cpp"
|
"src/common/stringTools.cpp"
|
||||||
"src/xapianSearcher.cpp"
|
"src/xapianSearcher.cpp"
|
||||||
|
|
|
@ -25,6 +25,7 @@ install_headers(
|
||||||
'tools/pathTools.h',
|
'tools/pathTools.h',
|
||||||
'tools/regexTools.h',
|
'tools/regexTools.h',
|
||||||
'tools/stringTools.h',
|
'tools/stringTools.h',
|
||||||
|
'tools/archiveTools.h',
|
||||||
subdir:'kiwix/tools'
|
subdir:'kiwix/tools'
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Maneesh P M <manu.pm55@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef KIWIX_ARCHIVETOOLS_H
|
||||||
|
#define KIWIX_ARCHIVETOOLS_H
|
||||||
|
|
||||||
|
#include <zim/archive.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This file contains all the functions that would make handling data related to
|
||||||
|
* an archive easier.
|
||||||
|
**/
|
||||||
|
|
||||||
|
namespace kiwix
|
||||||
|
{
|
||||||
|
std::string getMetadata(const zim::Archive* const archive, const std::string& name);
|
||||||
|
std::string getArchiveTitle(const zim::Archive* const archive);
|
||||||
|
std::string getMetaDescription(const zim::Archive* const archive);
|
||||||
|
std::string getMetaTags(const zim::Archive* const archive, bool original = false);
|
||||||
|
bool getArchiveFavicon(const zim::Archive* const archive,
|
||||||
|
std::string& content, std::string& mimeType);
|
||||||
|
std::string getMetaLanguage(const zim::Archive* const archive);
|
||||||
|
std::string getMetaName(const zim::Archive* const archive);
|
||||||
|
std::string getMetaDate(const zim::Archive* const archive);
|
||||||
|
std::string getMetaCreator(const zim::Archive* const archive);
|
||||||
|
std::string getMetaPublisher(const zim::Archive* const archive);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
|
@ -19,6 +19,7 @@ kiwix_sources = [
|
||||||
'tools/stringTools.cpp',
|
'tools/stringTools.cpp',
|
||||||
'tools/networkTools.cpp',
|
'tools/networkTools.cpp',
|
||||||
'tools/otherTools.cpp',
|
'tools/otherTools.cpp',
|
||||||
|
'tools/archiveTools.cpp',
|
||||||
'kiwixserve.cpp',
|
'kiwixserve.cpp',
|
||||||
'name_mapper.cpp',
|
'name_mapper.cpp',
|
||||||
'server/byte_range.cpp',
|
'server/byte_range.cpp',
|
||||||
|
|
|
@ -25,6 +25,7 @@
|
||||||
#include <zim/error.h>
|
#include <zim/error.h>
|
||||||
|
|
||||||
#include "tools/otherTools.h"
|
#include "tools/otherTools.h"
|
||||||
|
#include "tools/archiveTools.h"
|
||||||
|
|
||||||
inline char hi(char v)
|
inline char hi(char v)
|
||||||
{
|
{
|
||||||
|
@ -188,14 +189,7 @@ Entry Reader::getMainPage() const
|
||||||
|
|
||||||
bool Reader::getFavicon(string& content, string& mimeType) const
|
bool Reader::getFavicon(string& content, string& mimeType) const
|
||||||
{
|
{
|
||||||
try {
|
return kiwix::getArchiveFavicon(zimArchive.get(), content, mimeType);
|
||||||
auto item = zimArchive->getIllustrationItem();
|
|
||||||
content = item.getData();
|
|
||||||
mimeType = item.getMimetype();
|
|
||||||
return true;
|
|
||||||
} catch(zim::EntryNotFound& e) {};
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string Reader::getZimFilePath() const
|
string Reader::getZimFilePath() const
|
||||||
|
@ -217,47 +211,32 @@ bool Reader::getMetadata(const string& name, string& value) const
|
||||||
|
|
||||||
string Reader::getName() const
|
string Reader::getName() const
|
||||||
{
|
{
|
||||||
METADATA("Name")
|
return kiwix::getMetaName(zimArchive.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
string Reader::getTitle() const
|
string Reader::getTitle() const
|
||||||
{
|
{
|
||||||
string value = zimArchive->getMetadata("Title");
|
return kiwix::getArchiveTitle(zimArchive.get());
|
||||||
if (value.empty()) {
|
|
||||||
value = getLastPathElement(zimFilePath);
|
|
||||||
std::replace(value.begin(), value.end(), '_', ' ');
|
|
||||||
size_t pos = value.find(".zim");
|
|
||||||
value = value.substr(0, pos);
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string Reader::getCreator() const
|
string Reader::getCreator() const
|
||||||
{
|
{
|
||||||
METADATA("Creator")
|
return kiwix::getMetaCreator(zimArchive.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
string Reader::getPublisher() const
|
string Reader::getPublisher() const
|
||||||
{
|
{
|
||||||
METADATA("Publisher")
|
return kiwix::getMetaPublisher(zimArchive.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
string Reader::getDate() const
|
string Reader::getDate() const
|
||||||
{
|
{
|
||||||
METADATA("Date")
|
return kiwix::getMetaDate(zimArchive.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
string Reader::getDescription() const
|
string Reader::getDescription() const
|
||||||
{
|
{
|
||||||
string value;
|
return kiwix::getMetaDescription(zimArchive.get());
|
||||||
this->getMetadata("Description", value);
|
|
||||||
|
|
||||||
/* Mediawiki Collection tends to use the "Subtitle" name */
|
|
||||||
if (value.empty()) {
|
|
||||||
this->getMetadata("Subtitle", value);
|
|
||||||
}
|
|
||||||
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
string Reader::getLongDescription() const
|
string Reader::getLongDescription() const
|
||||||
|
@ -267,7 +246,7 @@ string Reader::getLongDescription() const
|
||||||
|
|
||||||
string Reader::getLanguage() const
|
string Reader::getLanguage() const
|
||||||
{
|
{
|
||||||
METADATA("Language")
|
return kiwix::getMetaLanguage(zimArchive.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
string Reader::getLicense() const
|
string Reader::getLicense() const
|
||||||
|
@ -277,13 +256,7 @@ string Reader::getLicense() const
|
||||||
|
|
||||||
string Reader::getTags(bool original) const
|
string Reader::getTags(bool original) const
|
||||||
{
|
{
|
||||||
string tags_str;
|
return kiwix::getMetaTags(zimArchive.get(), original);
|
||||||
getMetadata("Tags", tags_str);
|
|
||||||
if (original) {
|
|
||||||
return tags_str;
|
|
||||||
}
|
|
||||||
auto tags = convertTags(tags_str);
|
|
||||||
return join(tags, ";");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,7 @@ extern "C" {
|
||||||
#include "tools/pathTools.h"
|
#include "tools/pathTools.h"
|
||||||
#include "tools/regexTools.h"
|
#include "tools/regexTools.h"
|
||||||
#include "tools/stringTools.h"
|
#include "tools/stringTools.h"
|
||||||
|
#include "tools/archiveTools.h"
|
||||||
#include "library.h"
|
#include "library.h"
|
||||||
#include "name_mapper.h"
|
#include "name_mapper.h"
|
||||||
#include "entry.h"
|
#include "entry.h"
|
||||||
|
@ -55,6 +56,7 @@ extern "C" {
|
||||||
#include "opds_dumper.h"
|
#include "opds_dumper.h"
|
||||||
|
|
||||||
#include <zim/uuid.h>
|
#include <zim/uuid.h>
|
||||||
|
#include <zim/error.h>
|
||||||
|
|
||||||
#include <mustache.hpp>
|
#include <mustache.hpp>
|
||||||
|
|
||||||
|
@ -323,22 +325,95 @@ std::unique_ptr<Response> InternalServer::build_homepage(const RequestContext& r
|
||||||
return ContentResponse::build(*this, RESOURCE::templates::index_html, get_default_data(), "text/html; charset=utf-8", true);
|
return ContentResponse::build(*this, RESOURCE::templates::index_html, get_default_data(), "text/html; charset=utf-8", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Archive and Zim handlers begin
|
||||||
|
**/
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
**/
|
||||||
|
|
||||||
std::unique_ptr<Response> InternalServer::handle_meta(const RequestContext& request)
|
std::unique_ptr<Response> InternalServer::handle_meta(const RequestContext& request)
|
||||||
{
|
{
|
||||||
std::string bookName;
|
std::string bookName;
|
||||||
std::string bookId;
|
std::string bookId;
|
||||||
std::string meta_name;
|
std::string meta_name;
|
||||||
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);
|
||||||
meta_name = request.get_argument("name");
|
meta_name = request.get_argument("name");
|
||||||
reader = mp_library->getReaderById(bookId);
|
archive = mp_library->getArchiveById(bookId);
|
||||||
} catch (const std::out_of_range& e) {
|
} catch (const std::out_of_range& e) {
|
||||||
return Response::build_404(*this, request, bookName, "");
|
return Response::build_404(*this, request, bookName, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reader == nullptr) {
|
if (archive == nullptr) {
|
||||||
return Response::build_404(*this, request, bookName, "");
|
return Response::build_404(*this, request, bookName, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,23 +421,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 = reader->getTitle();
|
content = getArchiveTitle(archive.get());
|
||||||
} else if (meta_name == "description") {
|
} else if (meta_name == "description") {
|
||||||
content = reader->getDescription();
|
content = getMetaDescription(archive.get());
|
||||||
} else if (meta_name == "language") {
|
} else if (meta_name == "language") {
|
||||||
content = reader->getLanguage();
|
content = getMetaLanguage(archive.get());
|
||||||
} else if (meta_name == "name") {
|
} else if (meta_name == "name") {
|
||||||
content = reader->getName();
|
content = getMetaName(archive.get());
|
||||||
} else if (meta_name == "tags") {
|
} else if (meta_name == "tags") {
|
||||||
content = reader->getTags();
|
content = getMetaTags(archive.get());
|
||||||
} else if (meta_name == "date") {
|
} else if (meta_name == "date") {
|
||||||
content = reader->getDate();
|
content = getMetaDate(archive.get());
|
||||||
} else if (meta_name == "creator") {
|
} else if (meta_name == "creator") {
|
||||||
content = reader->getCreator();
|
content = getMetaCreator(archive.get());
|
||||||
} else if (meta_name == "publisher") {
|
} else if (meta_name == "publisher") {
|
||||||
content = reader->getPublisher();
|
content = getMetaPublisher(archive.get());
|
||||||
} else if (meta_name == "favicon") {
|
} else if (meta_name == "favicon") {
|
||||||
reader->getFavicon(content, mimeType);
|
getArchiveFavicon(archive.get(), content, mimeType);
|
||||||
} else {
|
} else {
|
||||||
return Response::build_404(*this, request, bookName, "");
|
return Response::build_404(*this, request, bookName, "");
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2021 Maneesh P M <manu.pm55@gmail.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
|
||||||
|
* MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <tools/archiveTools.h>
|
||||||
|
#include <tools/pathTools.h>
|
||||||
|
#include <tools/otherTools.h>
|
||||||
|
#include <tools/stringTools.h>
|
||||||
|
|
||||||
|
#include <zim/error.h>
|
||||||
|
#include <zim/item.h>
|
||||||
|
|
||||||
|
namespace kiwix
|
||||||
|
{
|
||||||
|
std::string getMetadata(const zim::Archive* const archive, const std::string& name) {
|
||||||
|
try {
|
||||||
|
return archive->getMetadata(name);
|
||||||
|
} catch (zim::EntryNotFound& e) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getArchiveTitle(const zim::Archive* const archive) {
|
||||||
|
std::string value = getMetadata(archive, "Title");
|
||||||
|
if (value.empty()) {
|
||||||
|
value = getLastPathElement(archive->getFilename());
|
||||||
|
std::replace(value.begin(), value.end(), '_', ' ');
|
||||||
|
size_t pos = value.find(".zim");
|
||||||
|
value = value.substr(0, pos);
|
||||||
|
}
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getMetaDescription(const zim::Archive* const archive) {
|
||||||
|
std::string value;
|
||||||
|
value = getMetadata(archive, "Description");
|
||||||
|
|
||||||
|
/* Mediawiki Collection tends to use the "Subtitle" name */
|
||||||
|
if (value.empty()) {
|
||||||
|
value = getMetadata(archive, "Subtitle");
|
||||||
|
}
|
||||||
|
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getMetaTags(const zim::Archive* const archive, bool original) {
|
||||||
|
std::string tags_str = getMetadata(archive, "Tags");
|
||||||
|
if (original) {
|
||||||
|
return tags_str;
|
||||||
|
}
|
||||||
|
auto tags = convertTags(tags_str);
|
||||||
|
return join(tags, ";");
|
||||||
|
}
|
||||||
|
|
||||||
|
bool getArchiveFavicon(const zim::Archive* const archive,
|
||||||
|
std::string& content, std::string& mimeType){
|
||||||
|
try {
|
||||||
|
auto entry = archive->getFaviconEntry();
|
||||||
|
auto item = entry.getItem(true);
|
||||||
|
content = item.getData();
|
||||||
|
mimeType = item.getMimetype();
|
||||||
|
return true;
|
||||||
|
} catch(zim::EntryNotFound& e) {};
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getMetaLanguage(const zim::Archive* const archive) {
|
||||||
|
return getMetadata(archive, "Language");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getMetaName(const zim::Archive* const archive) {
|
||||||
|
return getMetadata(archive, "Name");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getMetaDate(const zim::Archive* const archive) {
|
||||||
|
return getMetadata(archive, "Date");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getMetaCreator(const zim::Archive* const archive) {
|
||||||
|
return getMetadata(archive, "Creator");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string getMetaPublisher(const zim::Archive* const archive) {
|
||||||
|
return getMetadata(archive, "Publisher");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // kiwix
|
Loading…
Reference in New Issue