diff --git a/include/book.h b/include/book.h new file mode 100644 index 000000000..92fd7afb9 --- /dev/null +++ b/include/book.h @@ -0,0 +1,124 @@ +/* + * Copyright 2011 Emmanuel Engelhart + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifndef KIWIX_BOOK_H +#define KIWIX_BOOK_H + +#include + +namespace pugi { +class xml_node; +} + +namespace kiwix +{ +enum supportedIndexType { UNKNOWN, XAPIAN }; + +class OPDSDumper; +class Reader; + +/** + * A class to store information about a book (a zim file) + */ +class Book +{ + public: + Book(); + ~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); + static bool sortByCreator(const Book& a, const Book& b); + static bool sortByPublisher(const Book& a, const Book& b); + static bool sortByLanguage(const Book& a, const Book& b); + std::string getHumanReadableIdFromPath(); + + bool readOnly() const { return m_readOnly; } + const std::string& getId() const { return m_id; } + const std::string& getPath() const { return m_path; } + const std::string& getIndexPath() const { return m_indexPath; } + const supportedIndexType& getIndexType() const { return m_indexType; } + const std::string& getTitle() const { return m_title; } + const std::string& getDescription() const { return m_description; } + const std::string& getLanguage() const { return m_language; } + const std::string& getCreator() const { return m_creator; } + const std::string& getPublisher() const { return m_publisher; } + const std::string& getDate() const { return m_date; } + const std::string& getUrl() const { return m_url; } + const std::string& getName() const { return m_name; } + const std::string& getTags() const { return m_tags; } + const std::string& getOrigId() const { return m_origId; } + const uint64_t& getArticleCount() const { return m_articleCount; } + const uint64_t& getMediaCount() const { return m_mediaCount; } + const uint64_t& getSize() const { return m_size; } + const std::string& getFavicon() const { return m_favicon; } + const std::string& getFaviconMimeType() const { return m_faviconMimeType; } + + void setReadOnly(bool readOnly) { m_readOnly = readOnly; } + void setId(const std::string& id) { m_id = id; } + void setPath(const std::string& path); + void setIndexPath(const std::string& indexPath); + void setIndexType(supportedIndexType indexType) { m_indexType = indexType;} + void setTitle(const std::string& title) { m_title = title; } + void setDescription(const std::string& description) { m_description = description; } + void setLanguage(const std::string& language) { m_language = language; } + void setCreator(const std::string& creator) { m_creator = creator; } + void setPublisher(const std::string& publisher) { m_publisher = publisher; } + void setDate(const std::string& date) { m_date = date; } + void setUrl(const std::string& url) { m_url = url; } + void setName(const std::string& name) { m_name = name; } + void setTags(const std::string& tags) { m_tags = tags; } + void setOrigId(const std::string& origId) { m_origId = origId; } + void setArticleCount(uint64_t articleCount) { m_articleCount = articleCount; } + void setMediaCount(uint64_t mediaCount) { m_mediaCount = mediaCount; } + void setSize(uint64_t size) { m_size = size; } + void setFavicon(const std::string& favicon) { m_favicon = favicon; } + void setFaviconMimeType(const std::string& faviconMimeType) { m_faviconMimeType = faviconMimeType; } + + protected: + std::string m_id; + std::string m_path; + std::string m_indexPath; + supportedIndexType m_indexType; + std::string m_title; + std::string m_description; + std::string m_language; + std::string m_creator; + std::string m_publisher; + std::string m_date; + std::string m_url; + std::string m_name; + std::string m_tags; + std::string m_origId; + uint64_t m_articleCount; + uint64_t m_mediaCount; + bool m_readOnly; + uint64_t m_size; + std::string m_favicon; + std::string m_faviconMimeType; +}; + +} + +#endif diff --git a/include/library.h b/include/library.h index 61b7cffc3..66dc64230 100644 --- a/include/library.h +++ b/include/library.h @@ -20,115 +20,17 @@ #ifndef KIWIX_LIBRARY_H #define KIWIX_LIBRARY_H -#include -#include -#include #include +#include #include -#include "common/regexTools.h" -#include "common/stringTools.h" - #define KIWIX_LIBRARY_VERSION "20110515" -using namespace std; - -namespace pugi { -class xml_node; -} - namespace kiwix { -enum supportedIndexType { UNKNOWN, XAPIAN }; +class Book; class OPDSDumper; -class Reader; - -/** - * A class to store information about a book (a zim file) - */ -class Book -{ - public: - Book(); - ~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); - static bool sortByCreator(const Book& a, const Book& b); - static bool sortByPublisher(const Book& a, const Book& b); - static bool sortByLanguage(const Book& a, const Book& b); - string getHumanReadableIdFromPath(); - - bool readOnly() const { return m_readOnly; } - const string& getId() const { return m_id; } - const string& getPath() const { return m_path; } - const string& getIndexPath() const { return m_indexPath; } - const supportedIndexType& getIndexType() const { return m_indexType; } - const string& getTitle() const { return m_title; } - const string& getDescription() const { return m_description; } - const string& getLanguage() const { return m_language; } - const string& getCreator() const { return m_creator; } - const string& getPublisher() const { return m_publisher; } - const string& getDate() const { return m_date; } - const string& getUrl() const { return m_url; } - const string& getName() const { return m_name; } - const string& getTags() const { return m_tags; } - const string& getOrigId() const { return m_origId; } - const uint64_t& getArticleCount() const { return m_articleCount; } - const uint64_t& getMediaCount() const { return m_mediaCount; } - const uint64_t& getSize() const { return m_size; } - const string& getFavicon() const { return m_favicon; } - const string& getFaviconMimeType() const { return m_faviconMimeType; } - - void setReadOnly(bool readOnly) { m_readOnly = readOnly; } - void setId(const std::string& id) { m_id = id; } - void setPath(const std::string& path); - void setIndexPath(const std::string& indexPath); - void setIndexType(supportedIndexType indexType) { m_indexType = indexType;} - void setTitle(const std::string& title) { m_title = title; } - void setDescription(const std::string& description) { m_description = description; } - void setLanguage(const std::string& language) { m_language = language; } - void setCreator(const std::string& creator) { m_creator = creator; } - void setPublisher(const std::string& publisher) { m_publisher = publisher; } - void setDate(const std::string& date) { m_date = date; } - void setUrl(const std::string& url) { m_url = url; } - void setName(const std::string& name) { m_name = name; } - void setTags(const std::string& tags) { m_tags = tags; } - void setOrigId(const std::string& origId) { m_origId = origId; } - void setArticleCount(uint64_t articleCount) { m_articleCount = articleCount; } - void setMediaCount(uint64_t mediaCount) { m_mediaCount = mediaCount; } - void setSize(uint64_t size) { m_size = size; } - void setFavicon(const std::string& favicon) { m_favicon = favicon; } - void setFaviconMimeType(const std::string& faviconMimeType) { m_faviconMimeType = faviconMimeType; } - - protected: - string m_id; - string m_path; - string m_indexPath; - supportedIndexType m_indexType; - string m_title; - string m_description; - string m_language; - string m_creator; - string m_publisher; - string m_date; - string m_url; - string m_name; - string m_tags; - string m_origId; - uint64_t m_articleCount; - uint64_t m_mediaCount; - bool m_readOnly; - uint64_t m_size; - string m_favicon; - string m_faviconMimeType; -}; /** * A Library store several books. @@ -140,7 +42,7 @@ class Library Library(); ~Library(); - string version; + std::string version; /** * Add a book to the library. * @@ -186,7 +88,7 @@ class Library * @param search List only books with search in the title or description. * @return A `Library`. */ - Library filter(const string& search); + Library filter(const std::string& search); /** * Get all langagues of the books in the library. diff --git a/include/manager.h b/include/manager.h index f0d8fd687..ef4606542 100644 --- a/include/manager.h +++ b/include/manager.h @@ -20,6 +20,7 @@ #ifndef KIWIX_MANAGER_H #define KIWIX_MANAGER_H +#include "book.h" #include #include #include diff --git a/include/meson.build b/include/meson.build index 1aca8b9ab..e7ab6eca8 100644 --- a/include/meson.build +++ b/include/meson.build @@ -1,4 +1,5 @@ headers = [ + 'book.h', 'common.h', 'library.h', 'manager.h', diff --git a/src/book.cpp b/src/book.cpp new file mode 100644 index 000000000..6d06f62bc --- /dev/null +++ b/src/book.cpp @@ -0,0 +1,218 @@ +/* + * Copyright 2011 Emmanuel Engelhart + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#include "book.h" +#include "reader.h" + +#include "common/base64.h" +#include "common/regexTools.h" + +#include + +namespace kiwix +{ +/* Constructor */ +Book::Book() : m_readOnly(false) +{ +} +/* Destructor */ +Book::~Book() +{ +} +/* Sort functions */ +bool Book::sortByTitle(const kiwix::Book& a, const kiwix::Book& b) +{ + return a.m_title < b.m_title; +} + +bool Book::sortByDate(const kiwix::Book& a, const kiwix::Book& b) +{ + return a.m_date < b.m_date; +} + +bool Book::sortBySize(const kiwix::Book& a, const kiwix::Book& b) +{ + return a.m_size < b.m_size; +} + +bool Book::sortByPublisher(const kiwix::Book& a, const kiwix::Book& b) +{ + return a.m_publisher < b.m_publisher; +} + +bool Book::sortByCreator(const kiwix::Book& a, const kiwix::Book& b) +{ + return a.m_creator < b.m_creator; +} + +bool Book::sortByLanguage(const kiwix::Book& a, const kiwix::Book& b) +{ + return a.m_language < b.m_language; +} + +bool Book::update(const kiwix::Book& other) +{ + if (m_readOnly) + return false; + + m_readOnly = other.m_readOnly; + + if (m_path.empty()) { + m_path = other.m_path; + } + + if (m_url.empty()) { + m_url = other.m_url; + } + + if (m_tags.empty()) { + m_tags = other.m_tags; + } + + if (m_name.empty()) { + m_name = other.m_name; + } + + if (m_indexPath.empty()) { + m_indexPath = other.m_indexPath; + m_indexType = other.m_indexType; + } + + if (m_faviconMimeType.empty()) { + m_favicon = other.m_favicon; + m_faviconMimeType = other.m_faviconMimeType; + } + return true; +} + +void Book::update(const kiwix::Reader& reader) +{ + m_path = reader.getZimFilePath(); + m_id = reader.getId(); + 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_name = reader.getName(); + m_tags = reader.getTags(); + m_origId = reader.getOrigId(); + m_articleCount = reader.getArticleCount(); + m_mediaCount = reader.getMediaCount(); + m_size = reader.getFileSize(); + + 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; + if (!id.empty()) { + kiwix::removeAccents(id); + +#ifdef _WIN32 + id = replaceRegex(id, "", "^.*\\\\"); +#else + id = replaceRegex(id, "", "^.*/"); +#endif + + id = replaceRegex(id, "", "\\.zim[a-z]*$"); + id = replaceRegex(id, "_", " "); + id = replaceRegex(id, "plus", "\\+"); + } + return id; +} + +void Book::setPath(const std::string& path) +{ + m_path = isRelativePath(path) + ? computeAbsolutePath(getCurrentDirectory(), path) + : path; +} + +void Book::setIndexPath(const std::string& indexPath) +{ + m_indexPath = isRelativePath(indexPath) + ? computeAbsolutePath(getCurrentDirectory(), indexPath) + : indexPath; +} + +} diff --git a/src/library.cpp b/src/library.cpp index 0926498a0..c9611ab08 100644 --- a/src/library.cpp +++ b/src/library.cpp @@ -18,202 +18,16 @@ */ #include "library.h" -#include "reader.h" +#include "book.h" #include "common/base64.h" +#include "common/regexTools.h" +#include "common/pathTools.h" #include namespace kiwix { -/* Constructor */ -Book::Book() : m_readOnly(false) -{ -} -/* Destructor */ -Book::~Book() -{ -} -/* Sort functions */ -bool Book::sortByTitle(const kiwix::Book& a, const kiwix::Book& b) -{ - return a.m_title < b.m_title; -} - -bool Book::sortByDate(const kiwix::Book& a, const kiwix::Book& b) -{ - return a.m_date < b.m_date; -} - -bool Book::sortBySize(const kiwix::Book& a, const kiwix::Book& b) -{ - return a.m_size < b.m_size; -} - -bool Book::sortByPublisher(const kiwix::Book& a, const kiwix::Book& b) -{ - return a.m_publisher < b.m_publisher; -} - -bool Book::sortByCreator(const kiwix::Book& a, const kiwix::Book& b) -{ - return a.m_creator < b.m_creator; -} - -bool Book::sortByLanguage(const kiwix::Book& a, const kiwix::Book& b) -{ - return a.m_language < b.m_language; -} - -bool Book::update(const kiwix::Book& other) -{ - if (m_readOnly) - return false; - - m_readOnly = other.m_readOnly; - - if (m_path.empty()) { - m_path = other.m_path; - } - - if (m_url.empty()) { - m_url = other.m_url; - } - - if (m_tags.empty()) { - m_tags = other.m_tags; - } - - if (m_name.empty()) { - m_name = other.m_name; - } - - if (m_indexPath.empty()) { - m_indexPath = other.m_indexPath; - m_indexType = other.m_indexType; - } - - if (m_faviconMimeType.empty()) { - m_favicon = other.m_favicon; - m_faviconMimeType = other.m_faviconMimeType; - } - return true; -} - -void Book::update(const kiwix::Reader& reader) -{ - m_path = reader.getZimFilePath(); - m_id = reader.getId(); - 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_name = reader.getName(); - m_tags = reader.getTags(); - m_origId = reader.getOrigId(); - m_articleCount = reader.getArticleCount(); - m_mediaCount = reader.getMediaCount(); - m_size = reader.getFileSize(); - - 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; - if (!id.empty()) { - kiwix::removeAccents(id); - -#ifdef _WIN32 - id = replaceRegex(id, "", "^.*\\\\"); -#else - id = replaceRegex(id, "", "^.*/"); -#endif - - id = replaceRegex(id, "", "\\.zim[a-z]*$"); - id = replaceRegex(id, "_", " "); - id = replaceRegex(id, "plus", "\\+"); - } - return id; -} - -void Book::setPath(const std::string& path) -{ - m_path = isRelativePath(path) - ? computeAbsolutePath(getCurrentDirectory(), path) - : path; -} - -void Book::setIndexPath(const std::string& indexPath) -{ - m_indexPath = isRelativePath(indexPath) - ? computeAbsolutePath(getCurrentDirectory(), indexPath) - : indexPath; -} - /* Constructor */ Library::Library() : version(KIWIX_LIBRARY_VERSION) { diff --git a/src/meson.build b/src/meson.build index ed0036e7f..deefdac8f 100644 --- a/src/meson.build +++ b/src/meson.build @@ -1,4 +1,5 @@ kiwix_sources = [ + 'book.cpp', 'library.cpp', 'manager.cpp', 'opds_dumper.cpp', diff --git a/src/opds_dumper.cpp b/src/opds_dumper.cpp index 584a3b5c0..e99d1f61d 100644 --- a/src/opds_dumper.cpp +++ b/src/opds_dumper.cpp @@ -18,7 +18,7 @@ */ #include "opds_dumper.h" - +#include "book.h" #include