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:
Nikhil Tanwar 2023-02-15 02:43:33 +05:30
parent dbded6eee2
commit 0f7e11bd86
9 changed files with 123 additions and 14 deletions

View File

@ -47,14 +47,17 @@ std::string HTMLDumper::dumpPlainHTML() const
const auto langCode = bookObj.getCommaSeparatedLanguages();
const auto bookIconUrl = rootLocation + "/catalog/v2/illustration/" + bookId + "/?size=48";
const auto tags = bookObj.getTags();
const auto downloadAvailable = (bookObj.getUrl() != "");
std::string faviconAttr = "style=background-image:url(" + bookIconUrl + ")";
booksData.push_back(kainjow::mustache::object{
{"id", contentId},
{"title", bookTitle},
{"description", bookDescription},
{"langCode", langCode},
{"faviconAttr", faviconAttr},
{"tagList", getTagList(tags)}
{"tagList", getTagList(tags)},
{"downloadAvailable", downloadAvailable}
});
}

View File

@ -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");
}
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);
htmlDumper.setRootLocation(m_root);
htmlDumper.setLibraryId(getLibraryId());
return ContentResponse::build(
*this,
htmlDumper.dumpPlainHTML(),
"text/html; charset=utf-8"
const auto book = mp_library->getBookById(bookId);
auto bookUrl = kiwix::stripSuffix(book.getUrl(), ".meta4");
return render_template(
RESOURCE::templates::no_js_download_html,
kainjow::mustache::object{
{"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
{

View File

@ -156,6 +156,8 @@ class InternalServer {
std::string getLibraryId() const;
std::string getNoJSDownloadPageHTML(const std::string& bookId) const;
private: // types
class LockableSuggestionSearcher;
typedef ConcurrentCache<SearchInfo, std::shared_ptr<zim::Search>> SearchCache;

View File

@ -415,6 +415,17 @@ bool kiwix::startsWith(const std::string& base, const std::string& start)
&& 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> variants;
variants.push_back(title);

View File

@ -93,6 +93,8 @@ std::string extractFromString(const std::string& str);
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);
} //namespace kiwix
#endif

View File

@ -38,6 +38,7 @@ templates/catalog_v2_languages.xml
templates/url_of_search_results_css
templates/viewer_settings.js
templates/no_js_library_page.html
templates/no_js_download.html
opensearchdescription.xml
ft_opensearchdescription.xml
catalog_v2_searchdescription.xml

View File

@ -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>

View File

@ -44,6 +44,20 @@
.tag__link {
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>
</head>
<body>
@ -51,15 +65,18 @@
<div class="book__list">
{{#books}}
<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__icon" {{faviconAttr}}></div>
<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>
<a class="book__link" href="{{root}}/content/{{id}}" title="Preview" aria-label="Preview">
<div class="book__description" title="{{description}}">{{description}}</div>
</div>
</a>
</div>
<div class="book__languageTag" {{languageAttr}}>{{langCode}}</div>
<div class="book__tags"><div class="book__tags--wrapper">
{{#tagList}}

View File

@ -163,4 +163,11 @@ TEST(stringTools, urlDecode)
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");
}
};