mirror of https://github.com/kiwix/libkiwix.git
Add download-links to tiles in /nojs
The download-link links to /nojs/download/<bookname> for all 4 types of downloads.
This commit is contained in:
parent
dbded6eee2
commit
0f7e11bd86
|
@ -47,14 +47,17 @@ std::string HTMLDumper::dumpPlainHTML() const
|
||||||
const auto langCode = bookObj.getCommaSeparatedLanguages();
|
const auto langCode = bookObj.getCommaSeparatedLanguages();
|
||||||
const auto bookIconUrl = rootLocation + "/catalog/v2/illustration/" + bookId + "/?size=48";
|
const auto bookIconUrl = rootLocation + "/catalog/v2/illustration/" + bookId + "/?size=48";
|
||||||
const auto tags = bookObj.getTags();
|
const auto tags = bookObj.getTags();
|
||||||
|
const auto downloadAvailable = (bookObj.getUrl() != "");
|
||||||
std::string faviconAttr = "style=background-image:url(" + bookIconUrl + ")";
|
std::string faviconAttr = "style=background-image:url(" + bookIconUrl + ")";
|
||||||
|
|
||||||
booksData.push_back(kainjow::mustache::object{
|
booksData.push_back(kainjow::mustache::object{
|
||||||
{"id", contentId},
|
{"id", contentId},
|
||||||
{"title", bookTitle},
|
{"title", bookTitle},
|
||||||
{"description", bookDescription},
|
{"description", bookDescription},
|
||||||
{"langCode", langCode},
|
{"langCode", langCode},
|
||||||
{"faviconAttr", faviconAttr},
|
{"faviconAttr", faviconAttr},
|
||||||
{"tagList", getTagList(tags)}
|
{"tagList", getTagList(tags)},
|
||||||
|
{"downloadAvailable", downloadAvailable}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -759,18 +759,51 @@ std::unique_ptr<Response> InternalServer::handle_viewer_settings(const RequestCo
|
||||||
return ContentResponse::build(*this, RESOURCE::templates::viewer_settings_js, data, "application/javascript; charset=utf-8");
|
return ContentResponse::build(*this, RESOURCE::templates::viewer_settings_js, data, "application/javascript; charset=utf-8");
|
||||||
}
|
}
|
||||||
|
|
||||||
std::unique_ptr<Response> InternalServer::handle_no_js(const RequestContext& request)
|
std::string InternalServer::getNoJSDownloadPageHTML(const std::string& bookId) const
|
||||||
{
|
{
|
||||||
HTMLDumper htmlDumper(mp_library, mp_nameMapper);
|
const auto book = mp_library->getBookById(bookId);
|
||||||
htmlDumper.setRootLocation(m_root);
|
auto bookUrl = kiwix::stripSuffix(book.getUrl(), ".meta4");
|
||||||
htmlDumper.setLibraryId(getLibraryId());
|
|
||||||
return ContentResponse::build(
|
return render_template(
|
||||||
*this,
|
RESOURCE::templates::no_js_download_html,
|
||||||
htmlDumper.dumpPlainHTML(),
|
kainjow::mustache::object{
|
||||||
"text/html; charset=utf-8"
|
{"url", bookUrl},
|
||||||
|
{"bookTitle", book.getTitle()}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<Response> InternalServer::handle_no_js(const RequestContext& request)
|
||||||
|
{
|
||||||
|
const auto url = request.get_url();
|
||||||
|
const auto urlParts = kiwix::split(url, "/", true, false);
|
||||||
|
HTMLDumper htmlDumper(mp_library, mp_nameMapper);
|
||||||
|
htmlDumper.setRootLocation(m_root);
|
||||||
|
htmlDumper.setLibraryId(getLibraryId());
|
||||||
|
std::string content;
|
||||||
|
|
||||||
|
if (urlParts.size() == 1) {
|
||||||
|
content = htmlDumper.dumpPlainHTML();
|
||||||
|
} else if ((urlParts.size() == 3) && (urlParts[1] == "download")) {
|
||||||
|
try {
|
||||||
|
const auto bookId = mp_nameMapper->getIdForName(urlParts[2]);
|
||||||
|
content = getNoJSDownloadPageHTML(bookId);
|
||||||
|
} catch (const std::out_of_range&) {
|
||||||
|
return HTTP404Response(*this, request)
|
||||||
|
+ urlNotFoundMsg;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return HTTP404Response(*this, request)
|
||||||
|
+ urlNotFoundMsg;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return ContentResponse::build(
|
||||||
|
*this,
|
||||||
|
content,
|
||||||
|
"text/html; charset=utf-8"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
|
@ -156,6 +156,8 @@ class InternalServer {
|
||||||
|
|
||||||
std::string getLibraryId() const;
|
std::string getLibraryId() const;
|
||||||
|
|
||||||
|
std::string getNoJSDownloadPageHTML(const std::string& bookId) const;
|
||||||
|
|
||||||
private: // types
|
private: // types
|
||||||
class LockableSuggestionSearcher;
|
class LockableSuggestionSearcher;
|
||||||
typedef ConcurrentCache<SearchInfo, std::shared_ptr<zim::Search>> SearchCache;
|
typedef ConcurrentCache<SearchInfo, std::shared_ptr<zim::Search>> SearchCache;
|
||||||
|
|
|
@ -415,6 +415,17 @@ bool kiwix::startsWith(const std::string& base, const std::string& start)
|
||||||
&& std::equal(start.begin(), start.end(), base.begin());
|
&& std::equal(start.begin(), start.end(), base.begin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string kiwix::stripSuffix(const std::string& str, const std::string& suffix)
|
||||||
|
{
|
||||||
|
if (str.size() > suffix.size()) {
|
||||||
|
const auto subStr = str.substr(str.size() - suffix.size(), str.size());
|
||||||
|
if (subStr == suffix) {
|
||||||
|
return str.substr(0, str.size() - suffix.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::string> kiwix::getTitleVariants(const std::string& title) {
|
std::vector<std::string> kiwix::getTitleVariants(const std::string& title) {
|
||||||
std::vector<std::string> variants;
|
std::vector<std::string> variants;
|
||||||
variants.push_back(title);
|
variants.push_back(title);
|
||||||
|
|
|
@ -93,6 +93,8 @@ std::string extractFromString(const std::string& str);
|
||||||
|
|
||||||
bool startsWith(const std::string& base, const std::string& start);
|
bool startsWith(const std::string& base, const std::string& start);
|
||||||
|
|
||||||
|
std::string stripSuffix(const std::string& str, const std::string& suffix);
|
||||||
|
|
||||||
std::vector<std::string> getTitleVariants(const std::string& title);
|
std::vector<std::string> getTitleVariants(const std::string& title);
|
||||||
} //namespace kiwix
|
} //namespace kiwix
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -38,6 +38,7 @@ templates/catalog_v2_languages.xml
|
||||||
templates/url_of_search_results_css
|
templates/url_of_search_results_css
|
||||||
templates/viewer_settings.js
|
templates/viewer_settings.js
|
||||||
templates/no_js_library_page.html
|
templates/no_js_library_page.html
|
||||||
|
templates/no_js_download.html
|
||||||
opensearchdescription.xml
|
opensearchdescription.xml
|
||||||
ft_opensearchdescription.xml
|
ft_opensearchdescription.xml
|
||||||
catalog_v2_searchdescription.xml
|
catalog_v2_searchdescription.xml
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Download book</title>
|
||||||
|
</head>
|
||||||
|
<style>
|
||||||
|
.downloadLinksTitle {
|
||||||
|
text-align: center;
|
||||||
|
font-size: 32px;
|
||||||
|
margin-bottom: 6px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<div class="downloadLinksTitle">
|
||||||
|
Download links for <b><i>{{bookTitle}}</i></b>
|
||||||
|
</div>
|
||||||
|
<a href="{{url}}" download>
|
||||||
|
<div>Direct</div>
|
||||||
|
</a>
|
||||||
|
<a href="{{url}}.sha256" download>
|
||||||
|
<div>Sha256 hash</div>
|
||||||
|
</a>
|
||||||
|
<a href="{{url}}.magnet" target="_blank">
|
||||||
|
<div>Magnet link</div>
|
||||||
|
</a>
|
||||||
|
<a href="{{url}}.torrent" download>
|
||||||
|
<div>Torrent file</div>
|
||||||
|
</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -44,6 +44,20 @@
|
||||||
.tag__link {
|
.tag__link {
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.book__link__wrapper {
|
||||||
|
grid-column: 1 / 3;
|
||||||
|
grid-row: 1 / 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
.book__link {
|
||||||
|
grid-row: 2 / 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
#book__title>a, .book__download a {
|
||||||
|
text-decoration: none;
|
||||||
|
all: unset;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -51,15 +65,18 @@
|
||||||
<div class="book__list">
|
<div class="book__list">
|
||||||
{{#books}}
|
{{#books}}
|
||||||
<div class="book__wrapper">
|
<div class="book__wrapper">
|
||||||
<a class="book__link" href="{{root}}/content/{{id}}" title="Preview" aria-label="Preview">
|
|
||||||
<div class="book__link__wrapper">
|
<div class="book__link__wrapper">
|
||||||
<div class="book__icon" {{faviconAttr}}></div>
|
<div class="book__icon" {{faviconAttr}}></div>
|
||||||
<div class="book__header">
|
<div class="book__header">
|
||||||
<div id="book__title">{{title}}</div>
|
<div id="book__title"><a href="{{root}}/content/{{id}}">{{title}}</a></div>
|
||||||
|
{{#downloadAvailable}}
|
||||||
|
<div class="book__download"><span><a href="{{root}}/nojs/download/{{id}}">Download</a></span></div>
|
||||||
|
{{/downloadAvailable}}
|
||||||
</div>
|
</div>
|
||||||
|
<a class="book__link" href="{{root}}/content/{{id}}" title="Preview" aria-label="Preview">
|
||||||
<div class="book__description" title="{{description}}">{{description}}</div>
|
<div class="book__description" title="{{description}}">{{description}}</div>
|
||||||
</div>
|
|
||||||
</a>
|
</a>
|
||||||
|
</div>
|
||||||
<div class="book__languageTag" {{languageAttr}}>{{langCode}}</div>
|
<div class="book__languageTag" {{languageAttr}}>{{langCode}}</div>
|
||||||
<div class="book__tags"><div class="book__tags--wrapper">
|
<div class="book__tags"><div class="book__tags--wrapper">
|
||||||
{{#tagList}}
|
{{#tagList}}
|
||||||
|
|
|
@ -163,4 +163,11 @@ TEST(stringTools, urlDecode)
|
||||||
EXPECT_EQ(urlDecode(encodedUriDelimSymbols, false), encodedUriDelimSymbols);
|
EXPECT_EQ(urlDecode(encodedUriDelimSymbols, false), encodedUriDelimSymbols);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TEST(stringTools, stripSuffix)
|
||||||
|
{
|
||||||
|
EXPECT_EQ(stripSuffix("abc123", "123"), "abc");
|
||||||
|
EXPECT_EQ(stripSuffix("abc123", "123456789"), "abc123");
|
||||||
|
EXPECT_EQ(stripSuffix("abc123", "987"), "abc123");
|
||||||
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue