Merge pull request #837 from kiwix/opds_name_mapper_bis

Make OPDSDumper respect the NameMapper of the server.
This commit is contained in:
Kelson 2022-10-31 09:14:55 +01:00 committed by GitHub
commit 8cc1c47133
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 140 additions and 79 deletions

View File

@ -27,6 +27,7 @@
#include <pugixml.hpp> #include <pugixml.hpp>
#include "library.h" #include "library.h"
#include "name_mapper.h"
using namespace std; using namespace std;
@ -41,7 +42,7 @@ class OPDSDumper
{ {
public: public:
OPDSDumper() = default; OPDSDumper() = default;
OPDSDumper(Library* library); OPDSDumper(Library* library, NameMapper* NameMapper);
~OPDSDumper(); ~OPDSDumper();
/** /**
@ -110,6 +111,7 @@ class OPDSDumper
protected: protected:
kiwix::Library* library; kiwix::Library* library;
kiwix::NameMapper* nameMapper;
std::string libraryId; std::string libraryId;
std::string rootLocation; std::string rootLocation;
int m_totalResults; int m_totalResults;

View File

@ -30,8 +30,9 @@ namespace kiwix
{ {
/* Constructor */ /* Constructor */
OPDSDumper::OPDSDumper(Library* library) OPDSDumper::OPDSDumper(Library* library, NameMapper* nameMapper)
: library(library) : library(library),
nameMapper(nameMapper)
{ {
} }
/* Destructor */ /* Destructor */
@ -71,7 +72,7 @@ IllustrationInfo getBookIllustrationInfo(const Book& book)
return illustrations; return illustrations;
} }
std::string fullEntryXML(const Book& book, const std::string& rootLocation) std::string fullEntryXML(const Book& book, const std::string& rootLocation, const std::string& contentId)
{ {
const auto bookDate = book.getDate() + "T00:00:00Z"; const auto bookDate = book.getDate() + "T00:00:00Z";
const kainjow::mustache::object data{ const kainjow::mustache::object data{
@ -81,7 +82,7 @@ std::string fullEntryXML(const Book& book, const std::string& rootLocation)
{"title", book.getTitle()}, {"title", book.getTitle()},
{"description", book.getDescription()}, {"description", book.getDescription()},
{"language", book.getLanguage()}, {"language", book.getLanguage()},
{"content_id", urlEncode(book.getHumanReadableIdFromPath(), true)}, {"content_id", urlEncode(contentId, true)},
{"updated", bookDate}, // XXX: this should be the entry update datetime {"updated", bookDate}, // XXX: this should be the entry update datetime
{"book_date", bookDate}, {"book_date", bookDate},
{"category", book.getCategory()}, {"category", book.getCategory()},
@ -112,15 +113,16 @@ std::string partialEntryXML(const Book& book, const std::string& rootLocation)
return render_template(xmlTemplate, data); return render_template(xmlTemplate, data);
} }
BooksData getBooksData(const Library* library, const std::vector<std::string>& bookIds, const std::string& rootLocation, bool partial) BooksData getBooksData(const Library* library, const NameMapper* nameMapper, const std::vector<std::string>& bookIds, const std::string& rootLocation, bool partial)
{ {
BooksData booksData; BooksData booksData;
for ( const auto& bookId : bookIds ) { for ( const auto& bookId : bookIds ) {
try { try {
const Book book = library->getBookByIdThreadSafe(bookId); const Book book = library->getBookByIdThreadSafe(bookId);
const std::string contentId = nameMapper->getNameForId(bookId);
const auto entryXML = partial const auto entryXML = partial
? partialEntryXML(book, rootLocation) ? partialEntryXML(book, rootLocation)
: fullEntryXML(book, rootLocation); : fullEntryXML(book, rootLocation, contentId);
booksData.push_back(kainjow::mustache::object{ {"entry", entryXML} }); booksData.push_back(kainjow::mustache::object{ {"entry", entryXML} });
} catch ( const std::out_of_range& ) { } catch ( const std::out_of_range& ) {
// the book was removed from the library since its id was obtained // the book was removed from the library since its id was obtained
@ -188,7 +190,7 @@ std::string getLanguageSelfName(const std::string& lang) {
string OPDSDumper::dumpOPDSFeed(const std::vector<std::string>& bookIds, const std::string& query) const string OPDSDumper::dumpOPDSFeed(const std::vector<std::string>& bookIds, const std::string& query) const
{ {
const auto booksData = getBooksData(library, bookIds, rootLocation, false); const auto booksData = getBooksData(library, nameMapper, bookIds, rootLocation, false);
const kainjow::mustache::object template_data{ const kainjow::mustache::object template_data{
{"date", gen_date_str()}, {"date", gen_date_str()},
{"root", rootLocation}, {"root", rootLocation},
@ -206,7 +208,7 @@ string OPDSDumper::dumpOPDSFeed(const std::vector<std::string>& bookIds, const s
string OPDSDumper::dumpOPDSFeedV2(const std::vector<std::string>& bookIds, const std::string& query, bool partial) const string OPDSDumper::dumpOPDSFeedV2(const std::vector<std::string>& bookIds, const std::string& query, bool partial) const
{ {
const auto endpointRoot = rootLocation + "/catalog/v2"; const auto endpointRoot = rootLocation + "/catalog/v2";
const auto booksData = getBooksData(library, bookIds, rootLocation, partial); const auto booksData = getBooksData(library, nameMapper, bookIds, rootLocation, partial);
const char* const endpoint = partial ? "/partial_entries" : "/entries"; const char* const endpoint = partial ? "/partial_entries" : "/entries";
const kainjow::mustache::object template_data{ const kainjow::mustache::object template_data{
@ -228,9 +230,10 @@ string OPDSDumper::dumpOPDSFeedV2(const std::vector<std::string>& bookIds, const
std::string OPDSDumper::dumpOPDSCompleteEntry(const std::string& bookId) const std::string OPDSDumper::dumpOPDSCompleteEntry(const std::string& bookId) const
{ {
const auto book = library->getBookById(bookId); const auto book = library->getBookById(bookId);
const std::string contentId = nameMapper->getNameForId(bookId);
return XML_HEADER return XML_HEADER
+ "\n" + "\n"
+ fullEntryXML(book, rootLocation); + fullEntryXML(book, rootLocation, contentId);
} }
std::string OPDSDumper::categoriesOPDSFeed() const std::string OPDSDumper::categoriesOPDSFeed() const

View File

@ -992,7 +992,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog(const RequestContext& r
} }
zim::Uuid uuid; zim::Uuid uuid;
kiwix::OPDSDumper opdsDumper(mp_library); kiwix::OPDSDumper opdsDumper(mp_library, mp_nameMapper);
opdsDumper.setRootLocation(m_root); opdsDumper.setRootLocation(m_root);
opdsDumper.setLibraryId(getLibraryId()); opdsDumper.setLibraryId(getLibraryId());
std::vector<std::string> bookIdsToDump; std::vector<std::string> bookIdsToDump;

View File

@ -96,7 +96,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_root(const RequestCo
std::unique_ptr<Response> InternalServer::handle_catalog_v2_entries(const RequestContext& request, bool partial) std::unique_ptr<Response> InternalServer::handle_catalog_v2_entries(const RequestContext& request, bool partial)
{ {
OPDSDumper opdsDumper(mp_library); OPDSDumper opdsDumper(mp_library, mp_nameMapper);
opdsDumper.setRootLocation(m_root); opdsDumper.setRootLocation(m_root);
opdsDumper.setLibraryId(getLibraryId()); opdsDumper.setLibraryId(getLibraryId());
const auto bookIds = search_catalog(request, opdsDumper); const auto bookIds = search_catalog(request, opdsDumper);
@ -117,7 +117,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_complete_entry(const
+ urlNotFoundMsg; + urlNotFoundMsg;
} }
OPDSDumper opdsDumper(mp_library); OPDSDumper opdsDumper(mp_library, mp_nameMapper);
opdsDumper.setRootLocation(m_root); opdsDumper.setRootLocation(m_root);
opdsDumper.setLibraryId(getLibraryId()); opdsDumper.setLibraryId(getLibraryId());
const auto opdsFeed = opdsDumper.dumpOPDSCompleteEntry(entryId); const auto opdsFeed = opdsDumper.dumpOPDSCompleteEntry(entryId);
@ -130,7 +130,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_complete_entry(const
std::unique_ptr<Response> InternalServer::handle_catalog_v2_categories(const RequestContext& request) std::unique_ptr<Response> InternalServer::handle_catalog_v2_categories(const RequestContext& request)
{ {
OPDSDumper opdsDumper(mp_library); OPDSDumper opdsDumper(mp_library, mp_nameMapper);
opdsDumper.setRootLocation(m_root); opdsDumper.setRootLocation(m_root);
opdsDumper.setLibraryId(getLibraryId()); opdsDumper.setLibraryId(getLibraryId());
return ContentResponse::build( return ContentResponse::build(
@ -142,7 +142,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_categories(const Req
std::unique_ptr<Response> InternalServer::handle_catalog_v2_languages(const RequestContext& request) std::unique_ptr<Response> InternalServer::handle_catalog_v2_languages(const RequestContext& request)
{ {
OPDSDumper opdsDumper(mp_library); OPDSDumper opdsDumper(mp_library, mp_nameMapper);
opdsDumper.setRootLocation(m_root); opdsDumper.setRootLocation(m_root);
opdsDumper.setLibraryId(getLibraryId()); opdsDumper.setLibraryId(getLibraryId());
return ContentResponse::build( return ContentResponse::build(

View File

@ -18,8 +18,13 @@ protected:
const int PORT = 8002; const int PORT = 8002;
protected: protected:
void resetServer(ZimFileServer::Options options) {
zfs1_.reset();
zfs1_.reset(new ZimFileServer(PORT, options, "./test/library.xml"));
}
void SetUp() override { void SetUp() override {
zfs1_.reset(new ZimFileServer(PORT, "./test/library.xml")); zfs1_.reset(new ZimFileServer(PORT, ZimFileServer::DEFAULT_OPTIONS, "./test/library.xml"));
} }
void TearDown() override { void TearDown() override {
@ -70,20 +75,20 @@ std::string maskVariableOPDSFeedData(std::string s)
" type=\"application/opensearchdescription+xml\"" \ " type=\"application/opensearchdescription+xml\"" \
" href=\"/ROOT/catalog/searchdescription.xml\" />\n" " href=\"/ROOT/catalog/searchdescription.xml\" />\n"
#define CHARLES_RAY_CATALOG_ENTRY \ #define CATALOG_ENTRY(UUID, TITLE, SUMMARY, LANG, NAME, CATEGORY, TAGS, EXTRA_LINK, CONTENT_NAME, FILE_NAME, LENGTH) \
" <entry>\n" \ " <entry>\n" \
" <id>urn:uuid:charlesray</id>\n" \ " <id>urn:uuid:" UUID "</id>\n" \
" <title>Charles, Ray</title>\n" \ " <title>" TITLE "</title>\n" \
" <updated>YYYY-MM-DDThh:mm:ssZ</updated>\n" \ " <updated>YYYY-MM-DDThh:mm:ssZ</updated>\n" \
" <summary>Wikipedia articles about Ray Charles</summary>\n" \ " <summary>" SUMMARY "</summary>\n" \
" <language>fra</language>\n" \ " <language>" LANG "</language>\n" \
" <name>wikipedia_fr_ray_charles</name>\n" \ " <name>" NAME "</name>\n" \
" <flavour></flavour>\n" \ " <flavour></flavour>\n" \
" <category>jazz</category>\n" \ " <category>" CATEGORY "</category>\n" \
" <tags>unittest;wikipedia;_category:jazz;_pictures:no;_videos:no;_details:no;_ftindex:yes</tags>\n" \ " <tags>" TAGS "</tags>\n" \
" <articleCount>284</articleCount>\n" \ " <articleCount>284</articleCount>\n" \
" <mediaCount>2</mediaCount>\n" \ " <mediaCount>2</mediaCount>\n" \
" <link type=\"text/html\" href=\"/ROOT/content/zimfile%26other\" />\n" \ " " EXTRA_LINK "<link type=\"text/html\" href=\"/ROOT/content/" CONTENT_NAME "\" />\n" \
" <author>\n" \ " <author>\n" \
" <name>Wikipedia</name>\n" \ " <name>Wikipedia</name>\n" \
" </author>\n" \ " </author>\n" \
@ -91,59 +96,59 @@ std::string maskVariableOPDSFeedData(std::string s)
" <name>Kiwix</name>\n" \ " <name>Kiwix</name>\n" \
" </publisher>\n" \ " </publisher>\n" \
" <dc:issued>2020-03-31T00:00:00Z</dc:issued>\n" \ " <dc:issued>2020-03-31T00:00:00Z</dc:issued>\n" \
" <link rel=\"http://opds-spec.org/acquisition/open-access\" type=\"application/x-zim\" href=\"https://github.com/kiwix/libkiwix/raw/master/test/data/zimfile%26other.zim\" length=\"569344\" />\n" \ " <link rel=\"http://opds-spec.org/acquisition/open-access\" type=\"application/x-zim\" href=\"https://github.com/kiwix/libkiwix/raw/master/test/data/" FILE_NAME ".zim\" length=\"" LENGTH "\" />\n" \
" </entry>\n" " </entry>\n"
#define RAY_CHARLES_CATALOG_ENTRY \
" <entry>\n" \ #define _CHARLES_RAY_CATALOG_ENTRY(CONTENT_NAME) CATALOG_ENTRY( \
" <id>urn:uuid:raycharles</id>\n" \ "charlesray", \
" <title>Ray Charles</title>\n" \ "Charles, Ray", \
" <updated>YYYY-MM-DDThh:mm:ssZ</updated>\n" \ "Wikipedia articles about Ray Charles", \
" <summary>Wikipedia articles about Ray Charles</summary>\n" \ "fra", \
" <language>eng</language>\n" \ "wikipedia_fr_ray_charles",\
" <name>wikipedia_en_ray_charles</name>\n" \ "jazz",\
" <flavour></flavour>\n" \ "unittest;wikipedia;_category:jazz;_pictures:no;_videos:no;_details:no;_ftindex:yes",\
" <category>wikipedia</category>\n" \ "", \
" <tags>public_tag_without_a_value;_private_tag_without_a_value;wikipedia;_category:wikipedia;_pictures:no;_videos:no;_details:no;_ftindex:yes</tags>\n" \ CONTENT_NAME, \
" <articleCount>284</articleCount>\n" \ "zimfile%26other", \
" <mediaCount>2</mediaCount>\n" \ "569344" \
" <link rel=\"http://opds-spec.org/image/thumbnail\"\n" \ )
#define CHARLES_RAY_CATALOG_ENTRY _CHARLES_RAY_CATALOG_ENTRY("zimfile%26other")
#define CHARLES_RAY_CATALOG_ENTRY_NO_MAPPER _CHARLES_RAY_CATALOG_ENTRY("charlesray")
#define _RAY_CHARLES_CATALOG_ENTRY(CONTENT_NAME) CATALOG_ENTRY(\
"raycharles",\
"Ray Charles",\
"Wikipedia articles about Ray Charles",\
"eng",\
"wikipedia_en_ray_charles",\
"wikipedia",\
"public_tag_without_a_value;_private_tag_without_a_value;wikipedia;_category:wikipedia;_pictures:no;_videos:no;_details:no;_ftindex:yes",\
"<link rel=\"http://opds-spec.org/image/thumbnail\"\n" \
" href=\"/ROOT/catalog/v2/illustration/raycharles/?size=48\"\n" \ " href=\"/ROOT/catalog/v2/illustration/raycharles/?size=48\"\n" \
" type=\"image/png;width=48;height=48;scale=1\"/>\n" \ " type=\"image/png;width=48;height=48;scale=1\"/>\n ", \
" <link type=\"text/html\" href=\"/ROOT/content/zimfile\" />\n" \ CONTENT_NAME, \
" <author>\n" \ "zimfile", \
" <name>Wikipedia</name>\n" \ "569344"\
" </author>\n" \ )
" <publisher>\n" \
" <name>Kiwix</name>\n" \
" </publisher>\n" \
" <dc:issued>2020-03-31T00:00:00Z</dc:issued>\n" \
" <link rel=\"http://opds-spec.org/acquisition/open-access\" type=\"application/x-zim\" href=\"https://github.com/kiwix/libkiwix/raw/master/test/data/zimfile.zim\" length=\"569344\" />\n" \
" </entry>\n"
#define UNCATEGORIZED_RAY_CHARLES_CATALOG_ENTRY \ #define RAY_CHARLES_CATALOG_ENTRY _RAY_CHARLES_CATALOG_ENTRY("zimfile")
" <entry>\n" \ #define RAY_CHARLES_CATALOG_ENTRY_NO_MAPPER _RAY_CHARLES_CATALOG_ENTRY("raycharles")
" <id>urn:uuid:raycharles_uncategorized</id>\n" \
" <title>Ray (uncategorized) Charles</title>\n" \ #define UNCATEGORIZED_RAY_CHARLES_CATALOG_ENTRY CATALOG_ENTRY(\
" <updated>YYYY-MM-DDThh:mm:ssZ</updated>\n" \ "raycharles_uncategorized",\
" <summary>No category is assigned to this library entry.</summary>\n" \ "Ray (uncategorized) Charles",\
" <language>rus</language>\n" \ "No category is assigned to this library entry.",\
" <name>wikipedia_ru_ray_charles</name>\n" \ "rus",\
" <flavour></flavour>\n" \ "wikipedia_ru_ray_charles",\
" <category></category>\n" \ "",\
" <tags>public_tag_with_a_value:value_of_a_public_tag;_private_tag_with_a_value:value_of_a_private_tag;wikipedia;_pictures:no;_videos:no;_details:no</tags>\n" \ "public_tag_with_a_value:value_of_a_public_tag;_private_tag_with_a_value:value_of_a_private_tag;wikipedia;_pictures:no;_videos:no;_details:no",\
" <articleCount>284</articleCount>\n" \ "",\
" <mediaCount>2</mediaCount>\n" \ "zimfile", \
" <link type=\"text/html\" href=\"/ROOT/content/zimfile\" />\n" \ "zimfile", \
" <author>\n" \ "125952"\
" <name>Wikipedia</name>\n" \ )
" </author>\n" \
" <publisher>\n" \
" <name>Kiwix</name>\n" \
" </publisher>\n" \
" <dc:issued>2020-03-31T00:00:00Z</dc:issued>\n" \
" <link rel=\"http://opds-spec.org/acquisition/open-access\" type=\"application/x-zim\" href=\"https://github.com/kiwix/libkiwix/raw/master/test/data/zimfile.zim\" length=\"125952\" />\n" \
" </entry>\n"
TEST_F(LibraryServerTest, catalog_root_xml) TEST_F(LibraryServerTest, catalog_root_xml)
{ {
@ -780,4 +785,40 @@ TEST_F(LibraryServerTest, catalog_search_excludes_hidden_tags)
#undef EXPECT_ZERO_RESULTS #undef EXPECT_ZERO_RESULTS
} }
TEST_F(LibraryServerTest, no_name_mapper_returned_catalog_use_uuid_in_link)
{
resetServer(ZimFileServer::NO_NAME_MAPPER);
const auto r = zfs1_->GET("/ROOT/catalog/search?tag=_category:jazz");
EXPECT_EQ(r->status, 200);
EXPECT_EQ(maskVariableOPDSFeedData(r->body),
OPDS_FEED_TAG
" <id>12345678-90ab-cdef-1234-567890abcdef</id>\n"
" <title>Filtered zims (tag=_category:jazz)</title>\n"
" <updated>YYYY-MM-DDThh:mm:ssZ</updated>\n"
" <totalResults>1</totalResults>\n"
" <startIndex>0</startIndex>\n"
" <itemsPerPage>1</itemsPerPage>\n"
CATALOG_LINK_TAGS
CHARLES_RAY_CATALOG_ENTRY_NO_MAPPER
"</feed>\n"
);
}
TEST_F(LibraryServerTest, no_name_mapper_catalog_v2_individual_entry_access)
{
resetServer(ZimFileServer::NO_NAME_MAPPER);
const auto r = zfs1_->GET("/ROOT/catalog/v2/entry/raycharles");
EXPECT_EQ(r->status, 200);
EXPECT_EQ(maskVariableOPDSFeedData(r->body),
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
RAY_CHARLES_CATALOG_ENTRY_NO_MAPPER
);
const auto r1 = zfs1_->GET("/ROOT/catalog/v2/entry/non-existent-entry");
EXPECT_EQ(r1->status, 404);
}
#undef EXPECT_SEARCH_RESULTS #undef EXPECT_SEARCH_RESULTS

View File

@ -209,6 +209,15 @@ TEST_F(ServerTest, 200)
EXPECT_EQ(200, zfs1_->GET(res.url)->status) << "res.url: " << res.url; EXPECT_EQ(200, zfs1_->GET(res.url)->status) << "res.url: " << res.url;
} }
TEST_F(ServerTest, 200_IdNameMapper)
{
EXPECT_EQ(404, zfs1_->GET("/ROOT/content/6f1d19d0-633f-087b-fb55-7ac324ff9baf/A/index")->status);
EXPECT_EQ(200, zfs1_->GET("/ROOT/content/zimfile/A/index")->status);
resetServer(ZimFileServer::NO_NAME_MAPPER);
EXPECT_EQ(200, zfs1_->GET("/ROOT/content/6f1d19d0-633f-087b-fb55-7ac324ff9baf/A/index")->status);
EXPECT_EQ(404, zfs1_->GET("/ROOT/content/zimfile/A/index")->status);
}
TEST_F(ServerTest, CompressibleContentIsCompressedIfAcceptable) TEST_F(ServerTest, CompressibleContentIsCompressedIfAcceptable)
{ {
for ( const Resource& res : resources200Compressible ) { for ( const Resource& res : resources200Compressible ) {

View File

@ -61,6 +61,7 @@ public: // types
WITH_TASKBAR = 1 << 1, WITH_TASKBAR = 1 << 1,
WITH_LIBRARY_BUTTON = 1 << 2, WITH_LIBRARY_BUTTON = 1 << 2,
BLOCK_EXTERNAL_LINKS = 1 << 3, BLOCK_EXTERNAL_LINKS = 1 << 3,
NO_NAME_MAPPER = 1 << 4,
WITH_TASKBAR_AND_LIBRARY_BUTTON = WITH_TASKBAR | WITH_LIBRARY_BUTTON, WITH_TASKBAR_AND_LIBRARY_BUTTON = WITH_TASKBAR | WITH_LIBRARY_BUTTON,
@ -68,7 +69,7 @@ public: // types
}; };
public: // functions public: // functions
ZimFileServer(int serverPort, std::string libraryFilePath); ZimFileServer(int serverPort, Options options, std::string libraryFilePath);
ZimFileServer(int serverPort, ZimFileServer(int serverPort,
Options options, Options options,
const FilePathCollection& zimpaths, const FilePathCollection& zimpaths,
@ -91,14 +92,15 @@ private:
private: // data private: // data
kiwix::Library library; kiwix::Library library;
kiwix::Manager manager; kiwix::Manager manager;
std::unique_ptr<kiwix::HumanReadableNameMapper> nameMapper; std::unique_ptr<kiwix::NameMapper> nameMapper;
std::unique_ptr<kiwix::Server> server; std::unique_ptr<kiwix::Server> server;
std::unique_ptr<httplib::Client> client; std::unique_ptr<httplib::Client> client;
const Options options = DEFAULT_OPTIONS; const Options options = DEFAULT_OPTIONS;
}; };
ZimFileServer::ZimFileServer(int serverPort, std::string libraryFilePath) ZimFileServer::ZimFileServer(int serverPort, Options _options, std::string libraryFilePath)
: manager(&this->library) : manager(&this->library)
, options(_options)
{ {
if ( kiwix::isRelativePath(libraryFilePath) ) if ( kiwix::isRelativePath(libraryFilePath) )
libraryFilePath = kiwix::computeAbsolutePath(kiwix::getCurrentDirectory(), libraryFilePath); libraryFilePath = kiwix::computeAbsolutePath(kiwix::getCurrentDirectory(), libraryFilePath);
@ -123,7 +125,11 @@ ZimFileServer::ZimFileServer(int serverPort,
void ZimFileServer::run(int serverPort, std::string indexTemplateString) void ZimFileServer::run(int serverPort, std::string indexTemplateString)
{ {
const std::string address = "127.0.0.1"; const std::string address = "127.0.0.1";
if (options & NO_NAME_MAPPER) {
nameMapper.reset(new kiwix::IdNameMapper());
} else {
nameMapper.reset(new kiwix::HumanReadableNameMapper(library, false)); nameMapper.reset(new kiwix::HumanReadableNameMapper(library, false));
}
server.reset(new kiwix::Server(&library, nameMapper.get())); server.reset(new kiwix::Server(&library, nameMapper.get()));
server->setRoot("ROOT"); server->setRoot("ROOT");
server->setAddress(address); server->setAddress(address);