diff --git a/src/opds_dumper.cpp b/src/opds_dumper.cpp index 13c9804aa..7436ebc29 100644 --- a/src/opds_dumper.cpp +++ b/src/opds_dumper.cpp @@ -49,6 +49,8 @@ void OPDSDumper::setOpenSearchInfo(int totalResults, int startIndex, int count) namespace { +const std::string XML_HEADER(R"()"); + typedef kainjow::mustache::data MustacheData; typedef kainjow::mustache::list BooksData; typedef kainjow::mustache::list IllustrationInfo; @@ -69,10 +71,11 @@ IllustrationInfo getBookIllustrationInfo(const Book& book) return illustrations; } -kainjow::mustache::object getSingleBookData(const Book& book) +std::string fullEntryXML(const Book& book, const std::string& rootLocation) { const auto bookDate = book.getDate() + "T00:00:00Z"; - return kainjow::mustache::object{ + const kainjow::mustache::object data{ + {"root", rootLocation}, {"id", book.getId()}, {"name", book.getName()}, {"title", book.getTitle()}, @@ -92,27 +95,33 @@ kainjow::mustache::object getSingleBookData(const Book& book) {"size", to_string(book.getSize())}, {"icons", getBookIllustrationInfo(book)}, }; + return render_template(RESOURCE::templates::catalog_v2_entry_xml, data); } -std::string getSingleBookEntryXML(const Book& book, bool withXMLHeader, const std::string& rootLocation, const std::string& endpointRoot, bool partial) +std::string partialEntryXML(const Book& book, const std::string& rootLocation) { - auto data = getSingleBookData(book); - data["with_xml_header"] = MustacheData(withXMLHeader); - data["dump_partial_entries"] = MustacheData(partial); - data["endpoint_root"] = endpointRoot; - data["root"] = rootLocation; - return render_template(RESOURCE::templates::catalog_v2_entry_xml, data); + const auto bookDate = book.getDate() + "T00:00:00Z"; + const kainjow::mustache::object data{ + {"root", rootLocation}, + {"endpoint_root", rootLocation + "/catalog/v2"}, + {"id", book.getId()}, + {"title", book.getTitle()}, + {"updated", bookDate}, // XXX: this should be the entry update datetime + }; + const auto xmlTemplate = RESOURCE::templates::catalog_v2_partial_entry_xml; + return render_template(xmlTemplate, data); } -BooksData getBooksData(const Library* library, const std::vector& bookIds, const std::string& rootLocation, const std::string& endpointRoot, bool partial) +BooksData getBooksData(const Library* library, const std::vector& bookIds, const std::string& rootLocation, bool partial) { BooksData booksData; for ( const auto& bookId : bookIds ) { try { const Book book = library->getBookByIdThreadSafe(bookId); - booksData.push_back(kainjow::mustache::object{ - {"entry", getSingleBookEntryXML(book, false, rootLocation, endpointRoot, partial)} - }); + const auto entryXML = partial + ? partialEntryXML(book, rootLocation) + : fullEntryXML(book, rootLocation); + booksData.push_back(kainjow::mustache::object{ {"entry", entryXML} }); } catch ( const std::out_of_range& ) { // the book was removed from the library since its id was obtained // ignore it @@ -179,7 +188,7 @@ std::string getLanguageSelfName(const std::string& lang) { string OPDSDumper::dumpOPDSFeed(const std::vector& bookIds, const std::string& query) const { - const auto booksData = getBooksData(library, bookIds, rootLocation, "", false); + const auto booksData = getBooksData(library, bookIds, rootLocation, false); const kainjow::mustache::object template_data{ {"date", gen_date_str()}, {"root", rootLocation}, @@ -197,7 +206,7 @@ string OPDSDumper::dumpOPDSFeed(const std::vector& bookIds, const s string OPDSDumper::dumpOPDSFeedV2(const std::vector& bookIds, const std::string& query, bool partial) const { const auto endpointRoot = rootLocation + "/catalog/v2"; - const auto booksData = getBooksData(library, bookIds, rootLocation, endpointRoot, partial); + const auto booksData = getBooksData(library, bookIds, rootLocation, partial); const char* const endpoint = partial ? "/partial_entries" : "/entries"; const kainjow::mustache::object template_data{ @@ -218,7 +227,10 @@ string OPDSDumper::dumpOPDSFeedV2(const std::vector& bookIds, const std::string OPDSDumper::dumpOPDSCompleteEntry(const std::string& bookId) const { - return getSingleBookEntryXML(library->getBookById(bookId), true, rootLocation, "", false); + const auto book = library->getBookById(bookId); + return XML_HEADER + + "\n" + + fullEntryXML(book, rootLocation); } std::string OPDSDumper::categoriesOPDSFeed() const diff --git a/static/resources_list.txt b/static/resources_list.txt index 4ff6cc3ce..2730f1b20 100644 --- a/static/resources_list.txt +++ b/static/resources_list.txt @@ -27,6 +27,7 @@ templates/catalog_entries.xml templates/catalog_v2_root.xml templates/catalog_v2_entries.xml templates/catalog_v2_entry.xml +templates/catalog_v2_partial_entry.xml templates/catalog_v2_categories.xml templates/catalog_v2_languages.xml templates/url_of_search_results_css diff --git a/static/templates/catalog_v2_entry.xml b/static/templates/catalog_v2_entry.xml index c92a692df..f7c11f1f9 100644 --- a/static/templates/catalog_v2_entry.xml +++ b/static/templates/catalog_v2_entry.xml @@ -1,13 +1,8 @@ -{{#with_xml_header}} -{{/with_xml_header}} + urn:uuid:{{id}} {{title}} {{updated}} -{{#dump_partial_entries}} - -{{/dump_partial_entries}}{{^dump_partial_entries}} {{description}} + {{description}} {{language}} {{name}} {{flavour}} @@ -29,5 +24,4 @@ {{#url}} {{/url}} -{{/dump_partial_entries}} diff --git a/static/templates/catalog_v2_partial_entry.xml b/static/templates/catalog_v2_partial_entry.xml new file mode 100644 index 000000000..f3dc56b17 --- /dev/null +++ b/static/templates/catalog_v2_partial_entry.xml @@ -0,0 +1,8 @@ + + urn:uuid:{{id}} + {{title}} + {{updated}} + +