mirror of https://github.com/kiwix/libkiwix.git
Preliminary version of /catalog/v2/languages
This commit is contained in:
parent
64b55dbdc7
commit
5f90f5ee2a
|
@ -71,6 +71,13 @@ class OPDSDumper
|
|||
*/
|
||||
std::string categoriesOPDSFeed(const std::vector<std::string>& categories) const;
|
||||
|
||||
/**
|
||||
* Dump the languages OPDS feed.
|
||||
*
|
||||
* @return The OPDS feed.
|
||||
*/
|
||||
std::string languagesOPDSFeed() const;
|
||||
|
||||
/**
|
||||
* Set the id of the library.
|
||||
*
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "kiwixlib-resources.h"
|
||||
#include <mustache.hpp>
|
||||
#include <unicode/locid.h>
|
||||
|
||||
#include "tools/stringTools.h"
|
||||
#include "tools/otherTools.h"
|
||||
|
@ -83,6 +84,24 @@ BookData getBookData(const Library* library, const std::vector<std::string>& boo
|
|||
return bookData;
|
||||
}
|
||||
|
||||
struct LangInfo {
|
||||
std::string selfName, englishName;
|
||||
};
|
||||
|
||||
std::map<std::string, LangInfo> langMap = {
|
||||
{"eng", { "English", "English"} },
|
||||
{"fra", { "Français", "French"} },
|
||||
{"rus", { "Русский", "Russian"} },
|
||||
};
|
||||
|
||||
std::string getLanguageSelfName(const std::string& lang) {
|
||||
return langMap.at(lang).selfName;
|
||||
};
|
||||
|
||||
std::string getLanguageEnglishName(const std::string& lang) {
|
||||
return langMap.at(lang).englishName;
|
||||
};
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
string OPDSDumper::dumpOPDSFeed(const std::vector<std::string>& bookIds, const std::string& query) const
|
||||
|
@ -146,4 +165,31 @@ std::string OPDSDumper::categoriesOPDSFeed(const std::vector<std::string>& categ
|
|||
);
|
||||
}
|
||||
|
||||
std::string OPDSDumper::languagesOPDSFeed() const
|
||||
{
|
||||
const auto now = gen_date_str();
|
||||
kainjow::mustache::list languageData;
|
||||
for ( const auto& languageCode : library->getBooksLanguages() ) {
|
||||
const auto languageSelfName = getLanguageSelfName(languageCode);
|
||||
const auto languageEnglishName = getLanguageEnglishName(languageCode);
|
||||
languageData.push_back(kainjow::mustache::object{
|
||||
{"lang_code", languageCode},
|
||||
{"lang_self_name", languageSelfName},
|
||||
{"lang_english_name", languageEnglishName},
|
||||
{"updated", now},
|
||||
{"id", gen_uuid(libraryId + "/languages/" + languageCode)}
|
||||
});
|
||||
}
|
||||
|
||||
return render_template(
|
||||
RESOURCE::templates::catalog_v2_languages_xml,
|
||||
kainjow::mustache::object{
|
||||
{"date", now},
|
||||
{"endpoint_root", rootLocation + "/catalog/v2"},
|
||||
{"feed_id", gen_uuid(libraryId + "/languages")},
|
||||
{"languages", languageData }
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -77,6 +77,7 @@ class InternalServer {
|
|||
std::unique_ptr<Response> handle_catalog_v2_root(const RequestContext& request);
|
||||
std::unique_ptr<Response> handle_catalog_v2_entries(const RequestContext& request);
|
||||
std::unique_ptr<Response> handle_catalog_v2_categories(const RequestContext& request);
|
||||
std::unique_ptr<Response> handle_catalog_v2_languages(const RequestContext& request);
|
||||
std::unique_ptr<Response> handle_meta(const RequestContext& request);
|
||||
std::unique_ptr<Response> handle_search(const RequestContext& request);
|
||||
std::unique_ptr<Response> handle_suggest(const RequestContext& request);
|
||||
|
|
|
@ -59,6 +59,8 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2(const RequestContext
|
|||
return handle_catalog_v2_entries(request);
|
||||
} else if (url == "categories") {
|
||||
return handle_catalog_v2_categories(request);
|
||||
} else if (url == "languages") {
|
||||
return handle_catalog_v2_languages(request);
|
||||
} else {
|
||||
return Response::build_404(*this, request, "", "");
|
||||
}
|
||||
|
@ -107,4 +109,16 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_categories(const Req
|
|||
);
|
||||
}
|
||||
|
||||
std::unique_ptr<Response> InternalServer::handle_catalog_v2_languages(const RequestContext& request)
|
||||
{
|
||||
OPDSDumper opdsDumper(mp_library);
|
||||
opdsDumper.setRootLocation(m_root);
|
||||
opdsDumper.setLibraryId(m_library_id);
|
||||
return ContentResponse::build(
|
||||
*this,
|
||||
opdsDumper.languagesOPDSFeed(),
|
||||
"application/atom+xml;profile=opds-catalog;kind=navigation"
|
||||
);
|
||||
}
|
||||
|
||||
} // namespace kiwix
|
||||
|
|
|
@ -48,5 +48,6 @@ templates/catalog_entries.xml
|
|||
templates/catalog_v2_root.xml
|
||||
templates/catalog_v2_entries.xml
|
||||
templates/catalog_v2_categories.xml
|
||||
templates/catalog_v2_languages.xml
|
||||
opensearchdescription.xml
|
||||
catalog_v2_searchdescription.xml
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom"
|
||||
xmlns:opds="https://specs.opds.io/opds-1.2">
|
||||
<id>{{feed_id}}</id>
|
||||
<link rel="self"
|
||||
href="{{endpoint_root}}/languages"
|
||||
type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
|
||||
<link rel="start"
|
||||
href="{{endpoint_root}}/root.xml"
|
||||
type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
|
||||
<title>List of languages</title>
|
||||
<updated>{{date}}</updated>
|
||||
|
||||
{{#languages}}
|
||||
<entry>
|
||||
<title>{{lang_self_name}}</title>
|
||||
<link rel="subsection"
|
||||
href="{{endpoint_root}}/entries?lang={{{lang_code}}}"
|
||||
type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
|
||||
<updated>{{updated}}</updated>
|
||||
<id>{{id}}</id>
|
||||
<content type="text">All entries in {{lang_english_name}}.</content>
|
||||
</entry>
|
||||
{{/languages}}
|
||||
</feed>
|
|
@ -1014,6 +1014,55 @@ TEST_F(LibraryServerTest, catalog_v2_categories)
|
|||
EXPECT_EQ(maskVariableOPDSFeedData(r->body), expected_output);
|
||||
}
|
||||
|
||||
TEST_F(LibraryServerTest, catalog_v2_languages)
|
||||
{
|
||||
const auto r = zfs1_->GET("/catalog/v2/languages");
|
||||
EXPECT_EQ(r->status, 200);
|
||||
const char expected_output[] = R"(<?xml version="1.0" encoding="UTF-8"?>
|
||||
<feed xmlns="http://www.w3.org/2005/Atom"
|
||||
xmlns:opds="https://specs.opds.io/opds-1.2">
|
||||
<id>12345678-90ab-cdef-1234-567890abcdef</id>
|
||||
<link rel="self"
|
||||
href="/catalog/v2/languages"
|
||||
type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
|
||||
<link rel="start"
|
||||
href="/catalog/v2/root.xml"
|
||||
type="application/atom+xml;profile=opds-catalog;kind=navigation"/>
|
||||
<title>List of languages</title>
|
||||
<updated>YYYY-MM-DDThh:mm:ssZ</updated>
|
||||
|
||||
<entry>
|
||||
<title>English</title>
|
||||
<link rel="subsection"
|
||||
href="/catalog/v2/entries?lang=eng"
|
||||
type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
|
||||
<updated>YYYY-MM-DDThh:mm:ssZ</updated>
|
||||
<id>12345678-90ab-cdef-1234-567890abcdef</id>
|
||||
<content type="text">All entries in English.</content>
|
||||
</entry>
|
||||
<entry>
|
||||
<title>Français</title>
|
||||
<link rel="subsection"
|
||||
href="/catalog/v2/entries?lang=fra"
|
||||
type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
|
||||
<updated>YYYY-MM-DDThh:mm:ssZ</updated>
|
||||
<id>12345678-90ab-cdef-1234-567890abcdef</id>
|
||||
<content type="text">All entries in French.</content>
|
||||
</entry>
|
||||
<entry>
|
||||
<title>Русский</title>
|
||||
<link rel="subsection"
|
||||
href="/catalog/v2/entries?lang=rus"
|
||||
type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
|
||||
<updated>YYYY-MM-DDThh:mm:ssZ</updated>
|
||||
<id>12345678-90ab-cdef-1234-567890abcdef</id>
|
||||
<content type="text">All entries in Russian.</content>
|
||||
</entry>
|
||||
</feed>
|
||||
)";
|
||||
EXPECT_EQ(maskVariableOPDSFeedData(r->body), expected_output);
|
||||
}
|
||||
|
||||
#define CATALOG_V2_ENTRIES_PREAMBLE(q) \
|
||||
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" \
|
||||
"<feed xmlns=\"http://www.w3.org/2005/Atom\"\n" \
|
||||
|
|
Loading…
Reference in New Issue