Reimplement listBooksIds.

No real improvement.
This commit is contained in:
Matthieu Gautier 2018-09-06 18:22:12 +02:00
parent 99e313f915
commit 7804bf2276
5 changed files with 168 additions and 75 deletions

View File

@ -46,12 +46,6 @@ class Book
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; }

View File

@ -32,6 +32,8 @@ namespace kiwix
class Book;
class OPDSDumper;
enum supportedListSortBy { UNSORTED, TITLE, SIZE, DATE, CREATOR, PUBLISHER };
enum supportedListMode { ALL, REMOTE, LOCAL };
/**
* A Library store several books.
*/
@ -82,14 +84,6 @@ class Library
*/
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 std::string& search);
/**
* Get all langagues of the books in the library.
*
@ -118,6 +112,43 @@ class Library
*/
std::vector<std::string> getBooksIds();
/**
* Filter the library and generate a new one with the keep elements.
*
* This is equivalent to `listBookIds(ALL, UNSORTED, search)`.
*
* @param search List only books with search in the title or description.
* @return The list of bookIds corresponding to the query.
*/
std::vector<std::string> filter(const std::string& search);
/**
* List books in the library.
*
* @param mode The mode of listing :
* - ALL list all books.
* (LOCAL and REMOTE. Other filters are applied).
* - LOCAL list only local books.
* - REMOTE list only remote books.
* @param sortBy Attribute to sort by the book list.
* @param search List only books with search in the title, description.
* @param language List only books in this language.
* @param creator List only books of this creator.
* @param publisher List only books of this publisher.
* @param maxSize Do not list book bigger than maxSize.
* Set to 0 to cancel this filter.
* @return The list of bookIds corresponding to the query.
*/
std::vector<std::string> listBooksIds(
supportedListMode = ALL,
supportedListSortBy sortBy = UNSORTED,
const std::string& search = "",
const std::string& language = "",
const std::string& creator = "",
const std::string& publisher = "",
size_t maxSize = 0);
friend class OPDSDumper;
};
}

View File

@ -33,8 +33,6 @@ class xml_document;
namespace kiwix
{
enum supportedListMode { LASTOPEN, REMOTE, LOCAL };
enum supportedListSortBy { TITLE, SIZE, DATE, CREATOR, PUBLISHER };
/**
* A tool to manage a `Library`.

View File

@ -35,36 +35,6 @@ Book::Book() : m_readOnly(false)
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)
{

View File

@ -25,6 +25,7 @@
#include "common/pathTools.h"
#include <pugixml.hpp>
#include <algorithm>
namespace kiwix
{
@ -77,24 +78,6 @@ unsigned int Library::getBookCount(const bool localBooks,
return result;
}
Library Library::filter(const std::string& search) {
Library library;
if (search.empty()) {
return library;
}
for(auto& pair:books) {
auto& book = pair.second;
if (matchRegex(book.getTitle(), "\\Q" + search + "\\E")
|| matchRegex(book.getDescription(), "\\Q" + search + "\\E")) {
library.addBook(book);
}
}
return library;
}
bool Library::writeToFile(const std::string& path) {
pugi::xml_document doc;
auto baseDir = removeLastPathElement(path, true, false);
@ -217,17 +200,6 @@ std::vector<std::string> Library::getBooksCreators()
return booksCreators;
}
std::vector<std::string> Library::getBooksIds()
{
std::vector<std::string> booksIds;
for (auto& pair: books) {
booksIds.push_back(pair.first);
}
return booksIds;
}
std::vector<std::string> Library::getBooksPublishers()
{
std::vector<std::string> booksPublishers;
@ -247,6 +219,134 @@ std::vector<std::string> Library::getBooksPublishers()
return booksPublishers;
}
std::vector<std::string> Library::getBooksIds()
{
std::vector<std::string> bookIds;
for (auto& pair: books) {
bookIds.push_back(pair.first);
}
return bookIds;
}
std::vector<std::string> Library::filter(const std::string& search)
{
if (search.empty()) {
return getBooksIds();
}
std::vector<std::string> bookIds;
for(auto& pair:books) {
auto& book = pair.second;
if (matchRegex(book.getTitle(), "\\Q" + search + "\\E")
|| matchRegex(book.getDescription(), "\\Q" + search + "\\E")) {
bookIds.push_back(pair.first);
}
}
return bookIds;
}
template<supportedListSortBy sort>
struct Comparator {
Library* lib;
Comparator(Library* lib) : lib(lib) {}
bool operator() (const std::string& id1, const std::string& id2) {
return get_keys(id1) < get_keys(id2);
}
std::string get_keys(const std::string& id);
unsigned int get_keyi(const std::string& id);
};
template<>
std::string Comparator<TITLE>::get_keys(const std::string& id)
{
return lib->getBookById(id).getTitle();
}
template<>
unsigned int Comparator<SIZE>::get_keyi(const std::string& id)
{
return lib->getBookById(id).getSize();
}
template<>
bool Comparator<SIZE>::operator() (const std::string& id1, const std::string& id2)
{
return get_keyi(id1) < get_keyi(id2);
}
template<>
std::string Comparator<DATE>::get_keys(const std::string& id)
{
return lib->getBookById(id).getDate();
}
template<>
std::string Comparator<CREATOR>::get_keys(const std::string& id)
{
return lib->getBookById(id).getCreator();
}
template<>
std::string Comparator<PUBLISHER>::get_keys(const std::string& id)
{
return lib->getBookById(id).getPublisher();
}
std::vector<std::string> Library::listBooksIds(
supportedListMode mode,
supportedListSortBy sortBy,
const std::string& search,
const std::string& language,
const std::string& creator,
const std::string& publisher,
size_t maxSize) {
std::vector<std::string> bookIds;
for(auto& pair:books) {
auto& book = pair.second;
if (mode == LOCAL && book.getPath().empty())
continue;
if (mode == REMOTE && (!book.getPath().empty() || book.getUrl().empty()))
continue;
if (maxSize != 0 && book.getSize() > maxSize)
continue;
if (!language.empty() && book.getLanguage() != language)
continue;
if (!publisher.empty() && book.getPublisher() != publisher)
continue;
if (!creator.empty() && book.getCreator() != creator)
continue;
if (!search.empty() && !(matchRegex(book.getTitle(), "\\Q" + search + "\\E")
|| matchRegex(book.getDescription(), "\\Q" + search + "\\E")))
continue;
bookIds.push_back(pair.first);
}
switch(sortBy) {
case TITLE:
std::sort(bookIds.begin(), bookIds.end(), Comparator<TITLE>(this));
break;
case SIZE:
std::sort(bookIds.begin(), bookIds.end(), Comparator<SIZE>(this));
break;
case DATE:
std::sort(bookIds.begin(), bookIds.end(), Comparator<DATE>(this));
break;
case CREATOR:
std::sort(bookIds.begin(), bookIds.end(), Comparator<CREATOR>(this));
break;
case PUBLISHER:
std::sort(bookIds.begin(), bookIds.end(), Comparator<PUBLISHER>(this));
break;
default:
break;
}
return bookIds;
}
}