From ebb713cb85d31d73f55b20655073499842f407a7 Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Thu, 6 Oct 2022 12:48:37 +0400 Subject: [PATCH 1/4] Got rid of an unjustified parameter The XML header is injected in a more straightforward way in the single location where it is needed. --- src/opds_dumper.cpp | 12 ++++++++---- static/templates/catalog_v2_entry.xml | 3 +-- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/opds_dumper.cpp b/src/opds_dumper.cpp index 13c9804aa..67fe91eb8 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; @@ -94,10 +96,9 @@ kainjow::mustache::object getSingleBookData(const Book& book) }; } -std::string getSingleBookEntryXML(const Book& book, bool withXMLHeader, const std::string& rootLocation, const std::string& endpointRoot, bool partial) +std::string getSingleBookEntryXML(const Book& book, const std::string& rootLocation, const std::string& endpointRoot, bool partial) { auto data = getSingleBookData(book); - data["with_xml_header"] = MustacheData(withXMLHeader); data["dump_partial_entries"] = MustacheData(partial); data["endpoint_root"] = endpointRoot; data["root"] = rootLocation; @@ -111,7 +112,7 @@ BooksData getBooksData(const Library* library, const std::vector& b try { const Book book = library->getBookByIdThreadSafe(bookId); booksData.push_back(kainjow::mustache::object{ - {"entry", getSingleBookEntryXML(book, false, rootLocation, endpointRoot, partial)} + {"entry", getSingleBookEntryXML(book, rootLocation, endpointRoot, partial)} }); } catch ( const std::out_of_range& ) { // the book was removed from the library since its id was obtained @@ -218,7 +219,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" + + getSingleBookEntryXML(book, rootLocation, "", false); } std::string OPDSDumper::categoriesOPDSFeed() const diff --git a/static/templates/catalog_v2_entry.xml b/static/templates/catalog_v2_entry.xml index c92a692df..4e53f712f 100644 --- a/static/templates/catalog_v2_entry.xml +++ b/static/templates/catalog_v2_entry.xml @@ -1,5 +1,4 @@ -{{#with_xml_header}} -{{/with_xml_header}} + urn:uuid:{{id}} {{title}} {{updated}} From 0841472004fa02320e0ba9da7a5c6d1c7169d7a4 Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Thu, 6 Oct 2022 13:17:50 +0400 Subject: [PATCH 2/4] Separate templates for full & partial OPDS entries --- src/opds_dumper.cpp | 6 ++++-- static/resources_list.txt | 1 + static/templates/catalog_v2_entry.xml | 7 +------ static/templates/catalog_v2_partial_entry.xml | 8 ++++++++ 4 files changed, 14 insertions(+), 8 deletions(-) create mode 100644 static/templates/catalog_v2_partial_entry.xml diff --git a/src/opds_dumper.cpp b/src/opds_dumper.cpp index 67fe91eb8..d1c85dcae 100644 --- a/src/opds_dumper.cpp +++ b/src/opds_dumper.cpp @@ -99,10 +99,12 @@ kainjow::mustache::object getSingleBookData(const Book& book) std::string getSingleBookEntryXML(const Book& book, const std::string& rootLocation, const std::string& endpointRoot, bool partial) { auto data = getSingleBookData(book); - 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 xmlTemplate = partial + ? RESOURCE::templates::catalog_v2_partial_entry_xml + : RESOURCE::templates::catalog_v2_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) 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 4e53f712f..f7c11f1f9 100644 --- a/static/templates/catalog_v2_entry.xml +++ b/static/templates/catalog_v2_entry.xml @@ -2,11 +2,7 @@ urn:uuid:{{id}} {{title}} {{updated}} -{{#dump_partial_entries}} - -{{/dump_partial_entries}}{{^dump_partial_entries}} {{description}} + {{description}} {{language}} {{name}} {{flavour}} @@ -28,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}} + + From dc194683bb3c0a2cb0f8b5a9165777c0a8a0d669 Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Thu, 6 Oct 2022 13:48:58 +0400 Subject: [PATCH 3/4] Split XML generation code for full & partial entries --- src/opds_dumper.cpp | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/src/opds_dumper.cpp b/src/opds_dumper.cpp index d1c85dcae..4b1bd2782 100644 --- a/src/opds_dumper.cpp +++ b/src/opds_dumper.cpp @@ -71,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()}, @@ -94,17 +95,21 @@ 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, const std::string& rootLocation, const std::string& endpointRoot, bool partial) +std::string partialEntryXML(const Book& book, const std::string& rootLocation, const std::string& endpointRoot) { - auto data = getSingleBookData(book); - data["endpoint_root"] = endpointRoot; - data["root"] = rootLocation; - const auto xmlTemplate = partial - ? RESOURCE::templates::catalog_v2_partial_entry_xml - : RESOURCE::templates::catalog_v2_entry_xml; - return render_template(xmlTemplate, data); + const auto bookDate = book.getDate() + "T00:00:00Z"; + const kainjow::mustache::object data{ + {"root", rootLocation}, + {"endpoint_root", endpointRoot}, + {"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) @@ -113,9 +118,10 @@ BooksData getBooksData(const Library* library, const std::vector& b for ( const auto& bookId : bookIds ) { try { const Book book = library->getBookByIdThreadSafe(bookId); - booksData.push_back(kainjow::mustache::object{ - {"entry", getSingleBookEntryXML(book, rootLocation, endpointRoot, partial)} - }); + const auto entryXML = partial + ? partialEntryXML(book, rootLocation, endpointRoot) + : 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 @@ -224,7 +230,7 @@ std::string OPDSDumper::dumpOPDSCompleteEntry(const std::string& bookId) const const auto book = library->getBookById(bookId); return XML_HEADER + "\n" - + getSingleBookEntryXML(book, rootLocation, "", false); + + fullEntryXML(book, rootLocation); } std::string OPDSDumper::categoriesOPDSFeed() const From f13ca55ef652998f4bf05eec5891684edfd25f6c Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Thu, 6 Oct 2022 14:02:50 +0400 Subject: [PATCH 4/4] Eliminated the endpointRoot parameter --- src/opds_dumper.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/opds_dumper.cpp b/src/opds_dumper.cpp index 4b1bd2782..7436ebc29 100644 --- a/src/opds_dumper.cpp +++ b/src/opds_dumper.cpp @@ -98,12 +98,12 @@ std::string fullEntryXML(const Book& book, const std::string& rootLocation) return render_template(RESOURCE::templates::catalog_v2_entry_xml, data); } -std::string partialEntryXML(const Book& book, const std::string& rootLocation, const std::string& endpointRoot) +std::string partialEntryXML(const Book& book, const std::string& rootLocation) { const auto bookDate = book.getDate() + "T00:00:00Z"; const kainjow::mustache::object data{ {"root", rootLocation}, - {"endpoint_root", endpointRoot}, + {"endpoint_root", rootLocation + "/catalog/v2"}, {"id", book.getId()}, {"title", book.getTitle()}, {"updated", bookDate}, // XXX: this should be the entry update datetime @@ -112,14 +112,14 @@ std::string partialEntryXML(const Book& book, const std::string& rootLocation, c 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); const auto entryXML = partial - ? partialEntryXML(book, rootLocation, endpointRoot) + ? partialEntryXML(book, rootLocation) : fullEntryXML(book, rootLocation); booksData.push_back(kainjow::mustache::object{ {"entry", entryXML} }); } catch ( const std::out_of_range& ) { @@ -188,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}, @@ -206,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{