mirror of https://github.com/kiwix/libkiwix.git
Make the OPDSDumper use the ServerConfiguration.
This commit is contained in:
parent
3e54e56291
commit
6815a4c6a9
|
@ -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;
|
||||||
|
|
|
@ -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 }
|
||||||
}
|
}
|
||||||
|
|
|
@ -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") {
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in New Issue