mirror of https://github.com/kiwix/libkiwix.git
Make the Library`s book vector private.
Move a lot of methods from Manager to Library. Because books is private and thoses methods are better in Library.
This commit is contained in:
parent
741c67786a
commit
c9eac04050
|
@ -38,6 +38,7 @@ namespace kiwix
|
||||||
{
|
{
|
||||||
enum supportedIndexType { UNKNOWN, XAPIAN };
|
enum supportedIndexType { UNKNOWN, XAPIAN };
|
||||||
|
|
||||||
|
class OPDSDumper;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class to store information about a book (a zim file)
|
* A class to store information about a book (a zim file)
|
||||||
|
@ -88,6 +89,7 @@ class Book
|
||||||
*/
|
*/
|
||||||
class Library
|
class Library
|
||||||
{
|
{
|
||||||
|
std::vector<kiwix::Book> books;
|
||||||
public:
|
public:
|
||||||
Library();
|
Library();
|
||||||
~Library();
|
~Library();
|
||||||
|
@ -105,26 +107,72 @@ class Library
|
||||||
*/
|
*/
|
||||||
bool addBook(const Book& book);
|
bool addBook(const Book& book);
|
||||||
|
|
||||||
|
Book& getBookById(const std::string& id);
|
||||||
|
|
||||||
|
bool removeBookByIndex(const unsigned int bookIndex);
|
||||||
/**
|
/**
|
||||||
* Remove a book from the library.
|
* Remove a book from the library.
|
||||||
*
|
*
|
||||||
* @param bookIndex the index of the book to remove.
|
* @param id the id of the book to remove.
|
||||||
* @return True
|
* @return True if the book were in the lirbrary and has been removed.
|
||||||
*/
|
*/
|
||||||
bool removeBookByIndex(const unsigned int bookIndex);
|
bool removeBookById(const std::string& id);
|
||||||
vector<kiwix::Book> books;
|
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* 'current' is the variable storing the current content/book id
|
* Write the library to a file.
|
||||||
* in the library. This is used to be able to load per default a
|
*
|
||||||
* content. As Kiwix may work with many library XML files, you may
|
* @param path the path of the file to write to.
|
||||||
* have "current" defined many time with different values. The
|
* @return True if the library has been correctly save.
|
||||||
* last XML file read has the priority, Although we do not have an
|
|
||||||
* library object for each file, we want to be able to fallback to
|
|
||||||
* an 'old' current book if the one which should be load
|
|
||||||
* failed. That is the reason why we need a stack here
|
|
||||||
*/
|
*/
|
||||||
|
bool writeToFile(const std::string& path);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the number of book in the library.
|
||||||
|
*
|
||||||
|
* @param localBooks If we must count local books (books with a path).
|
||||||
|
* @param remoteBooks If we must count remote books (books with an url)
|
||||||
|
* @return The number of books.
|
||||||
|
*/
|
||||||
|
unsigned int getBookCount(const bool localBooks, const bool remoteBooks);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Filter the library and generate a new one with the keep elements.
|
||||||
|
*
|
||||||
|
* @param search List only books with search in the title or description.
|
||||||
|
* @return A `Library`.
|
||||||
|
*/
|
||||||
|
Library filter(const string& search);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all langagues of the books in the library.
|
||||||
|
*
|
||||||
|
* @return A list of languages.
|
||||||
|
*/
|
||||||
|
std::vector<std::string> getBooksLanguages();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all book creators of the books in the library.
|
||||||
|
*
|
||||||
|
* @return A list of book creators.
|
||||||
|
*/
|
||||||
|
std::vector<std::string> getBooksCreators();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all book publishers of the books in the library.
|
||||||
|
*
|
||||||
|
* @return A list of book publishers.
|
||||||
|
*/
|
||||||
|
std::vector<std::string> getBooksPublishers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get all book ids of the books in the library.
|
||||||
|
*
|
||||||
|
* @return A list of book ids.
|
||||||
|
*/
|
||||||
|
std::vector<std::string> getBooksIds();
|
||||||
|
|
||||||
stack<string> current;
|
stack<string> current;
|
||||||
|
friend class OPDSDumper;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -99,15 +99,6 @@ class Manager
|
||||||
*/
|
*/
|
||||||
bool readOpds(const string& content, const std::string& urlHost);
|
bool readOpds(const string& content, const std::string& urlHost);
|
||||||
|
|
||||||
/**
|
|
||||||
* Write the library to a file.
|
|
||||||
*
|
|
||||||
* @param path the path of the file to write.
|
|
||||||
* @return True.
|
|
||||||
*/
|
|
||||||
bool writeFile(const string path);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove a book from the library.
|
* Remove a book from the library.
|
||||||
*
|
*
|
||||||
|
@ -193,13 +184,6 @@ class Manager
|
||||||
const string url = "",
|
const string url = "",
|
||||||
const bool checkMetaData = false);
|
const bool checkMetaData = false);
|
||||||
|
|
||||||
/**
|
|
||||||
* Clone and return the internal library.
|
|
||||||
*
|
|
||||||
* @return A clone of the library.
|
|
||||||
*/
|
|
||||||
Library cloneLibrary();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the book corresponding to an id.
|
* Get the book corresponding to an id.
|
||||||
*
|
*
|
||||||
|
@ -217,15 +201,6 @@ class Manager
|
||||||
*/
|
*/
|
||||||
bool getCurrentBook(Book& book);
|
bool getCurrentBook(Book& book);
|
||||||
|
|
||||||
/**
|
|
||||||
* Get the number of book in the library.
|
|
||||||
*
|
|
||||||
* @param localBooks If we must count local books (books with a path).
|
|
||||||
* @param remoteBooks If we must count remote books (books with an url)
|
|
||||||
* @return The number of books.
|
|
||||||
*/
|
|
||||||
unsigned int getBookCount(const bool localBooks, const bool remoteBooks);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Update the "last open date" of a book
|
* Update the "last open date" of a book
|
||||||
*
|
*
|
||||||
|
@ -266,43 +241,6 @@ class Manager
|
||||||
const string publisher,
|
const string publisher,
|
||||||
const string search);
|
const string search);
|
||||||
|
|
||||||
/**
|
|
||||||
* Filter the library and generate a new one with the keep elements.
|
|
||||||
*
|
|
||||||
* @param search List only books with search in the title or description.
|
|
||||||
* @return A `Library`.
|
|
||||||
*/
|
|
||||||
Library filter(const string& search);
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all langagues of the books in the library.
|
|
||||||
*
|
|
||||||
* @return A list of languages.
|
|
||||||
*/
|
|
||||||
vector<string> getBooksLanguages();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all book creators of the books in the library.
|
|
||||||
*
|
|
||||||
* @return A list of book creators.
|
|
||||||
*/
|
|
||||||
vector<string> getBooksCreators();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all book publishers of the books in the library.
|
|
||||||
*
|
|
||||||
* @return A list of book publishers.
|
|
||||||
*/
|
|
||||||
vector<string> getBooksPublishers();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Get all book ids of the books in the library.
|
|
||||||
*
|
|
||||||
* @return A list of book ids.
|
|
||||||
*/
|
|
||||||
vector<string> getBooksIds();
|
|
||||||
|
|
||||||
string writableLibraryPath;
|
string writableLibraryPath;
|
||||||
|
|
||||||
vector<std::string> bookIdList;
|
vector<std::string> bookIdList;
|
||||||
|
|
214
src/library.cpp
214
src/library.cpp
|
@ -19,6 +19,8 @@
|
||||||
|
|
||||||
#include "library.h"
|
#include "library.h"
|
||||||
|
|
||||||
|
#include <pugixml.hpp>
|
||||||
|
|
||||||
namespace kiwix
|
namespace kiwix
|
||||||
{
|
{
|
||||||
/* Constructor */
|
/* Constructor */
|
||||||
|
@ -136,6 +138,8 @@ Library::Library() : version(KIWIX_LIBRARY_VERSION)
|
||||||
Library::~Library()
|
Library::~Library()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Library::addBook(const Book& book)
|
bool Library::addBook(const Book& book)
|
||||||
{
|
{
|
||||||
/* Try to find it */
|
/* Try to find it */
|
||||||
|
@ -152,9 +156,219 @@ bool Library::addBook(const Book& book)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool Library::removeBookByIndex(const unsigned int bookIndex)
|
bool Library::removeBookByIndex(const unsigned int bookIndex)
|
||||||
{
|
{
|
||||||
books.erase(books.begin() + bookIndex);
|
books.erase(books.begin() + bookIndex);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool Library::removeBookById(const std::string& id)
|
||||||
|
{
|
||||||
|
auto itr = books.begin();
|
||||||
|
for(; itr != books.end(); itr ++) {
|
||||||
|
if (itr->id == id) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (itr != books.end()) {
|
||||||
|
books.erase(itr);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Book& Library::getBookById(const std::string& id)
|
||||||
|
{
|
||||||
|
for(auto& book: books) {
|
||||||
|
if(book.id == id) {
|
||||||
|
return book;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw std::runtime_error("");
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int Library::getBookCount(const bool localBooks,
|
||||||
|
const bool remoteBooks)
|
||||||
|
{
|
||||||
|
unsigned int result = 0;
|
||||||
|
for (auto& book: books) {
|
||||||
|
if ((!book.path.empty() && localBooks)
|
||||||
|
|| (book.path.empty() && remoteBooks)) {
|
||||||
|
result++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
Library Library::filter(const std::string& search) {
|
||||||
|
Library library;
|
||||||
|
|
||||||
|
if (search.empty()) {
|
||||||
|
return library;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(auto& book:books) {
|
||||||
|
if (matchRegex(book.title, "\\Q" + search + "\\E")
|
||||||
|
|| matchRegex(book.description, "\\Q" + search + "\\E")) {
|
||||||
|
library.addBook(book);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return library;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Library::writeToFile(const std::string& path) {
|
||||||
|
pugi::xml_document doc;
|
||||||
|
|
||||||
|
/* Add the library node */
|
||||||
|
pugi::xml_node libraryNode = doc.append_child("library");
|
||||||
|
|
||||||
|
if (!version.empty())
|
||||||
|
libraryNode.append_attribute("version") = version.c_str();
|
||||||
|
|
||||||
|
/* Add each book */
|
||||||
|
for (auto& book: books) {
|
||||||
|
if (!book.readOnly) {
|
||||||
|
pugi::xml_node bookNode = libraryNode.append_child("book");
|
||||||
|
bookNode.append_attribute("id") = book.id.c_str();
|
||||||
|
|
||||||
|
if (!book.path.empty()) {
|
||||||
|
bookNode.append_attribute("path") = book.path.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!book.last.empty() && book.last != "undefined") {
|
||||||
|
bookNode.append_attribute("last") = book.last.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!book.indexPath.empty())
|
||||||
|
bookNode.append_attribute("indexPath") = book.indexPath.c_str();
|
||||||
|
|
||||||
|
if (!book.indexPath.empty() || !book.indexPathAbsolute.empty()) {
|
||||||
|
if (book.indexType == XAPIAN) {
|
||||||
|
bookNode.append_attribute("indexType") = "xapian";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (book.origId.empty()) {
|
||||||
|
if (!book.title.empty())
|
||||||
|
bookNode.append_attribute("title") = book.title.c_str();
|
||||||
|
|
||||||
|
if (!book.name.empty())
|
||||||
|
bookNode.append_attribute("name") = book.name.c_str();
|
||||||
|
|
||||||
|
if (!book.tags.empty())
|
||||||
|
bookNode.append_attribute("tags") = book.tags.c_str();
|
||||||
|
|
||||||
|
if (!book.description.empty())
|
||||||
|
bookNode.append_attribute("description") = book.description.c_str();
|
||||||
|
|
||||||
|
if (!book.language.empty())
|
||||||
|
bookNode.append_attribute("language") = book.language.c_str();
|
||||||
|
|
||||||
|
if (!book.creator.empty())
|
||||||
|
bookNode.append_attribute("creator") = book.creator.c_str();
|
||||||
|
|
||||||
|
if (!book.publisher.empty())
|
||||||
|
bookNode.append_attribute("publisher") = book.publisher.c_str();
|
||||||
|
|
||||||
|
if (!book.favicon.empty())
|
||||||
|
bookNode.append_attribute("favicon") = book.favicon.c_str();
|
||||||
|
|
||||||
|
if (!book.faviconMimeType.empty())
|
||||||
|
bookNode.append_attribute("faviconMimeType")
|
||||||
|
= book.faviconMimeType.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!book.date.empty()) {
|
||||||
|
bookNode.append_attribute("date") = book.date.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!book.url.empty()) {
|
||||||
|
bookNode.append_attribute("url") = book.url.c_str();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!book.origId.empty())
|
||||||
|
bookNode.append_attribute("origId") = book.origId.c_str();
|
||||||
|
|
||||||
|
if (!book.articleCount.empty())
|
||||||
|
bookNode.append_attribute("articleCount") = book.articleCount.c_str();
|
||||||
|
|
||||||
|
if (!book.mediaCount.empty())
|
||||||
|
bookNode.append_attribute("mediaCount") = book.mediaCount.c_str();
|
||||||
|
|
||||||
|
if (!book.size.empty()) {
|
||||||
|
bookNode.append_attribute("size") = book.size.c_str();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* saving file */
|
||||||
|
return doc.save_file(path.c_str());
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> Library::getBooksLanguages()
|
||||||
|
{
|
||||||
|
std::vector<std::string> booksLanguages;
|
||||||
|
std::map<std::string, bool> booksLanguagesMap;
|
||||||
|
|
||||||
|
for (auto& book: books) {
|
||||||
|
if (booksLanguagesMap.find(book.language) == booksLanguagesMap.end()) {
|
||||||
|
if (book.origId.empty()) {
|
||||||
|
booksLanguagesMap[book.language] = true;
|
||||||
|
booksLanguages.push_back(book.language);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return booksLanguages;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> Library::getBooksCreators()
|
||||||
|
{
|
||||||
|
std::vector<std::string> booksCreators;
|
||||||
|
std::map<std::string, bool> booksCreatorsMap;
|
||||||
|
|
||||||
|
for (auto& book: books) {
|
||||||
|
if (booksCreatorsMap.find(book.creator) == booksCreatorsMap.end()) {
|
||||||
|
if (book.origId.empty()) {
|
||||||
|
booksCreatorsMap[book.creator] = true;
|
||||||
|
booksCreators.push_back(book.creator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return booksCreators;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> Library::getBooksIds()
|
||||||
|
{
|
||||||
|
std::vector<std::string> booksIds;
|
||||||
|
|
||||||
|
for (auto& book: books) {
|
||||||
|
booksIds.push_back(book.id);
|
||||||
|
}
|
||||||
|
|
||||||
|
return booksIds;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> Library::getBooksPublishers()
|
||||||
|
{
|
||||||
|
std::vector<std::string> booksPublishers;
|
||||||
|
std::map<std::string, bool> booksPublishersMap;
|
||||||
|
|
||||||
|
for (auto& book:books) {
|
||||||
|
if (booksPublishersMap.find(book.publisher) == booksPublishersMap.end()) {
|
||||||
|
if (book.origId.empty()) {
|
||||||
|
booksPublishersMap[book.publisher] = true;
|
||||||
|
booksPublishers.push_back(book.publisher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return booksPublishers;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
371
src/manager.cpp
371
src/manager.cpp
|
@ -194,105 +194,6 @@ bool Manager::readFile(const string nativePath,
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::writeFile(const string path)
|
|
||||||
{
|
|
||||||
pugi::xml_document doc;
|
|
||||||
|
|
||||||
/* Add the library node */
|
|
||||||
pugi::xml_node libraryNode = doc.append_child("library");
|
|
||||||
|
|
||||||
if (!getCurrentBookId().empty()) {
|
|
||||||
libraryNode.append_attribute("current") = getCurrentBookId().c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!library.version.empty())
|
|
||||||
libraryNode.append_attribute("version") = library.version.c_str();
|
|
||||||
|
|
||||||
/* Add each book */
|
|
||||||
std::vector<kiwix::Book>::iterator itr;
|
|
||||||
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
|
|
||||||
if (!itr->readOnly) {
|
|
||||||
this->checkAndCleanBookPaths(*itr, path);
|
|
||||||
|
|
||||||
pugi::xml_node bookNode = libraryNode.append_child("book");
|
|
||||||
bookNode.append_attribute("id") = itr->id.c_str();
|
|
||||||
|
|
||||||
if (!itr->path.empty()) {
|
|
||||||
bookNode.append_attribute("path") = itr->path.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!itr->last.empty() && itr->last != "undefined") {
|
|
||||||
bookNode.append_attribute("last") = itr->last.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!itr->indexPath.empty())
|
|
||||||
bookNode.append_attribute("indexPath") = itr->indexPath.c_str();
|
|
||||||
|
|
||||||
if (!itr->indexPath.empty() || !itr->indexPathAbsolute.empty()) {
|
|
||||||
if (itr->indexType == XAPIAN) {
|
|
||||||
bookNode.append_attribute("indexType") = "xapian";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (itr->origId.empty()) {
|
|
||||||
if (!itr->title.empty())
|
|
||||||
bookNode.append_attribute("title") = itr->title.c_str();
|
|
||||||
|
|
||||||
if (!itr->name.empty())
|
|
||||||
bookNode.append_attribute("name") = itr->name.c_str();
|
|
||||||
|
|
||||||
if (!itr->tags.empty())
|
|
||||||
bookNode.append_attribute("tags") = itr->tags.c_str();
|
|
||||||
|
|
||||||
if (!itr->description.empty())
|
|
||||||
bookNode.append_attribute("description") = itr->description.c_str();
|
|
||||||
|
|
||||||
if (!itr->language.empty())
|
|
||||||
bookNode.append_attribute("language") = itr->language.c_str();
|
|
||||||
|
|
||||||
if (!itr->creator.empty())
|
|
||||||
bookNode.append_attribute("creator") = itr->creator.c_str();
|
|
||||||
|
|
||||||
if (!itr->publisher.empty())
|
|
||||||
bookNode.append_attribute("publisher") = itr->publisher.c_str();
|
|
||||||
|
|
||||||
if (!itr->favicon.empty())
|
|
||||||
bookNode.append_attribute("favicon") = itr->favicon.c_str();
|
|
||||||
|
|
||||||
if (!itr->faviconMimeType.empty())
|
|
||||||
bookNode.append_attribute("faviconMimeType")
|
|
||||||
= itr->faviconMimeType.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!itr->date.empty()) {
|
|
||||||
bookNode.append_attribute("date") = itr->date.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!itr->url.empty()) {
|
|
||||||
bookNode.append_attribute("url") = itr->url.c_str();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!itr->origId.empty())
|
|
||||||
bookNode.append_attribute("origId") = itr->origId.c_str();
|
|
||||||
|
|
||||||
if (!itr->articleCount.empty())
|
|
||||||
bookNode.append_attribute("articleCount") = itr->articleCount.c_str();
|
|
||||||
|
|
||||||
if (!itr->mediaCount.empty())
|
|
||||||
bookNode.append_attribute("mediaCount") = itr->mediaCount.c_str();
|
|
||||||
|
|
||||||
if (!itr->size.empty()) {
|
|
||||||
bookNode.append_attribute("size") = itr->size.c_str();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* saving file */
|
|
||||||
doc.save_file(path.c_str());
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
bool Manager::setCurrentBookId(const string id)
|
bool Manager::setCurrentBookId(const string id)
|
||||||
{
|
{
|
||||||
|
@ -411,300 +312,62 @@ bool Manager::removeBookByIndex(const unsigned int bookIndex)
|
||||||
|
|
||||||
bool Manager::removeBookById(const string id)
|
bool Manager::removeBookById(const string id)
|
||||||
{
|
{
|
||||||
unsigned int bookIndex = 0;
|
return library.removeBookById(id);
|
||||||
std::vector<kiwix::Book>::iterator itr;
|
|
||||||
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
|
|
||||||
if (itr->id == id) {
|
|
||||||
return this->library.removeBookByIndex(bookIndex);
|
|
||||||
}
|
|
||||||
bookIndex++;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vector<string> Manager::getBooksLanguages()
|
|
||||||
{
|
|
||||||
std::vector<string> booksLanguages;
|
|
||||||
std::vector<kiwix::Book>::iterator itr;
|
|
||||||
std::map<string, bool> booksLanguagesMap;
|
|
||||||
|
|
||||||
std::sort(
|
|
||||||
library.books.begin(), library.books.end(), kiwix::Book::sortByLanguage);
|
|
||||||
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
|
|
||||||
if (booksLanguagesMap.find(itr->language) == booksLanguagesMap.end()) {
|
|
||||||
if (itr->origId.empty()) {
|
|
||||||
booksLanguagesMap[itr->language] = true;
|
|
||||||
booksLanguages.push_back(itr->language);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return booksLanguages;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<string> Manager::getBooksCreators()
|
|
||||||
{
|
|
||||||
std::vector<string> booksCreators;
|
|
||||||
std::vector<kiwix::Book>::iterator itr;
|
|
||||||
std::map<string, bool> booksCreatorsMap;
|
|
||||||
|
|
||||||
std::sort(
|
|
||||||
library.books.begin(), library.books.end(), kiwix::Book::sortByCreator);
|
|
||||||
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
|
|
||||||
if (booksCreatorsMap.find(itr->creator) == booksCreatorsMap.end()) {
|
|
||||||
if (itr->origId.empty()) {
|
|
||||||
booksCreatorsMap[itr->creator] = true;
|
|
||||||
booksCreators.push_back(itr->creator);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return booksCreators;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<string> Manager::getBooksIds()
|
|
||||||
{
|
|
||||||
std::vector<string> booksIds;
|
|
||||||
std::vector<kiwix::Book>::iterator itr;
|
|
||||||
|
|
||||||
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
|
|
||||||
booksIds.push_back(itr->id);
|
|
||||||
}
|
|
||||||
|
|
||||||
return booksIds;
|
|
||||||
}
|
|
||||||
|
|
||||||
vector<string> Manager::getBooksPublishers()
|
|
||||||
{
|
|
||||||
std::vector<string> booksPublishers;
|
|
||||||
std::vector<kiwix::Book>::iterator itr;
|
|
||||||
std::map<string, bool> booksPublishersMap;
|
|
||||||
|
|
||||||
std::sort(
|
|
||||||
library.books.begin(), library.books.end(), kiwix::Book::sortByPublisher);
|
|
||||||
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
|
|
||||||
if (booksPublishersMap.find(itr->publisher) == booksPublishersMap.end()) {
|
|
||||||
if (itr->origId.empty()) {
|
|
||||||
booksPublishersMap[itr->publisher] = true;
|
|
||||||
booksPublishers.push_back(itr->publisher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return booksPublishers;
|
|
||||||
}
|
|
||||||
|
|
||||||
kiwix::Library Manager::cloneLibrary()
|
|
||||||
{
|
|
||||||
return this->library;
|
|
||||||
}
|
|
||||||
bool Manager::getCurrentBook(Book& book)
|
bool Manager::getCurrentBook(Book& book)
|
||||||
{
|
{
|
||||||
string currentBookId = getCurrentBookId();
|
string currentBookId = getCurrentBookId();
|
||||||
if (currentBookId.empty()) {
|
if (currentBookId.empty()) {
|
||||||
return false;
|
return false;
|
||||||
} else {
|
} else {
|
||||||
getBookById(currentBookId, book);
|
book = library.getBookById(currentBookId);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::getBookById(const string id, Book& book)
|
|
||||||
{
|
|
||||||
std::vector<kiwix::Book>::iterator itr;
|
|
||||||
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
|
|
||||||
if (itr->id == id) {
|
|
||||||
book = *itr;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Manager::updateBookLastOpenDateById(const string id)
|
bool Manager::updateBookLastOpenDateById(const string id)
|
||||||
{
|
try {
|
||||||
std::vector<kiwix::Book>::iterator itr;
|
auto book = library.getBookById(id);
|
||||||
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
|
|
||||||
if (itr->id == id) {
|
|
||||||
char unixdate[12];
|
char unixdate[12];
|
||||||
sprintf(unixdate, "%d", (int)time(NULL));
|
sprintf(unixdate, "%d", (int)time(NULL));
|
||||||
itr->last = unixdate;
|
book.last = unixdate;
|
||||||
return true;
|
return true;
|
||||||
}
|
} catch(...) {
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::setBookIndex(const string id,
|
bool Manager::setBookIndex(const string id,
|
||||||
const string path,
|
const string path,
|
||||||
const supportedIndexType type)
|
const supportedIndexType type)
|
||||||
{
|
try {
|
||||||
std::vector<kiwix::Book>::iterator itr;
|
auto book = library.getBookById(id);
|
||||||
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
|
book.indexPath = path;
|
||||||
if (itr->id == id) {
|
book.indexPathAbsolute = isRelativePath(path)
|
||||||
itr->indexPath = path;
|
|
||||||
itr->indexPathAbsolute
|
|
||||||
= isRelativePath(path)
|
|
||||||
? computeAbsolutePath(
|
? computeAbsolutePath(
|
||||||
removeLastPathElement(writableLibraryPath, true, false),
|
removeLastPathElement(writableLibraryPath, true, false),
|
||||||
path)
|
path)
|
||||||
: path;
|
: path;
|
||||||
itr->indexType = type;
|
book.indexType = type;
|
||||||
return true;
|
return true;
|
||||||
}
|
} catch (...) {
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::setBookPath(const string id, const string path)
|
bool Manager::setBookPath(const string id, const string path)
|
||||||
{
|
try {
|
||||||
std::vector<kiwix::Book>::iterator itr;
|
auto book = library.getBookById(id);
|
||||||
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
|
book.path = path;
|
||||||
if (itr->id == id) {
|
book.pathAbsolute = isRelativePath(path)
|
||||||
itr->path = path;
|
|
||||||
itr->pathAbsolute
|
|
||||||
= isRelativePath(path)
|
|
||||||
? computeAbsolutePath(
|
? computeAbsolutePath(
|
||||||
removeLastPathElement(writableLibraryPath, true, false),
|
removeLastPathElement(writableLibraryPath, true, false),
|
||||||
path)
|
path)
|
||||||
: path;
|
: path;
|
||||||
return true;
|
return true;
|
||||||
}
|
} catch(...) {
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::removeBookPaths()
|
|
||||||
{
|
|
||||||
std::vector<kiwix::Book>::iterator itr;
|
|
||||||
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
|
|
||||||
itr->path = "";
|
|
||||||
itr->pathAbsolute = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
unsigned int Manager::getBookCount(const bool localBooks,
|
|
||||||
const bool remoteBooks)
|
|
||||||
{
|
|
||||||
unsigned int result = 0;
|
|
||||||
std::vector<kiwix::Book>::iterator itr;
|
|
||||||
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
|
|
||||||
if ((!itr->path.empty() && localBooks)
|
|
||||||
|| (itr->path.empty() && remoteBooks)) {
|
|
||||||
result++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Manager::listBooks(const supportedListMode mode,
|
|
||||||
const supportedListSortBy sortBy,
|
|
||||||
const unsigned int maxSize,
|
|
||||||
const string language,
|
|
||||||
const string creator,
|
|
||||||
const string publisher,
|
|
||||||
const string search)
|
|
||||||
{
|
|
||||||
this->bookIdList.clear();
|
|
||||||
std::vector<kiwix::Book>::iterator itr;
|
|
||||||
|
|
||||||
/* Sort */
|
|
||||||
if (sortBy == TITLE) {
|
|
||||||
std::sort(
|
|
||||||
library.books.begin(), library.books.end(), kiwix::Book::sortByTitle);
|
|
||||||
} else if (sortBy == SIZE) {
|
|
||||||
std::sort(
|
|
||||||
library.books.begin(), library.books.end(), kiwix::Book::sortBySize);
|
|
||||||
} else if (sortBy == DATE) {
|
|
||||||
std::sort(
|
|
||||||
library.books.begin(), library.books.end(), kiwix::Book::sortByDate);
|
|
||||||
} else if (sortBy == CREATOR) {
|
|
||||||
std::sort(
|
|
||||||
library.books.begin(), library.books.end(), kiwix::Book::sortByCreator);
|
|
||||||
} else if (sortBy == PUBLISHER) {
|
|
||||||
std::sort(library.books.begin(),
|
|
||||||
library.books.end(),
|
|
||||||
kiwix::Book::sortByPublisher);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Special sort for LASTOPEN */
|
|
||||||
if (mode == LASTOPEN) {
|
|
||||||
std::sort(library.books.begin(),
|
|
||||||
library.books.end(),
|
|
||||||
kiwix::Book::sortByLastOpen);
|
|
||||||
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
|
|
||||||
if (!itr->last.empty()) {
|
|
||||||
this->bookIdList.push_back(itr->id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
/* Generate the list of book id */
|
|
||||||
for (itr = library.books.begin(); itr != library.books.end(); ++itr) {
|
|
||||||
bool ok = true;
|
|
||||||
|
|
||||||
if (mode == LOCAL && itr->path.empty()) {
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok == true && mode == REMOTE
|
|
||||||
&& (!itr->path.empty() || itr->url.empty())) {
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok == true && maxSize != 0
|
|
||||||
&& (unsigned int)atoi(itr->size.c_str()) > maxSize * 1024 * 1024) {
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok == true && !language.empty()
|
|
||||||
&& !matchRegex(itr->language, language)) {
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok == true && !creator.empty() && itr->creator != creator) {
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok == true && !publisher.empty() && itr->publisher != publisher) {
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((ok == true && !search.empty())
|
|
||||||
&& !(matchRegex(itr->title, "\\Q" + search + "\\E")
|
|
||||||
|| matchRegex(itr->description, "\\Q" + search + "\\E")
|
|
||||||
|| matchRegex(itr->language, "\\Q" + search + "\\E"))) {
|
|
||||||
ok = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ok == true) {
|
|
||||||
this->bookIdList.push_back(itr->id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
Library Manager::filter(const std::string& search) {
|
|
||||||
Library library;
|
|
||||||
|
|
||||||
if (search.empty()) {
|
|
||||||
return library;
|
|
||||||
}
|
|
||||||
|
|
||||||
for(auto book:this->library.books) {
|
|
||||||
if (matchRegex(book.title, "\\Q" + search + "\\E")
|
|
||||||
|| matchRegex(book.description, "\\Q" + search + "\\E")) {
|
|
||||||
library.addBook(book);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return library;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Manager::checkAndCleanBookPaths(Book& book, const string& libraryPath)
|
void Manager::checkAndCleanBookPaths(Book& book, const string& libraryPath)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue