diff --git a/include/library.h b/include/library.h index d3a40ab3d..029bdb64e 100644 --- a/include/library.h +++ b/include/library.h @@ -33,6 +33,10 @@ using namespace std; +namespace pugi { +class xml_node; +} + namespace kiwix { enum supportedIndexType { UNKNOWN, XAPIAN }; @@ -51,6 +55,8 @@ class Book bool update(const Book& other); void update(const Reader& reader); + void updateFromXml(const pugi::xml_node& node, const std::string& baseDir); + void updateFromOpds(const pugi::xml_node& node); static bool sortByTitle(const Book& a, const Book& b); static bool sortBySize(const Book& a, const Book& b); static bool sortByDate(const Book& a, const Book& b); diff --git a/src/library.cpp b/src/library.cpp index 91a8cd6ba..a9c6bbae8 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -20,6 +20,8 @@ #include "library.h" #include "reader.h" +#include "common/base64.h" + #include namespace kiwix @@ -118,6 +120,67 @@ void Book::update(const kiwix::Reader& reader) reader.getFavicon(m_favicon, m_faviconMimeType); } +#define ATTR(name) node.attribute(name).value() +void Book::updateFromXml(const pugi::xml_node& node, const std::string& baseDir) +{ + m_id = ATTR("id"); + std::string path = ATTR("path"); + if (isRelativePath(path)) { + path = computeAbsolutePath(baseDir, path); + } + m_path = path; + path = ATTR("indexPath"); + if (!path.empty()) { + if (isRelativePath(path)) { + path = computeAbsolutePath(baseDir, path); + } + m_indexPath = path; + m_indexType = XAPIAN; + } + 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_url = ATTR("url"); + m_origId = ATTR("origId"); + m_articleCount = strtoull(ATTR("articleCount"), 0, 0); + m_mediaCount = strtoull(ATTR("mediaCount"), 0, 0); + m_size = strtoull(ATTR("size"), 0, 0); + m_favicon = base64_decode(ATTR("favicon")); + m_faviconMimeType = ATTR("faviconMimeType"); +} +#undef ATTR + + +#define VALUE(name) node.child(name).child_value() +void Book::updateFromOpds(const pugi::xml_node& node) +{ + m_id = VALUE("id"); + if (!m_id.compare(0, 9, "urn:uuid:")) { + m_id.erase(0, 9); + } + m_title = VALUE("title"); + m_description = VALUE("description"); + m_language = VALUE("language"); + m_date = VALUE("updated"); + m_creator = node.child("author").child("name").child_value(); + for(auto linkNode = node.child("link"); linkNode; + linkNode = linkNode.next_sibling("link")) { + std::string rel = linkNode.attribute("rel").value(); + + if (rel == "http://opds-spec.org/acquisition/open-access") { + m_url = linkNode.attribute("href").value(); + break; + } + } + +} +#undef VALUE + std::string Book::getHumanReadableIdFromPath() { std::string id = m_path; diff --git a/src/manager.cpp b/src/manager.cpp index 02b344f48..aa0b3c2af 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -46,35 +46,7 @@ bool Manager::parseXmlDom(const pugi::xml_document& doc, kiwix::Book book; book.setReadOnly(readOnly); - book.setFavicon(base64_decode(bookNode.attribute("favicon").value()); - book.setId(bookNode.attribute("id").value()); - std::string path = bookNode.attribute("path").value(); - if (isRelativePath(path)) { - path = computeAbsolutePath( - removeLastPathElement(libraryPath, true, false), path); - } - book.setPath(path); - std::string indexPath = bookNode.attribute("indexPath").value(); - if (isRelativePath(indexPath)) { - indexPath = computeAbsolutePath( - removeLastPathElement(libraryPath, true, false), indexPath); - } - book.setIndexPath(indexPath); - book.setIndexType(XAPIAN); - book.setTitle(bookNode.attribute("title").value()); - book.setName(bookNode.attribute("name").value()); - book.setTags(bookNode.attribute("tags").value()); - book.setDescription(bookNode.attribute("description").value()); - book.setLanguage(bookNode.attribute("language").value()); - book.setDate(bookNode.attribute("date").value()); - book.setCreator(bookNode.attribute("creator").value()); - book.setPublisher(bookNode.attribute("publisher").value()); - book.setUrl(bookNode.attribute("url").value()); - book.setOrigId(bookNode.attribute("origId").value()); - book.setArticleCount(strtoull(bookNode.attribute("articleCount").value(), 0, 0)); - book.setMediaCount(strtoull(bookNode.attribute("mediaCount").value(), 0, 0)); - book.setSize(strtoull(bookNode.attribute("size").value(), 0, 0)); - book.setFaviconMimeType(bookNode.attribute("faviconMimeType").value()); + book.updateFromXml(bookNode, removeLastPathElement(libraryPath, true, false)); /* Update the book properties with the new importer */ if (libraryVersion.empty() @@ -119,12 +91,7 @@ bool Manager::parseOpdsDom(const pugi::xml_document& doc, const std::string& url kiwix::Book book; book.setReadOnly(false); - book.setId(entryNode.child("id").child_value()); - book.setTitle(entryNode.child("title").child_value()); - book.setDescription(entryNode.child("summary").child_value()); - book.setLanguage(entryNode.child("language").child_value()); - book.setDate(entryNode.child("updated").child_value()); - book.setCreator(entryNode.child("author").child("name").child_value()); + book.updateFromOpds(entryNode); for(pugi::xml_node linkNode = entryNode.child("link"); linkNode; linkNode = linkNode.next_sibling("link")) { std::string rel = linkNode.attribute("rel").value(); @@ -140,9 +107,7 @@ bool Manager::parseOpdsDom(const pugi::xml_document& doc, const std::string& url } else { std::cerr << "Cannot get favicon content from " << faviconUrl << std::endl; } - - } else if (rel == "http://opds-spec.org/acquisition/open-access") { - book.setUrl(linkNode.attribute("href").value()); + break; } }