diff --git a/src/html_dumper.cpp b/src/html_dumper.cpp index 277dc92ec..27be874ab 100644 --- a/src/html_dumper.cpp +++ b/src/html_dumper.cpp @@ -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} }); } diff --git a/src/server/internalServer.cpp b/src/server/internalServer.cpp index a0236f3e6..32aa7752f 100644 --- a/src/server/internalServer.cpp +++ b/src/server/internalServer.cpp @@ -759,18 +759,51 @@ std::unique_ptr InternalServer::handle_viewer_settings(const RequestCo return ContentResponse::build(*this, RESOURCE::templates::viewer_settings_js, data, "application/javascript; charset=utf-8"); } -std::unique_ptr 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 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 { diff --git a/src/server/internalServer.h b/src/server/internalServer.h index a9e0070c8..de84f251e 100644 --- a/src/server/internalServer.h +++ b/src/server/internalServer.h @@ -156,6 +156,8 @@ class InternalServer { std::string getLibraryId() const; + std::string getNoJSDownloadPageHTML(const std::string& bookId) const; + private: // types class LockableSuggestionSearcher; typedef ConcurrentCache> SearchCache; diff --git a/src/tools/stringTools.cpp b/src/tools/stringTools.cpp index 3ca8124aa..7ec66deec 100644 --- a/src/tools/stringTools.cpp +++ b/src/tools/stringTools.cpp @@ -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 kiwix::getTitleVariants(const std::string& title) { std::vector variants; variants.push_back(title); diff --git a/src/tools/stringTools.h b/src/tools/stringTools.h index 1f55a22bc..af0527f29 100644 --- a/src/tools/stringTools.h +++ b/src/tools/stringTools.h @@ -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 getTitleVariants(const std::string& title); } //namespace kiwix #endif diff --git a/static/resources_list.txt b/static/resources_list.txt index 516c8bfc6..71ebe6760 100644 --- a/static/resources_list.txt +++ b/static/resources_list.txt @@ -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 diff --git a/static/templates/no_js_download.html b/static/templates/no_js_download.html new file mode 100644 index 000000000..d1ba6f249 --- /dev/null +++ b/static/templates/no_js_download.html @@ -0,0 +1,33 @@ + + + + + + + Download book + + + + + Download links for {{bookTitle}} + + + Direct + + + Sha256 hash + + + Magnet link + + + Torrent file + + + \ No newline at end of file diff --git a/static/templates/no_js_library_page.html b/static/templates/no_js_library_page.html index 3494bd74d..21671cc83 100644 --- a/static/templates/no_js_library_page.html +++ b/static/templates/no_js_library_page.html @@ -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; + } @@ -51,15 +65,18 @@ {{#books}} - - {{title}} + {{title}} + {{#downloadAvailable}} + Download + {{/downloadAvailable}} - {{description}} - - + + {{description}} + + {{langCode}} {{#tagList}} diff --git a/test/stringTools.cpp b/test/stringTools.cpp index 27cc712b8..d866cda81 100644 --- a/test/stringTools.cpp +++ b/test/stringTools.cpp @@ -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"); +} + };