From 5f90f5ee2a746b65d1ca329e3c0e6c17541abe12 Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Fri, 11 Jun 2021 12:55:04 +0400 Subject: [PATCH] Preliminary version of /catalog/v2/languages --- include/opds_dumper.h | 7 ++++ src/opds_dumper.cpp | 46 +++++++++++++++++++++ src/server/internalServer.h | 1 + src/server/internalServer_catalog_v2.cpp | 14 +++++++ static/resources_list.txt | 1 + static/templates/catalog_v2_languages.xml | 25 ++++++++++++ test/server.cpp | 49 +++++++++++++++++++++++ 7 files changed, 143 insertions(+) create mode 100644 static/templates/catalog_v2_languages.xml diff --git a/include/opds_dumper.h b/include/opds_dumper.h index db6026ef8..0a70b65d5 100644 --- a/include/opds_dumper.h +++ b/include/opds_dumper.h @@ -71,6 +71,13 @@ class OPDSDumper */ std::string categoriesOPDSFeed(const std::vector& categories) const; + /** + * Dump the languages OPDS feed. + * + * @return The OPDS feed. + */ + std::string languagesOPDSFeed() const; + /** * Set the id of the library. * diff --git a/src/opds_dumper.cpp b/src/opds_dumper.cpp index 8426a34d1..65ea3c526 100644 --- a/src/opds_dumper.cpp +++ b/src/opds_dumper.cpp @@ -22,6 +22,7 @@ #include "kiwixlib-resources.h" #include +#include #include "tools/stringTools.h" #include "tools/otherTools.h" @@ -83,6 +84,24 @@ BookData getBookData(const Library* library, const std::vector& boo return bookData; } +struct LangInfo { + std::string selfName, englishName; +}; + +std::map langMap = { + {"eng", { "English", "English"} }, + {"fra", { "Français", "French"} }, + {"rus", { "Русский", "Russian"} }, +}; + +std::string getLanguageSelfName(const std::string& lang) { + return langMap.at(lang).selfName; +}; + +std::string getLanguageEnglishName(const std::string& lang) { + return langMap.at(lang).englishName; +}; + } // unnamed namespace string OPDSDumper::dumpOPDSFeed(const std::vector& bookIds, const std::string& query) const @@ -146,4 +165,31 @@ std::string OPDSDumper::categoriesOPDSFeed(const std::vector& categ ); } +std::string OPDSDumper::languagesOPDSFeed() const +{ + const auto now = gen_date_str(); + kainjow::mustache::list languageData; + for ( const auto& languageCode : library->getBooksLanguages() ) { + const auto languageSelfName = getLanguageSelfName(languageCode); + const auto languageEnglishName = getLanguageEnglishName(languageCode); + languageData.push_back(kainjow::mustache::object{ + {"lang_code", languageCode}, + {"lang_self_name", languageSelfName}, + {"lang_english_name", languageEnglishName}, + {"updated", now}, + {"id", gen_uuid(libraryId + "/languages/" + languageCode)} + }); + } + + return render_template( + RESOURCE::templates::catalog_v2_languages_xml, + kainjow::mustache::object{ + {"date", now}, + {"endpoint_root", rootLocation + "/catalog/v2"}, + {"feed_id", gen_uuid(libraryId + "/languages")}, + {"languages", languageData } + } + ); +} + } diff --git a/src/server/internalServer.h b/src/server/internalServer.h index ed40fea9c..f1c813a81 100644 --- a/src/server/internalServer.h +++ b/src/server/internalServer.h @@ -77,6 +77,7 @@ class InternalServer { std::unique_ptr handle_catalog_v2_root(const RequestContext& request); std::unique_ptr handle_catalog_v2_entries(const RequestContext& request); std::unique_ptr handle_catalog_v2_categories(const RequestContext& request); + std::unique_ptr handle_catalog_v2_languages(const RequestContext& request); std::unique_ptr handle_meta(const RequestContext& request); std::unique_ptr handle_search(const RequestContext& request); std::unique_ptr handle_suggest(const RequestContext& request); diff --git a/src/server/internalServer_catalog_v2.cpp b/src/server/internalServer_catalog_v2.cpp index 879d059c2..3d79111a3 100644 --- a/src/server/internalServer_catalog_v2.cpp +++ b/src/server/internalServer_catalog_v2.cpp @@ -59,6 +59,8 @@ std::unique_ptr InternalServer::handle_catalog_v2(const RequestContext return handle_catalog_v2_entries(request); } else if (url == "categories") { return handle_catalog_v2_categories(request); + } else if (url == "languages") { + return handle_catalog_v2_languages(request); } else { return Response::build_404(*this, request, "", ""); } @@ -107,4 +109,16 @@ std::unique_ptr InternalServer::handle_catalog_v2_categories(const Req ); } +std::unique_ptr InternalServer::handle_catalog_v2_languages(const RequestContext& request) +{ + OPDSDumper opdsDumper(mp_library); + opdsDumper.setRootLocation(m_root); + opdsDumper.setLibraryId(m_library_id); + return ContentResponse::build( + *this, + opdsDumper.languagesOPDSFeed(), + "application/atom+xml;profile=opds-catalog;kind=navigation" + ); +} + } // namespace kiwix diff --git a/static/resources_list.txt b/static/resources_list.txt index 41552195d..a440e1841 100644 --- a/static/resources_list.txt +++ b/static/resources_list.txt @@ -48,5 +48,6 @@ templates/catalog_entries.xml templates/catalog_v2_root.xml templates/catalog_v2_entries.xml templates/catalog_v2_categories.xml +templates/catalog_v2_languages.xml opensearchdescription.xml catalog_v2_searchdescription.xml diff --git a/static/templates/catalog_v2_languages.xml b/static/templates/catalog_v2_languages.xml new file mode 100644 index 000000000..845d3279e --- /dev/null +++ b/static/templates/catalog_v2_languages.xml @@ -0,0 +1,25 @@ + + + {{feed_id}} + + + List of languages + {{date}} + + {{#languages}} + + {{lang_self_name}} + + {{updated}} + {{id}} + All entries in {{lang_english_name}}. + + {{/languages}} + diff --git a/test/server.cpp b/test/server.cpp index e256f5bb2..7c534b5fa 100644 --- a/test/server.cpp +++ b/test/server.cpp @@ -1014,6 +1014,55 @@ TEST_F(LibraryServerTest, catalog_v2_categories) EXPECT_EQ(maskVariableOPDSFeedData(r->body), expected_output); } +TEST_F(LibraryServerTest, catalog_v2_languages) +{ + const auto r = zfs1_->GET("/catalog/v2/languages"); + EXPECT_EQ(r->status, 200); + const char expected_output[] = R"( + + 12345678-90ab-cdef-1234-567890abcdef + + + List of languages + YYYY-MM-DDThh:mm:ssZ + + + English + + YYYY-MM-DDThh:mm:ssZ + 12345678-90ab-cdef-1234-567890abcdef + All entries in English. + + + Français + + YYYY-MM-DDThh:mm:ssZ + 12345678-90ab-cdef-1234-567890abcdef + All entries in French. + + + Русский + + YYYY-MM-DDThh:mm:ssZ + 12345678-90ab-cdef-1234-567890abcdef + All entries in Russian. + + +)"; + EXPECT_EQ(maskVariableOPDSFeedData(r->body), expected_output); +} + #define CATALOG_V2_ENTRIES_PREAMBLE(q) \ "\n" \ "