Make the OPDSDumper use the ServerConfiguration.

This commit is contained in:
Matthieu Gautier 2022-10-07 11:40:15 +02:00
parent 3e54e56291
commit 6815a4c6a9
4 changed files with 34 additions and 48 deletions

View File

@ -23,11 +23,11 @@
#include <time.h> #include <time.h>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <vector>
#include <pugixml.hpp> #include <pugixml.hpp>
#include "library.h" #include "server.h"
#include "name_mapper.h"
using namespace std; using namespace std;
@ -41,8 +41,7 @@ namespace kiwix
class OPDSDumper class OPDSDumper
{ {
public: public:
OPDSDumper() = default; OPDSDumper(Server::Configuration configuration);
OPDSDumper(std::shared_ptr<Library> library, std::shared_ptr<NameMapper> NameMapper);
~OPDSDumper(); ~OPDSDumper();
/** /**
@ -93,13 +92,6 @@ class OPDSDumper
*/ */
void setLibraryId(const std::string& id) { this->libraryId = id;} void setLibraryId(const std::string& id) { this->libraryId = id;}
/**
* Set the root location used when generating url.
*
* @param rootLocation the root location to use.
*/
void setRootLocation(const std::string& rootLocation) { this->rootLocation = rootLocation; }
/** /**
* Set some informations about the search results. * Set some informations about the search results.
* *
@ -110,10 +102,8 @@ class OPDSDumper
void setOpenSearchInfo(int totalResult, int startIndex, int count); void setOpenSearchInfo(int totalResult, int startIndex, int count);
protected: protected:
std::shared_ptr<kiwix::Library> library; Server::Configuration m_configuration;
std::shared_ptr<kiwix::NameMapper> nameMapper;
std::string libraryId; std::string libraryId;
std::string rootLocation;
int m_totalResults; int m_totalResults;
int m_startIndex; int m_startIndex;
int m_count; int m_count;

View File

@ -19,6 +19,8 @@
#include "opds_dumper.h" #include "opds_dumper.h"
#include "book.h" #include "book.h"
#include "library.h"
#include "name_mapper.h"
#include "libkiwix-resources.h" #include "libkiwix-resources.h"
#include <mustache.hpp> #include <mustache.hpp>
@ -30,9 +32,8 @@ namespace kiwix
{ {
/* Constructor */ /* Constructor */
OPDSDumper::OPDSDumper(std::shared_ptr<Library> library, std::shared_ptr<NameMapper> nameMapper) OPDSDumper::OPDSDumper(Server::Configuration configuration)
: library(library), : m_configuration(configuration)
nameMapper(nameMapper)
{ {
} }
/* Destructor */ /* Destructor */
@ -72,11 +73,11 @@ IllustrationInfo getBookIllustrationInfo(const Book& book)
return illustrations; return illustrations;
} }
std::string fullEntryXML(const Book& book, const std::string& rootLocation, const std::string& bookName) std::string fullEntryXML(const Server::Configuration& configuration, const Book& book, const std::string& bookName)
{ {
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{
{"root", rootLocation}, {"root", configuration.m_root},
{"id", book.getId()}, {"id", book.getId()},
{"name", book.getName()}, {"name", book.getName()},
{"title", book.getTitle()}, {"title", book.getTitle()},
@ -99,12 +100,12 @@ std::string fullEntryXML(const Book& book, const std::string& rootLocation, cons
return render_template(RESOURCE::templates::catalog_v2_entry_xml, data); return render_template(RESOURCE::templates::catalog_v2_entry_xml, data);
} }
std::string partialEntryXML(const Book& book, const std::string& rootLocation) std::string partialEntryXML(const Server::Configuration& configuration, const Book& book)
{ {
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{
{"root", rootLocation}, {"root", configuration.m_root},
{"endpoint_root", rootLocation + "/catalog/v2"}, {"endpoint_root", configuration.m_root + "/catalog/v2"},
{"id", book.getId()}, {"id", book.getId()},
{"title", book.getTitle()}, {"title", book.getTitle()},
{"updated", bookDate}, // XXX: this should be the entry update datetime {"updated", bookDate}, // XXX: this should be the entry update datetime
@ -113,16 +114,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 NameMapper& nameMapper, const std::vector<std::string>& bookIds, const std::string& rootLocation, bool partial) BooksData getBooksData(const Server::Configuration& configuration, const std::vector<std::string>& bookIds, 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 = configuration.mp_library->getBookByIdThreadSafe(bookId);
const std::string bookName = nameMapper.getNameForId(bookId); const std::string bookName = configuration.mp_nameMapper->getNameForId(bookId);
const auto entryXML = partial const auto entryXML = partial
? partialEntryXML(book, rootLocation) ? partialEntryXML(configuration, book)
: fullEntryXML(book, rootLocation, bookName); : fullEntryXML(configuration, book, bookName);
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
@ -190,10 +191,10 @@ 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, *nameMapper, bookIds, rootLocation, false); const auto booksData = getBooksData(m_configuration, bookIds, false);
const kainjow::mustache::object template_data{ const kainjow::mustache::object template_data{
{"date", gen_date_str()}, {"date", gen_date_str()},
{"root", rootLocation}, {"root", m_configuration.m_root},
{"feed_id", gen_uuid(libraryId + "/catalog/search?"+query)}, {"feed_id", gen_uuid(libraryId + "/catalog/search?"+query)},
{"filter", onlyAsNonEmptyMustacheValue(query)}, {"filter", onlyAsNonEmptyMustacheValue(query)},
{"totalResults", to_string(m_totalResults)}, {"totalResults", to_string(m_totalResults)},
@ -207,8 +208,8 @@ 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 = m_configuration.m_root + "/catalog/v2";
const auto booksData = getBooksData(*library, *nameMapper, bookIds, rootLocation, partial); const auto booksData = getBooksData(m_configuration, bookIds, 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{
@ -229,18 +230,18 @@ 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 = m_configuration.mp_library->getBookById(bookId);
const std::string bookName = nameMapper->getNameForId(bookId); const std::string bookName = m_configuration.mp_nameMapper->getNameForId(bookId);
return XML_HEADER return XML_HEADER
+ "\n" + "\n"
+ fullEntryXML(book, rootLocation, bookName); + fullEntryXML(m_configuration, book, bookName);
} }
std::string OPDSDumper::categoriesOPDSFeed() const std::string OPDSDumper::categoriesOPDSFeed() const
{ {
const auto now = gen_date_str(); const auto now = gen_date_str();
kainjow::mustache::list categoryData; kainjow::mustache::list categoryData;
for ( const auto& category : library->getBooksCategories() ) { for ( const auto& category : m_configuration.mp_library->getBooksCategories() ) {
const auto urlencodedCategoryName = urlEncode(category); const auto urlencodedCategoryName = urlEncode(category);
categoryData.push_back(kainjow::mustache::object{ categoryData.push_back(kainjow::mustache::object{
{"name", category}, {"name", category},
@ -254,7 +255,7 @@ std::string OPDSDumper::categoriesOPDSFeed() const
RESOURCE::templates::catalog_v2_categories_xml, RESOURCE::templates::catalog_v2_categories_xml,
kainjow::mustache::object{ kainjow::mustache::object{
{"date", now}, {"date", now},
{"endpoint_root", rootLocation + "/catalog/v2"}, {"endpoint_root", m_configuration.m_root + "/catalog/v2"},
{"feed_id", gen_uuid(libraryId + "/categories")}, {"feed_id", gen_uuid(libraryId + "/categories")},
{"categories", categoryData } {"categories", categoryData }
} }
@ -266,7 +267,7 @@ std::string OPDSDumper::languagesOPDSFeed() const
const auto now = gen_date_str(); const auto now = gen_date_str();
kainjow::mustache::list languageData; kainjow::mustache::list languageData;
std::call_once(fillLanguagesFlag, fillLanguagesMap); std::call_once(fillLanguagesFlag, fillLanguagesMap);
for ( const auto& langAndBookCount : library->getBooksLanguagesWithCounts() ) { for ( const auto& langAndBookCount : m_configuration.mp_library->getBooksLanguagesWithCounts() ) {
const std::string languageCode = langAndBookCount.first; const std::string languageCode = langAndBookCount.first;
const int bookCount = langAndBookCount.second; const int bookCount = langAndBookCount.second;
const auto languageSelfName = getLanguageSelfName(languageCode); const auto languageSelfName = getLanguageSelfName(languageCode);
@ -283,7 +284,7 @@ std::string OPDSDumper::languagesOPDSFeed() const
RESOURCE::templates::catalog_v2_languages_xml, RESOURCE::templates::catalog_v2_languages_xml,
kainjow::mustache::object{ kainjow::mustache::object{
{"date", now}, {"date", now},
{"endpoint_root", rootLocation + "/catalog/v2"}, {"endpoint_root", m_configuration.m_root + "/catalog/v2"},
{"feed_id", gen_uuid(libraryId + "/languages")}, {"feed_id", gen_uuid(libraryId + "/languages")},
{"languages", languageData } {"languages", languageData }
} }

View File

@ -932,8 +932,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog(const RequestContext& r
} }
zim::Uuid uuid; zim::Uuid uuid;
kiwix::OPDSDumper opdsDumper(mp_library, mp_nameMapper); kiwix::OPDSDumper opdsDumper(*this);
opdsDumper.setRootLocation(m_root);
opdsDumper.setLibraryId(m_library_id); opdsDumper.setLibraryId(m_library_id);
std::vector<std::string> bookIdsToDump; std::vector<std::string> bookIdsToDump;
if (url == "root.xml") { if (url == "root.xml") {

View File

@ -95,8 +95,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, mp_nameMapper); OPDSDumper opdsDumper(*this);
opdsDumper.setRootLocation(m_root);
opdsDumper.setLibraryId(m_library_id); opdsDumper.setLibraryId(m_library_id);
const auto bookIds = search_catalog(request, opdsDumper); const auto bookIds = search_catalog(request, opdsDumper);
const auto opdsFeed = opdsDumper.dumpOPDSFeedV2(bookIds, request.get_query(), partial); const auto opdsFeed = opdsDumper.dumpOPDSFeedV2(bookIds, request.get_query(), partial);
@ -116,8 +115,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_complete_entry(const
+ urlNotFoundMsg; + urlNotFoundMsg;
} }
OPDSDumper opdsDumper(mp_library, mp_nameMapper); OPDSDumper opdsDumper(*this);
opdsDumper.setRootLocation(m_root);
opdsDumper.setLibraryId(m_library_id); opdsDumper.setLibraryId(m_library_id);
const auto opdsFeed = opdsDumper.dumpOPDSCompleteEntry(entryId); const auto opdsFeed = opdsDumper.dumpOPDSCompleteEntry(entryId);
return ContentResponse::build( return ContentResponse::build(
@ -129,8 +127,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, mp_nameMapper); OPDSDumper opdsDumper(*this);
opdsDumper.setRootLocation(m_root);
opdsDumper.setLibraryId(m_library_id); opdsDumper.setLibraryId(m_library_id);
return ContentResponse::build( return ContentResponse::build(
*this, *this,
@ -141,8 +138,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, mp_nameMapper); OPDSDumper opdsDumper(*this);
opdsDumper.setRootLocation(m_root);
opdsDumper.setLibraryId(m_library_id); opdsDumper.setLibraryId(m_library_id);
return ContentResponse::build( return ContentResponse::build(
*this, *this,