From 7e26f3502d6b0574b73bceb44dd3e9352335160a Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Wed, 29 Jan 2020 18:00:17 +0100 Subject: [PATCH 1/5] Fix opds dumper/parser. Add missing attributes. --- src/book.cpp | 4 +++- src/opds_dumper.cpp | 5 +++++ test/library.cpp | 2 +- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/book.cpp b/src/book.cpp index 3e530510a..234b6a73f 100644 --- a/src/book.cpp +++ b/src/book.cpp @@ -124,10 +124,12 @@ void Book::updateFromOpds(const pugi::xml_node& node, const std::string& urlHost m_id.erase(0, 9); } m_title = VALUE("title"); - m_description = VALUE("description"); + m_name = VALUE("name"); + m_description = VALUE("summary"); m_language = VALUE("language"); m_date = fromOpdsDate(VALUE("updated")); m_creator = node.child("author").child("name").child_value(); + m_publisher = node.child("publisher").child("name").child_value(); m_tags = VALUE("tags"); for(auto linkNode = node.child("link"); linkNode; linkNode = linkNode.next_sibling("link")) { diff --git a/src/opds_dumper.cpp b/src/opds_dumper.cpp index af3f1522d..ceefe0a8d 100644 --- a/src/opds_dumper.cpp +++ b/src/opds_dumper.cpp @@ -71,11 +71,13 @@ void OPDSDumper::setOpenSearchInfo(int totalResults, int startIndex, int count) pugi::xml_node OPDSDumper::handleBook(Book book, pugi::xml_node root_node) { auto entry_node = root_node.append_child("entry"); ADD_TEXT_ENTRY(entry_node, "title", book.getTitle()); + ADD_TEXT_ENTRY(entry_node, "name", book.getName()); ADD_TEXT_ENTRY(entry_node, "id", "urn:uuid:"+book.getId()); ADD_TEXT_ENTRY(entry_node, "icon", rootLocation + "/meta?name=favicon&content=" + book.getHumanReadableIdFromPath()); ADD_TEXT_ENTRY(entry_node, "updated", gen_date_from_yyyy_mm_dd(book.getDate())); ADD_TEXT_ENTRY(entry_node, "summary", book.getDescription()); ADD_TEXT_ENTRY(entry_node, "tags", book.getTags()); + ADD_TEXT_ENTRY(entry_node, "language", book.getLanguage()); auto content_node = entry_node.append_child("link"); content_node.append_attribute("type") = "text/html"; @@ -84,6 +86,9 @@ pugi::xml_node OPDSDumper::handleBook(Book book, pugi::xml_node root_node) { auto author_node = entry_node.append_child("author"); ADD_TEXT_ENTRY(author_node, "name", book.getCreator()); + auto publisher_node = entry_node.append_child("publisher"); + ADD_TEXT_ENTRY(publisher_node, "name", book.getPublisher()); + if (! book.getUrl().empty()) { auto acquisition_link = entry_node.append_child("link"); acquisition_link.append_attribute("rel") = "http://opds-spec.org/acquisition/open-access"; diff --git a/test/library.cpp b/test/library.cpp index 3f4921789..3f23df775 100644 --- a/test/library.cpp +++ b/test/library.cpp @@ -252,7 +252,7 @@ TEST_F(LibraryTest, filterCheck) EXPECT_EQ(bookIds.size(), 1U); bookIds = lib.filter(kiwix::Filter().query("Wiki")); - EXPECT_EQ(bookIds.size(), 3U); + EXPECT_EQ(bookIds.size(), 4U); bookIds = lib.filter(kiwix::Filter().query("Wiki").creator("Wiki")); EXPECT_EQ(bookIds.size(), 1U); From 7846b45befbd44edfd96f927fbced82ee35c7a86 Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Wed, 29 Jan 2020 18:42:12 +0100 Subject: [PATCH 2/5] Fix opds filtering by tag. --- src/server.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/server.cpp b/src/server.cpp index fe33181b1..8de04ba29 100644 --- a/src/server.cpp +++ b/src/server.cpp @@ -768,7 +768,7 @@ Response InternalServer::handle_catalog(const RequestContext& request) startIndex = extractFromString(request.get_argument("start")); } catch (...) {} try { - filter.acceptTags(kiwix::split(request.get_argument("notag"), ";")); + filter.acceptTags(kiwix::split(request.get_argument("tag"), ";")); } catch (...) {} try { filter.rejectTags(kiwix::split(request.get_argument("notag"), ";")); From 49aa0fbb9f5c77f1557165dc2b5b8cf7fb882e7a Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Thu, 30 Jan 2020 11:14:08 +0100 Subject: [PATCH 3/5] Use a macro to write the filters. --- src/library.cpp | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/src/library.cpp b/src/library.cpp index 46f1e86be..12ff5a18d 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -466,23 +466,26 @@ Filter& Filter::query(std::string query) } #define ACTIVE(X) (activeFilters & (X)) +#define FILTER(TAG, TEST) if (ACTIVE(TAG) && !(TEST)) { return false; } bool Filter::accept(const Book& book) const { auto local = !book.getPath().empty(); - if (ACTIVE(_LOCAL) && !local) - return false; - if (ACTIVE(_NOLOCAL) && local) - return false; + FILTER(_LOCAL, local) + FILTER(_NOLOCAL, !local) + auto valid = book.isPathValid(); - if (ACTIVE(_VALID) && !valid) - return false; - if (ACTIVE(_NOVALID) && valid) - return false; + FILTER(_VALID, valid) + FILTER(_NOVALID, !valid) + auto remote = !book.getUrl().empty(); - if (ACTIVE(_REMOTE) && !remote) - return false; - if (ACTIVE(_NOREMOTE) && remote) - return false; + FILTER(_REMOTE, remote) + FILTER(_NOREMOTE, !remote) + + FILTER(MAXSIZE, book.getSize() <= _maxSize) + FILTER(LANG, book.getLanguage() == _lang) + FILTER(_PUBLISHER, book.getPublisher() == _publisher) + FILTER(_CREATOR, book.getCreator() == _creator) + if (ACTIVE(ACCEPTTAGS)) { if (!_acceptTags.empty()) { auto vBookTags = split(book.getTags(), ";"); @@ -505,18 +508,6 @@ bool Filter::accept(const Book& book) const } } } - if (ACTIVE(MAXSIZE) && book.getSize() > _maxSize) - return false; - - if (ACTIVE(LANG) && book.getLanguage() != _lang) - return false; - - if (ACTIVE(_PUBLISHER) && book.getPublisher() != _publisher) - return false; - - if (ACTIVE(_CREATOR) && book.getCreator() != _creator) - return false; - if ( ACTIVE(QUERY) && !(matchRegex(book.getTitle(), "\\Q" + _query + "\\E") || matchRegex(book.getDescription(), "\\Q" + _query + "\\E"))) From 77ba09c310ec1e96fd37999bc7ca316f813cf111 Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Thu, 30 Jan 2020 14:50:29 +0100 Subject: [PATCH 4/5] Reorder setting and dumper of book attribute. No real change. Reordering setting and dumping of attribute in the same order (mostly) they are declared in book.h make it easier to detect missing attribute. --- src/book.cpp | 17 +++++++++-------- src/libxml_dumper.cpp | 4 ++-- src/opds_dumper.cpp | 10 +++++----- 3 files changed, 16 insertions(+), 15 deletions(-) diff --git a/src/book.cpp b/src/book.cpp index 234b6a73f..4964e3593 100644 --- a/src/book.cpp +++ b/src/book.cpp @@ -48,8 +48,8 @@ bool Book::update(const kiwix::Book& other) m_path = other.m_path; m_pathValid = other.m_pathValid; m_url = other.m_url; - m_tags = other.m_tags; m_name = other.m_name; + m_tags = other.m_tags; m_favicon = other.m_favicon; m_faviconMimeType = other.m_faviconMimeType; @@ -59,13 +59,14 @@ bool Book::update(const kiwix::Book& other) void Book::update(const kiwix::Reader& reader) { m_path = reader.getZimFilePath(); + m_pathValid = true; m_id = reader.getId(); + m_title = reader.getTitle(); m_description = reader.getDescription(); m_language = reader.getLanguage(); - m_date = reader.getDate(); m_creator = reader.getCreator(); m_publisher = reader.getPublisher(); - m_title = reader.getTitle(); + m_date = reader.getDate(); m_name = reader.getName(); m_tags = reader.getTags(); m_origId = reader.getOrigId(); @@ -87,14 +88,14 @@ void Book::updateFromXml(const pugi::xml_node& node, const std::string& baseDir) } m_path = path; m_title = ATTR("title"); - m_name = ATTR("name"); - m_tags = ATTR("tags"); m_description = ATTR("description"); m_language = ATTR("language"); - m_date = ATTR("date"); m_creator = ATTR("creator"); m_publisher = ATTR("publisher"); + m_date = ATTR("date"); m_url = ATTR("url"); + m_name = ATTR("name"); + m_tags = ATTR("tags"); m_origId = ATTR("origId"); m_articleCount = strtoull(ATTR("articleCount"), 0, 0); m_mediaCount = strtoull(ATTR("mediaCount"), 0, 0); @@ -124,12 +125,12 @@ void Book::updateFromOpds(const pugi::xml_node& node, const std::string& urlHost m_id.erase(0, 9); } m_title = VALUE("title"); - m_name = VALUE("name"); m_description = VALUE("summary"); m_language = VALUE("language"); - m_date = fromOpdsDate(VALUE("updated")); m_creator = node.child("author").child("name").child_value(); m_publisher = node.child("publisher").child("name").child_value(); + m_date = fromOpdsDate(VALUE("updated")); + m_name = VALUE("name"); m_tags = VALUE("tags"); for(auto linkNode = node.child("link"); linkNode; linkNode = linkNode.next_sibling("link")) { diff --git a/src/libxml_dumper.cpp b/src/libxml_dumper.cpp index b6d3b488a..58e350731 100644 --- a/src/libxml_dumper.cpp +++ b/src/libxml_dumper.cpp @@ -53,12 +53,12 @@ void LibXMLDumper::handleBook(Book book, pugi::xml_node root_node) { if (book.getOrigId().empty()) { ADD_ATTR_NOT_EMPTY(entry_node, "title", book.getTitle()); - ADD_ATTR_NOT_EMPTY(entry_node, "name", book.getName()); - ADD_ATTR_NOT_EMPTY(entry_node, "tags", book.getTags()); ADD_ATTR_NOT_EMPTY(entry_node, "description", book.getDescription()); ADD_ATTR_NOT_EMPTY(entry_node, "language", book.getLanguage()); ADD_ATTR_NOT_EMPTY(entry_node, "creator", book.getCreator()); ADD_ATTR_NOT_EMPTY(entry_node, "publisher", book.getPublisher()); + ADD_ATTR_NOT_EMPTY(entry_node, "name", book.getName()); + ADD_ATTR_NOT_EMPTY(entry_node, "tags", book.getTags()); ADD_ATTR_NOT_EMPTY(entry_node, "faviconMimeType", book.getFaviconMimeType()); if (!book.getFavicon().empty()) ADD_ATTRIBUTE(entry_node, "favicon", base64_encode(book.getFavicon())); diff --git a/src/opds_dumper.cpp b/src/opds_dumper.cpp index ceefe0a8d..04cdb5436 100644 --- a/src/opds_dumper.cpp +++ b/src/opds_dumper.cpp @@ -70,14 +70,14 @@ void OPDSDumper::setOpenSearchInfo(int totalResults, int startIndex, int count) pugi::xml_node OPDSDumper::handleBook(Book book, pugi::xml_node root_node) { auto entry_node = root_node.append_child("entry"); - ADD_TEXT_ENTRY(entry_node, "title", book.getTitle()); - ADD_TEXT_ENTRY(entry_node, "name", book.getName()); ADD_TEXT_ENTRY(entry_node, "id", "urn:uuid:"+book.getId()); - ADD_TEXT_ENTRY(entry_node, "icon", rootLocation + "/meta?name=favicon&content=" + book.getHumanReadableIdFromPath()); - ADD_TEXT_ENTRY(entry_node, "updated", gen_date_from_yyyy_mm_dd(book.getDate())); + ADD_TEXT_ENTRY(entry_node, "title", book.getTitle()); ADD_TEXT_ENTRY(entry_node, "summary", book.getDescription()); - ADD_TEXT_ENTRY(entry_node, "tags", book.getTags()); ADD_TEXT_ENTRY(entry_node, "language", book.getLanguage()); + ADD_TEXT_ENTRY(entry_node, "updated", gen_date_from_yyyy_mm_dd(book.getDate())); + ADD_TEXT_ENTRY(entry_node, "name", book.getName()); + ADD_TEXT_ENTRY(entry_node, "tags", book.getTags()); + ADD_TEXT_ENTRY(entry_node, "icon", rootLocation + "/meta?name=favicon&content=" + book.getHumanReadableIdFromPath()); auto content_node = entry_node.append_child("link"); content_node.append_attribute("type") = "text/html"; From 2881face70874157e1528eed0f51f444c4b97e66 Mon Sep 17 00:00:00 2001 From: Matthieu Gautier Date: Thu, 30 Jan 2020 14:51:12 +0100 Subject: [PATCH 5/5] Add missing setting of attribute. --- src/book.cpp | 17 +++++++++++++++++ src/libxml_dumper.cpp | 1 + 2 files changed, 18 insertions(+) diff --git a/src/book.cpp b/src/book.cpp index 4964e3593..15bd31743 100644 --- a/src/book.cpp +++ b/src/book.cpp @@ -44,14 +44,30 @@ bool Book::update(const kiwix::Book& other) if (m_readOnly) return false; + if (m_id != other.m_id) + return false; + m_readOnly = other.m_readOnly; m_path = other.m_path; m_pathValid = other.m_pathValid; + m_title = other.m_title; + m_description = other.m_description; + m_language = other.m_language; + m_creator = other.m_creator; + m_publisher = other.m_publisher; + m_date = other.m_date; m_url = other.m_url; m_name = other.m_name; m_tags = other.m_tags; + m_origId = other.m_origId; + m_articleCount = other.m_articleCount; + m_mediaCount = other.m_mediaCount; + m_size = other.m_size; m_favicon = other.m_favicon; m_faviconMimeType = other.m_faviconMimeType; + m_faviconUrl = other.m_faviconUrl; + + m_downloadId = other.m_downloadId; return true; } @@ -102,6 +118,7 @@ void Book::updateFromXml(const pugi::xml_node& node, const std::string& baseDir) m_size = strtoull(ATTR("size"), 0, 0) << 10; m_favicon = base64_decode(ATTR("favicon")); m_faviconMimeType = ATTR("faviconMimeType"); + m_faviconUrl = ATTR("faviconUrl"); try { m_downloadId = ATTR("downloadId"); } catch(...) {} diff --git a/src/libxml_dumper.cpp b/src/libxml_dumper.cpp index 58e350731..56ec4b44d 100644 --- a/src/libxml_dumper.cpp +++ b/src/libxml_dumper.cpp @@ -60,6 +60,7 @@ void LibXMLDumper::handleBook(Book book, pugi::xml_node root_node) { ADD_ATTR_NOT_EMPTY(entry_node, "name", book.getName()); ADD_ATTR_NOT_EMPTY(entry_node, "tags", book.getTags()); ADD_ATTR_NOT_EMPTY(entry_node, "faviconMimeType", book.getFaviconMimeType()); + ADD_ATTR_NOT_EMPTY(entry_node, "faviconUrl", book.getFaviconUrl()); if (!book.getFavicon().empty()) ADD_ATTRIBUTE(entry_node, "favicon", base64_encode(book.getFavicon())); } else {