Languages OPDS feed includes book counts

This commit is contained in:
Veloman Yunkan 2021-07-08 17:00:54 +04:00 committed by Matthieu Gautier
parent 45adda44b3
commit ab3095745e
5 changed files with 34 additions and 5 deletions

View File

@ -154,6 +154,7 @@ class Library
public: public:
typedef std::vector<std::string> BookIdCollection; typedef std::vector<std::string> BookIdCollection;
typedef std::map<std::string, int> AttributeCounts;
public: public:
Library(); Library();
@ -242,6 +243,13 @@ class Library
*/ */
std::vector<std::string> getBooksLanguages() const; std::vector<std::string> getBooksLanguages() const;
/**
* Get all languagues of the books in the library with counts.
*
* @return A list of languages with the count of books in each language.
*/
AttributeCounts getBooksLanguagesWithCounts() const;
/** /**
* Get all categories of the books in the library. * Get all categories of the books in the library.
* *
@ -345,6 +353,7 @@ private: // types
typedef const std::string& (Book::*BookStrPropMemFn)() const; typedef const std::string& (Book::*BookStrPropMemFn)() const;
private: // functions private: // functions
AttributeCounts getBookAttributeCounts(BookStrPropMemFn p) const;
std::vector<std::string> getBookPropValueSet(BookStrPropMemFn p) const; std::vector<std::string> getBookPropValueSet(BookStrPropMemFn p) const;
BookIdCollection filterViaBookDB(const Filter& filter) const; BookIdCollection filterViaBookDB(const Filter& filter) const;
void updateBookDB(const Book& book); void updateBookDB(const Book& book);

View File

@ -208,18 +208,26 @@ bool Library::writeBookmarksToFile(const std::string& path) const
return writeTextFile(path, dumper.dumpLibXMLBookmark()); return writeTextFile(path, dumper.dumpLibXMLBookmark());
} }
std::vector<std::string> Library::getBookPropValueSet(BookStrPropMemFn p) const Library::AttributeCounts Library::getBookAttributeCounts(BookStrPropMemFn p) const
{ {
std::set<std::string> propValues; AttributeCounts propValueCounts;
for (const auto& pair: m_books) { for (const auto& pair: m_books) {
const auto& book = pair.second; const auto& book = pair.second;
if (book.getOrigId().empty()) { if (book.getOrigId().empty()) {
propValues.insert((book.*p)()); propValueCounts[(book.*p)()] += 1;
} }
} }
return propValueCounts;
}
return std::vector<std::string>(propValues.begin(), propValues.end()); std::vector<std::string> Library::getBookPropValueSet(BookStrPropMemFn p) const
{
std::vector<std::string> result;
for ( const auto& kv : getBookAttributeCounts(p) ) {
result.push_back(kv.first);
}
return result;
} }
std::vector<std::string> Library::getBooksLanguages() const std::vector<std::string> Library::getBooksLanguages() const
@ -227,6 +235,11 @@ std::vector<std::string> Library::getBooksLanguages() const
return getBookPropValueSet(&Book::getLanguage); return getBookPropValueSet(&Book::getLanguage);
} }
Library::AttributeCounts Library::getBooksLanguagesWithCounts() const
{
return getBookAttributeCounts(&Book::getLanguage);
}
std::vector<std::string> Library::getBooksCategories() const std::vector<std::string> Library::getBooksCategories() const
{ {
std::set<std::string> categories; std::set<std::string> categories;

View File

@ -160,11 +160,14 @@ std::string OPDSDumper::languagesOPDSFeed() const
{ {
const auto now = gen_date_str(); const auto now = gen_date_str();
kainjow::mustache::list languageData; kainjow::mustache::list languageData;
for ( const auto& languageCode : library->getBooksLanguages() ) { for ( const auto& langAndBookCount : library->getBooksLanguagesWithCounts() ) {
const std::string languageCode = langAndBookCount.first;
const int bookCount = langAndBookCount.second;
const auto languageSelfName = getLanguageSelfName(languageCode); const auto languageSelfName = getLanguageSelfName(languageCode);
languageData.push_back(kainjow::mustache::object{ languageData.push_back(kainjow::mustache::object{
{"lang_code", languageCode}, {"lang_code", languageCode},
{"lang_self_name", languageSelfName}, {"lang_self_name", languageSelfName},
{"book_count", to_string(bookCount)},
{"updated", now}, {"updated", now},
{"id", gen_uuid(libraryId + "/languages/" + languageCode)} {"id", gen_uuid(libraryId + "/languages/" + languageCode)}
}); });

View File

@ -16,6 +16,7 @@
<entry> <entry>
<title>{{lang_self_name}}</title> <title>{{lang_self_name}}</title>
<dc:language>{{{lang_code}}}</dc:language> <dc:language>{{{lang_code}}}</dc:language>
<thr:count>{{book_count}}</thr:count>
<link rel="subsection" <link rel="subsection"
href="{{endpoint_root}}/entries?lang={{{lang_code}}}" href="{{endpoint_root}}/entries?lang={{{lang_code}}}"
type="application/atom+xml;profile=opds-catalog;kind=acquisition"/> type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>

View File

@ -1035,6 +1035,7 @@ TEST_F(LibraryServerTest, catalog_v2_languages)
<entry> <entry>
<title>English</title> <title>English</title>
<dc:language>eng</dc:language> <dc:language>eng</dc:language>
<thr:count>1</thr:count>
<link rel="subsection" <link rel="subsection"
href="/catalog/v2/entries?lang=eng" href="/catalog/v2/entries?lang=eng"
type="application/atom+xml;profile=opds-catalog;kind=acquisition"/> type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
@ -1044,6 +1045,7 @@ TEST_F(LibraryServerTest, catalog_v2_languages)
<entry> <entry>
<title>français</title> <title>français</title>
<dc:language>fra</dc:language> <dc:language>fra</dc:language>
<thr:count>1</thr:count>
<link rel="subsection" <link rel="subsection"
href="/catalog/v2/entries?lang=fra" href="/catalog/v2/entries?lang=fra"
type="application/atom+xml;profile=opds-catalog;kind=acquisition"/> type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
@ -1053,6 +1055,7 @@ TEST_F(LibraryServerTest, catalog_v2_languages)
<entry> <entry>
<title>русский</title> <title>русский</title>
<dc:language>rus</dc:language> <dc:language>rus</dc:language>
<thr:count>1</thr:count>
<link rel="subsection" <link rel="subsection"
href="/catalog/v2/entries?lang=rus" href="/catalog/v2/entries?lang=rus"
type="application/atom+xml;profile=opds-catalog;kind=acquisition"/> type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>