Move the `Book` class in its own source file.

This commit is contained in:
Matthieu Gautier 2018-09-06 15:45:45 +02:00
parent 1e8f85eaff
commit 839320d5e7
8 changed files with 353 additions and 292 deletions

124
include/book.h Normal file
View File

@ -0,0 +1,124 @@
/*
* Copyright 2011 Emmanuel Engelhart <kelson@kiwix.org>
*
* 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 <string>
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

View File

@ -20,115 +20,17 @@
#ifndef KIWIX_LIBRARY_H
#define KIWIX_LIBRARY_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <vector>
#include <map>
#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.

View File

@ -20,6 +20,7 @@
#ifndef KIWIX_MANAGER_H
#define KIWIX_MANAGER_H
#include "book.h"
#include <time.h>
#include <sstream>
#include <string>

View File

@ -1,4 +1,5 @@
headers = [
'book.h',
'common.h',
'library.h',
'manager.h',

218
src/book.cpp Normal file
View File

@ -0,0 +1,218 @@
/*
* Copyright 2011 Emmanuel Engelhart <kelson@kiwix.org>
*
* 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 <pugixml.hpp>
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;
}
}

View File

@ -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 <pugixml.hpp>
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)
{

View File

@ -1,4 +1,5 @@
kiwix_sources = [
'book.cpp',
'library.cpp',
'manager.cpp',
'opds_dumper.cpp',

View File

@ -18,7 +18,7 @@
*/
#include "opds_dumper.h"
#include "book.h"
#include <common/otherTools.h>