From c87add14197e599f9eaece47ee2e27c0f3a83ee8 Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Mon, 31 Oct 2022 20:59:31 +0400 Subject: [PATCH 1/4] Removed an unused variable --- src/server/internalServer.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp index 378f516fd..ceb5dc41b 100644 --- a/src/server/internalServer.cpp +++ b/src/server/internalServer.cpp @@ -1036,9 +1036,6 @@ InternalServer::search_catalog(const RequestContext& request, kiwix::OPDSDumper& opdsDumper) { const auto filter = get_search_filter(request); - const std::string q = filter.hasQuery() - ? filter.getQuery() - : ""; std::vector bookIdsToDump = mp_library->filter(filter); const auto totalResults = bookIdsToDump.size(); const size_t count = request.get_optional_param("count", 10UL); From c0d027e8a48ebadaffb1687848065255d2f0d323 Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Mon, 31 Oct 2022 21:25:38 +0400 Subject: [PATCH 2/4] Unittests for OPDS filtering by language --- test/library_server.cpp | 68 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/test/library_server.cpp b/test/library_server.cpp index 4afcbc10b..e5e330d66 100644 --- a/test/library_server.cpp +++ b/test/library_server.cpp @@ -317,6 +317,42 @@ TEST_F(LibraryServerTest, catalog_search_by_category) ); } +TEST_F(LibraryServerTest, catalog_search_by_language) +{ + { + const auto r = zfs1_->GET("/ROOT/catalog/search?lang=eng"); + EXPECT_EQ(r->status, 200); + EXPECT_EQ(maskVariableOPDSFeedData(r->body), + OPDS_FEED_TAG + " 12345678-90ab-cdef-1234-567890abcdef\n" + " Filtered zims (lang=eng)\n" + " YYYY-MM-DDThh:mm:ssZ\n" + " 1\n" + " 0\n" + " 1\n" + CATALOG_LINK_TAGS + RAY_CHARLES_CATALOG_ENTRY + "\n" + ); + } + + { + const auto r = zfs1_->GET("/ROOT/catalog/search?lang=eng,fra"); + EXPECT_EQ(r->status, 200); + EXPECT_EQ(maskVariableOPDSFeedData(r->body), + OPDS_FEED_TAG + " 12345678-90ab-cdef-1234-567890abcdef\n" + " Filtered zims (lang=eng,fra)\n" + " YYYY-MM-DDThh:mm:ssZ\n" + " 0\n" + " 0\n" + " 0\n" + CATALOG_LINK_TAGS + "\n" + ); + } +} + TEST_F(LibraryServerTest, catalog_search_results_pagination) { { @@ -667,6 +703,38 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_search_terms) ); } +TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_language) +{ + { + const auto r = zfs1_->GET("/ROOT/catalog/v2/entries?lang=eng"); + EXPECT_EQ(r->status, 200); + EXPECT_EQ(maskVariableOPDSFeedData(r->body), + CATALOG_V2_ENTRIES_PREAMBLE("?lang=eng") + " Filtered Entries (lang=eng)\n" + " YYYY-MM-DDThh:mm:ssZ\n" + " 1\n" + " 0\n" + " 1\n" + RAY_CHARLES_CATALOG_ENTRY + "\n" + ); + } + + { + const auto r = zfs1_->GET("/ROOT/catalog/v2/entries?lang=eng,fra"); + EXPECT_EQ(r->status, 200); + EXPECT_EQ(maskVariableOPDSFeedData(r->body), + CATALOG_V2_ENTRIES_PREAMBLE("?lang=eng,fra") + " Filtered Entries (lang=eng,fra)\n" + " YYYY-MM-DDThh:mm:ssZ\n" + " 0\n" + " 0\n" + " 0\n" + "\n" + ); + } +} + TEST_F(LibraryServerTest, catalog_v2_individual_entry_access) { const auto r = zfs1_->GET("/ROOT/catalog/v2/entry/raycharles"); From 7d69ece27d1128d5f766faa0b0d9ac29f1a25f7f Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Mon, 31 Oct 2022 21:41:28 +0400 Subject: [PATCH 3/4] OPDS can be filtered using more than one language From now on, the `lang` parameter of the /catalog/search, /catalog/v2/entries, and /catalog/v2/partial_entries endpoints is interpreted as a comma-separated list of languages. --- include/library.h | 8 ++++++++ src/library.cpp | 15 +++++++++++++-- test/library_server.cpp | 12 ++++++++---- 3 files changed, 29 insertions(+), 6 deletions(-) diff --git a/include/library.h b/include/library.h index 856a3a9ef..fa8f24263 100644 --- a/include/library.h +++ b/include/library.h @@ -106,7 +106,15 @@ class Filter { Filter& rejectTags(const Tags& tags); Filter& category(std::string category); + + /** + * Set the filter to only accept books in the specified language. + * + * Multiple languages can be specified as a comma-separated list (in + * which case a book in any of those languages will match). + */ Filter& lang(std::string lang); + Filter& publisher(std::string publisher); Filter& creator(std::string creator); Filter& maxSize(size_t size); diff --git a/src/library.cpp b/src/library.cpp index 508d7c8e1..fb9fc035b 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -535,9 +535,20 @@ Xapian::Query categoryQuery(const std::string& category) return Xapian::Query("XC" + normalizeText(category)); } -Xapian::Query langQuery(const std::string& lang) +Xapian::Query langQuery(const std::string& commaSeparatedLanguageList) { - return Xapian::Query("L" + normalizeText(lang)); + Xapian::Query q; + bool firstIteration = true; + for ( const auto& lang : kiwix::split(commaSeparatedLanguageList, ",") ) { + const Xapian::Query singleLangQuery("L" + normalizeText(lang)); + if ( firstIteration ) { + q = singleLangQuery; + firstIteration = false; + } else { + q = Xapian::Query(Xapian::Query::OP_OR, q, singleLangQuery); + } + } + return q; } Xapian::Query publisherQuery(const std::string& publisher) diff --git a/test/library_server.cpp b/test/library_server.cpp index e5e330d66..ee20b954d 100644 --- a/test/library_server.cpp +++ b/test/library_server.cpp @@ -344,10 +344,12 @@ TEST_F(LibraryServerTest, catalog_search_by_language) " 12345678-90ab-cdef-1234-567890abcdef\n" " Filtered zims (lang=eng,fra)\n" " YYYY-MM-DDThh:mm:ssZ\n" - " 0\n" + " 2\n" " 0\n" - " 0\n" + " 2\n" CATALOG_LINK_TAGS + RAY_CHARLES_CATALOG_ENTRY + CHARLES_RAY_CATALOG_ENTRY "\n" ); } @@ -727,9 +729,11 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_language) CATALOG_V2_ENTRIES_PREAMBLE("?lang=eng,fra") " Filtered Entries (lang=eng,fra)\n" " YYYY-MM-DDThh:mm:ssZ\n" - " 0\n" + " 2\n" " 0\n" - " 0\n" + " 2\n" + RAY_CHARLES_CATALOG_ENTRY + CHARLES_RAY_CATALOG_ENTRY "\n" ); } From 7765769e6fc3804265c11240c5010685f33314d7 Mon Sep 17 00:00:00 2001 From: Veloman Yunkan Date: Tue, 1 Nov 2022 10:13:26 +0400 Subject: [PATCH 4/4] Beautification (better alignment) --- test/library_server.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/library_server.cpp b/test/library_server.cpp index ee20b954d..f61d94281 100644 --- a/test/library_server.cpp +++ b/test/library_server.cpp @@ -114,7 +114,7 @@ std::string maskVariableOPDSFeedData(std::string s) "569344" \ ) -#define CHARLES_RAY_CATALOG_ENTRY _CHARLES_RAY_CATALOG_ENTRY("zimfile%26other") +#define CHARLES_RAY_CATALOG_ENTRY _CHARLES_RAY_CATALOG_ENTRY("zimfile%26other") #define CHARLES_RAY_CATALOG_ENTRY_NO_MAPPER _CHARLES_RAY_CATALOG_ENTRY("charlesray") #define _RAY_CHARLES_CATALOG_ENTRY(CONTENT_NAME) CATALOG_ENTRY(\ @@ -133,7 +133,7 @@ std::string maskVariableOPDSFeedData(std::string s) "569344"\ ) -#define RAY_CHARLES_CATALOG_ENTRY _RAY_CHARLES_CATALOG_ENTRY("zimfile") +#define RAY_CHARLES_CATALOG_ENTRY _RAY_CHARLES_CATALOG_ENTRY("zimfile") #define RAY_CHARLES_CATALOG_ENTRY_NO_MAPPER _RAY_CHARLES_CATALOG_ENTRY("raycharles") #define UNCATEGORIZED_RAY_CHARLES_CATALOG_ENTRY CATALOG_ENTRY(\