mirror of https://github.com/kiwix/libkiwix.git
Merge pull request #846 from kiwix/frontend_i18n
This commit is contained in:
commit
936707f73b
|
@ -97,14 +97,19 @@ inline std::string normalizeRootUrl(std::string rootUrl)
|
|||
std::string
|
||||
fullURL2LocalURL(const std::string& fullUrl, const std::string& rootLocation)
|
||||
{
|
||||
assert(rootLocation.size() > 0 && rootLocation.back() == '/');
|
||||
if ( kiwix::startsWith(fullUrl, rootLocation) ) {
|
||||
return fullUrl.substr(rootLocation.size() - 1);
|
||||
return fullUrl.substr(rootLocation.size());
|
||||
} else {
|
||||
return "";
|
||||
return "INVALID URL";
|
||||
}
|
||||
}
|
||||
|
||||
std::string getSearchComponent(const RequestContext& request)
|
||||
{
|
||||
const std::string query = request.get_query();
|
||||
return query.empty() ? query : "?" + query;
|
||||
}
|
||||
|
||||
Filter get_search_filter(const RequestContext& request, const std::string& prefix="")
|
||||
{
|
||||
auto filter = kiwix::Filter().valid(true).local(true);
|
||||
|
@ -415,7 +420,7 @@ InternalServer::InternalServer(Library* library,
|
|||
m_addr(addr),
|
||||
m_port(port),
|
||||
m_root(normalizeRootUrl(root)),
|
||||
m_rootPrefixOfDecodedURL(m_root + "/"),
|
||||
m_rootPrefixOfDecodedURL(m_root),
|
||||
m_nbThreads(nbThreads),
|
||||
m_multizimSearchLimit(multizimSearchLimit),
|
||||
m_verbose(verbose),
|
||||
|
@ -585,6 +590,13 @@ std::unique_ptr<Response> InternalServer::handle_request(const RequestContext& r
|
|||
+ urlNotFoundMsg;
|
||||
}
|
||||
|
||||
if ( request.get_url() == "" ) {
|
||||
// Redirect /ROOT_LOCATION to /ROOT_LOCATION/ (note the added slash)
|
||||
// so that relative URLs are resolved correctly
|
||||
const std::string query = getSearchComponent(request);
|
||||
return Response::build_redirect(*this, m_root + "/" + query);
|
||||
}
|
||||
|
||||
const ETag etag = get_matching_if_none_match_etag(request, getLibraryId());
|
||||
if ( etag )
|
||||
return Response::build_304(*this, etag);
|
||||
|
@ -623,11 +635,9 @@ std::unique_ptr<Response> InternalServer::handle_request(const RequestContext& r
|
|||
if (isEndpointUrl(url, "catch"))
|
||||
return handle_catch(request);
|
||||
|
||||
std::string contentUrl = m_root + "/content" + urlEncode(url);
|
||||
const std::string query = request.get_query();
|
||||
if ( ! query.empty() )
|
||||
contentUrl += "?" + query;
|
||||
return Response::build_redirect(*this, contentUrl);
|
||||
const std::string contentUrl = m_root + "/content" + urlEncode(url);
|
||||
const std::string query = getSearchComponent(request);
|
||||
return Response::build_redirect(*this, contentUrl + query);
|
||||
} catch (std::exception& e) {
|
||||
fprintf(stderr, "===== Unhandled error : %s\n", e.what());
|
||||
return HTTP500Response(*this, request)
|
||||
|
|
|
@ -181,7 +181,7 @@ std::string RequestContext::get_root_path() const {
|
|||
}
|
||||
|
||||
bool RequestContext::is_valid_url() const {
|
||||
return !url.empty();
|
||||
return url.empty() || url[0] == '/';
|
||||
}
|
||||
|
||||
ByteRange RequestContext::get_range() const {
|
||||
|
|
|
@ -97,6 +97,62 @@ function setUserLanguage(lang, callback) {
|
|||
Translations.whenReady(callback);
|
||||
}
|
||||
|
||||
function createModalUILanguageSelector() {
|
||||
document.body.insertAdjacentHTML('beforeend',
|
||||
`<div id="uiLanguageSelector" class="modal-wrapper">
|
||||
<div class="modal">
|
||||
<div class="modal-heading">
|
||||
<div class="modal-title">
|
||||
<div>
|
||||
Select UI language
|
||||
</div>
|
||||
</div>
|
||||
<div onclick="window.modalUILanguageSelector.close()" class="modal-close-button">
|
||||
<div>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 14 14" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M13.7071 1.70711C14.0976 1.31658 14.0976
|
||||
0.683417 13.7071 0.292893C13.3166 -0.0976311 12.6834 -0.0976311 12.2929 0.292893L7 5.58579L1.70711
|
||||
0.292893C1.31658 -0.0976311 0.683417 -0.0976311 0.292893 0.292893C-0.0976311 0.683417
|
||||
-0.0976311 1.31658 0.292893 1.70711L5.58579 7L0.292893 12.2929C-0.0976311 12.6834
|
||||
-0.0976311 13.3166 0.292893 13.7071C0.683417 14.0976 1.31658 14.0976 1.70711 13.7071L7
|
||||
8.41421L12.2929 13.7071C12.6834 14.0976 13.3166 14.0976 13.7071 13.7071C14.0976 13.3166
|
||||
14.0976 12.6834 13.7071 12.2929L8.41421 7L13.7071 1.70711Z" fill="black" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="modal-content">
|
||||
<select id="ui_language"></select>
|
||||
</div>
|
||||
</div>
|
||||
</div>`);
|
||||
|
||||
window.modalUILanguageSelector = {
|
||||
show: () => {
|
||||
document.getElementById('uiLanguageSelector').style.display = 'flex';
|
||||
},
|
||||
|
||||
close: () => {
|
||||
document.getElementById('uiLanguageSelector').style.display = 'none';
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function initUILanguageSelector(activeLanguage, languageChangeCallback) {
|
||||
if ( document.getElementById("ui_language") == null ) {
|
||||
createModalUILanguageSelector();
|
||||
}
|
||||
const languageSelector = document.getElementById("ui_language");
|
||||
for (const lang of uiLanguages ) {
|
||||
const lang_name = Object.getOwnPropertyNames(lang)[0];
|
||||
const lang_code = lang[lang_name];
|
||||
const is_selected = lang_code == activeLanguage;
|
||||
languageSelector.appendChild(new Option(lang_name, lang_code, is_selected, is_selected));
|
||||
}
|
||||
languageSelector.onchange = languageChangeCallback;
|
||||
}
|
||||
|
||||
window.$t = $t;
|
||||
window.getUserLanguage = getUserLanguage;
|
||||
window.setUserLanguage = setUserLanguage;
|
||||
window.initUILanguageSelector = initUILanguageSelector;
|
||||
|
|
|
@ -28,4 +28,22 @@
|
|||
, "random-page-button-text": "Go to a randomly selected page"
|
||||
, "searchbox-tooltip": "Search '{{BOOK_TITLE}}'"
|
||||
, "confusion-of-tongues": "Two or more books in different languages would participate in search, which may lead to confusing results."
|
||||
, "welcome-page-overzealous-filter": "No result. Would you like to <a href=\"?lang=\">reset filter</a>?"
|
||||
, "powered-by-kiwix-html": "Powered by <a href=\"https://kiwix.org\">Kiwix</a>"
|
||||
, "search": "Search"
|
||||
, "book-filtering-all-categories": "All categories"
|
||||
, "book-filtering-all-languages": "All languages"
|
||||
, "count-of-matching-books": "{{COUNT}} book(s)"
|
||||
, "download": "Download"
|
||||
, "direct-download-link-text": "Direct"
|
||||
, "direct-download-alt-text": "direct download"
|
||||
, "hash-download-link-text": "Sha256 hash"
|
||||
, "hash-download-alt-text": "download hash"
|
||||
, "magnet-link-text": "Magnet link"
|
||||
, "magnet-alt-text": "download magnet"
|
||||
, "torrent-download-link-text": "Torrent file"
|
||||
, "torrent-download-alt-text": "download torrent"
|
||||
, "library-opds-feed": "Library OPDS Feed"
|
||||
, "filter-by-tag": "Filter by tag \"{{TAG}}\""
|
||||
, "stop-filtering-by-tag": "Stop filtering by tag \"{{TAG}}\""
|
||||
}
|
||||
|
|
|
@ -29,5 +29,23 @@
|
|||
"library-button-text": "Tooltip of the button leading to the welcome page",
|
||||
"home-button-text": "Tooltip of the button leading to the main page of a book",
|
||||
"random-page-button-text": "Tooltip of the button opening a randomly selected page",
|
||||
"searchbox-tooltip": "Tooltip displayed for the search box"
|
||||
"searchbox-tooltip": "Tooltip displayed for the search box in the viewer"
|
||||
, "welcome-page-overzealous-filter": "Text shown when book filtering on the welcome page produces zero results"
|
||||
, "powered-by-kiwix-html": "Link to Kiwix website"
|
||||
, "search": "A general search action (text displayed on search buttons or as aplaceholder in searchboxes)"
|
||||
, "book-filtering-all-categories": "Choosing this filter will disable filtering of books by category"
|
||||
, "book-filtering-all-languages": "Choosing this filter will disable filtering of books by language"
|
||||
, "count-of-matching-books": "Reporting the count of books matching the filter"
|
||||
, "download": "A general download action"
|
||||
, "direct-download-link-text": "Link text for a direct download"
|
||||
, "direct-download-alt-text": "Hint for a direct download icon"
|
||||
, "hash-download-link-text": "Link text for downloading the hash"
|
||||
, "hash-download-alt-text": "Hint for the icon of hash download"
|
||||
, "magnet-link-text": "Link text for a magnet link"
|
||||
, "magnet-alt-text": "Hint for the icon of a magnet link"
|
||||
, "torrent-download-link-text": "Link text for downloading the torrent file"
|
||||
, "torrent-download-alt-text": "Hint for the icon of torrent download"
|
||||
, "library-opds-feed": "Hint for the library OPDS feed link"
|
||||
, "filter-by-tag": "Hint for a link that would load results filtered by a single tag"
|
||||
, "stop-filtering-by-tag": "Tooltip for the button that cancels filtering by tag"
|
||||
}
|
||||
|
|
|
@ -17,4 +17,22 @@
|
|||
, "home-button-text": "[I18N TESTING] Jump to the main page of '{{BOOK_TITLE}}'"
|
||||
, "random-page-button-text": "[I18N TESTING] I am tired of determinism"
|
||||
, "searchbox-tooltip": "[I18N TESTING] Let's search in '{{BOOK_TITLE}}'"
|
||||
, "welcome-page-overzealous-filter": "[I18N TESTING] Nothing found. <a href=\"?lang=\">Reset filter</a>"
|
||||
, "powered-by-kiwix-html": "[I18N TESTING] Powered by <a href=\"https://kiwix.org\">Kiwix</a> (nominal power: 1.23 kW)"
|
||||
, "search": "[I18N Search TESTING]"
|
||||
, "book-filtering-all-categories": "All [I18N TESTING] categories"
|
||||
, "book-filtering-all-languages": "All [I18N TESTING] languages"
|
||||
, "count-of-matching-books": "[I18N TESTING] Number of matching books: {{COUNT}}"
|
||||
, "download": "[I18N Download TESTING]"
|
||||
, "direct-download-link-text": "[I18N TESTING] HTTP(S)"
|
||||
, "direct-download-alt-text": "[I18N TESTING] download directly"
|
||||
, "hash-download-link-text": "Sha256 [I18N TESTING] hash"
|
||||
, "hash-download-alt-text": "download [I18N TESTING] hash"
|
||||
, "magnet-link-text": "Magnet [I18N TESTING] link"
|
||||
, "magnet-alt-text": "download [I18N TESTING] magnet"
|
||||
, "torrent-download-link-text": "Torrent [I18N TESTING] file"
|
||||
, "torrent-download-alt-text": "download [I18N TESTING] torrent"
|
||||
, "library-opds-feed": "Library [I18N] OPDS [TESTING] Feed"
|
||||
, "filter-by-tag": "Filter [I18N] by [TESTING] tag \"{{TAG}}\""
|
||||
, "stop-filtering-by-tag": "[I18N] Stop filtering [TESTING] by tag \"{{TAG}}\""
|
||||
}
|
||||
|
|
|
@ -157,6 +157,28 @@ body {
|
|||
font-weight: bolder;
|
||||
}
|
||||
|
||||
#uiLanguageSelector {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#uiLanguageSelector .modal {
|
||||
height: 140px;
|
||||
}
|
||||
|
||||
#uiLanguageSelector .modal-heading {
|
||||
height: 40%;
|
||||
}
|
||||
|
||||
#uiLanguageSelector .modal-content #ui_language {
|
||||
font-size: 1.6rem;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#uiLanguageSelectorButton {
|
||||
margin: 16px 12px 0 0;
|
||||
float: right;
|
||||
}
|
||||
|
||||
.book__list {
|
||||
position: relative;
|
||||
margin: 0 auto;
|
||||
|
@ -472,11 +494,11 @@ body {
|
|||
.kiwixHomeBody {
|
||||
min-height: calc(100vh - 287px);
|
||||
}
|
||||
|
||||
|
||||
.kiwixSearch {
|
||||
margin-top: 11px;
|
||||
}
|
||||
|
||||
|
||||
.kiwixButton {
|
||||
margin: 15px 0;
|
||||
width: 229px;
|
||||
|
@ -489,8 +511,4 @@ body {
|
|||
.kiwixNav__filters {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.feedLogo {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
let noResultInjected = false;
|
||||
let filters = getCookie(filterCookieName);
|
||||
let params = new URLSearchParams(window.location.search || filters || '');
|
||||
params.delete('userlang');
|
||||
let timer;
|
||||
let languages = {};
|
||||
|
||||
|
@ -31,6 +32,14 @@
|
|||
document.querySelector('#feedLink').href = feedLink;
|
||||
}
|
||||
|
||||
function changeUILanguage() {
|
||||
window.modalUILanguageSelector.close();
|
||||
const s = document.getElementById("ui_language");
|
||||
const lang = s.options[s.selectedIndex].value;
|
||||
setPermanentGlobalCookie('userlang', lang);
|
||||
window.location.reload();
|
||||
}
|
||||
|
||||
function queryUrlBuilder() {
|
||||
let url = `${root}/catalog/search?`;
|
||||
url += Object.keys(incrementalLoadingParams).map(key => `${key}=${incrementalLoadingParams[key]}`).join("&");
|
||||
|
@ -38,10 +47,14 @@
|
|||
return (url);
|
||||
}
|
||||
|
||||
function setCookie(cookieName, cookieValue) {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + oneDayDelta);
|
||||
document.cookie = `${cookieName}=${cookieValue};expires=${date.toUTCString()};sameSite=Strict`;
|
||||
function setCookie(cookieName, cookieValue, ttl) {
|
||||
let exp = "";
|
||||
if ( ttl ) {
|
||||
const date = new Date();
|
||||
date.setTime(date.getTime() + ttl);
|
||||
exp = `expires=${date.toUTCString()};`;
|
||||
}
|
||||
document.cookie = `${cookieName}=${cookieValue};${exp}sameSite=Strict`;
|
||||
}
|
||||
|
||||
function getCookie(cookieName) {
|
||||
|
@ -93,7 +106,7 @@
|
|||
function generateTagLink(tagValue) {
|
||||
tagValue = tagValue.toLowerCase();
|
||||
const humanFriendlyTagValue = humanFriendlyTitle(tagValue);
|
||||
const tagMessage = `Filter by tag "${humanFriendlyTagValue}"`;
|
||||
const tagMessage = $t("filter-by-tag", {TAG: humanFriendlyTagValue});
|
||||
return `<span class='tag__link' aria-label='${tagMessage}' title='${tagMessage}' data-tag=${tagValue}>${humanFriendlyTagValue}</span>`
|
||||
}
|
||||
|
||||
|
@ -143,7 +156,7 @@
|
|||
<div class="book__icon" ${faviconAttr}></div>
|
||||
<div class="book__header">
|
||||
<div id="book__title">${title}</div>
|
||||
${downloadLink ? `<div class="book__download"><span data-link="${downloadLink}">Download ${humanFriendlyZimSize ? ` - ${humanFriendlyZimSize}</span></div>`: ''}` : ''}
|
||||
${downloadLink ? `<div class="book__download"><span data-link="${downloadLink}">${$t("download")} ${humanFriendlyZimSize ? ` - ${humanFriendlyZimSize}</span></div>`: ''}` : ''}
|
||||
</div>
|
||||
<div class="book__description" title="${description}">${description}</div>
|
||||
</div>
|
||||
|
@ -209,27 +222,27 @@
|
|||
<div class="modal-content">
|
||||
<div class="modal-regular-download">
|
||||
<a href="${downloadLink}" download>
|
||||
<img src="../skin/download.png?KIWIXCACHEID" alt="direct download" />
|
||||
<div>Direct</div>
|
||||
<img src="${root}/skin/download.png?KIWIXCACHEID" alt="${$t("direct-download-alt-text")}" />
|
||||
<div>${$t("direct-download-link-text")}</div>
|
||||
</a>
|
||||
</div>
|
||||
<div class="modal-regular-download">
|
||||
<a href="${downloadLink}.sha256" download>
|
||||
<img src="../skin/hash.png?KIWIXCACHEID" alt="download hash" />
|
||||
<div>Sha256 hash</div>
|
||||
<img src="${root}/skin/hash.png?KIWIXCACHEID" alt="${$t("hash-download-alt-text")}" />
|
||||
<div>${$t("hash-download-link-text")}</div>
|
||||
</a>
|
||||
</div>
|
||||
${magnetLink ?
|
||||
`<div class="modal-regular-download">
|
||||
<a href="${magnetLink}" target="_blank">
|
||||
<img src="../skin/magnet.png?KIWIXCACHEID" alt="download magnet" />
|
||||
<div>Magnet link</div>
|
||||
<img src="${root}/skin/magnet.png?KIWIXCACHEID" alt="${$t("magnet-alt-text")}" />
|
||||
<div>${$t("magnet-link-text")}</div>
|
||||
</a>
|
||||
</div>` : ``}
|
||||
<div class="modal-regular-download">
|
||||
<a href="${downloadLink}.torrent" download>
|
||||
<img src="../skin/bittorrent.png?KIWIXCACHEID" alt="download torrent" />
|
||||
<div>Torrent file</div>
|
||||
<img src="${root}/skin/bittorrent.png?KIWIXCACHEID" alt="${$t("torrent-download-alt-text")}" />
|
||||
<div>${$t("torrent-download-link-text")}</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -262,16 +275,10 @@
|
|||
} else {
|
||||
toggleFooter();
|
||||
}
|
||||
const kiwixResultText = document.querySelector('.kiwixHomeBody__results')
|
||||
if (results) {
|
||||
let resultText = `${results} books`;
|
||||
if (results === 1) {
|
||||
resultText = `${results} book`;
|
||||
}
|
||||
kiwixResultText.innerHTML = resultText;
|
||||
} else {
|
||||
kiwixResultText.innerHTML = ``;
|
||||
}
|
||||
const text = results
|
||||
? $t("count-of-matching-books", {COUNT: results})
|
||||
: '';
|
||||
document.querySelector('.kiwixHomeBody__results').innerHTML = text;
|
||||
loader.style.display = 'none';
|
||||
return books;
|
||||
});
|
||||
|
@ -298,7 +305,7 @@
|
|||
const kiwixHomeBody = document.querySelector('.kiwixHomeBody');
|
||||
const divTag = document.createElement('div');
|
||||
divTag.setAttribute('class', 'noResults');
|
||||
divTag.innerHTML = `No result. Would you like to <a href="?lang=">reset filter</a>?`;
|
||||
divTag.innerHTML = $t("welcome-page-overzealous-filter");
|
||||
kiwixHomeBody.append(divTag);
|
||||
kiwixHomeBody.setAttribute('style', 'display: flex; justify-content: center; align-items: center');
|
||||
loader.setAttribute('style', 'position: absolute; top: 50%');
|
||||
|
@ -373,7 +380,7 @@
|
|||
if (filterType) {
|
||||
params.set(filterType, filterValue);
|
||||
window.history.pushState({}, null, `?${params.toString()}`);
|
||||
setCookie(filterCookieName, params.toString());
|
||||
setCookie(filterCookieName, params.toString(), oneDayDelta);
|
||||
}
|
||||
updateFilterColors();
|
||||
updateFeedLink();
|
||||
|
@ -411,7 +418,7 @@
|
|||
tagElement.style.display = 'inline-block';
|
||||
const humanFriendlyTagValue = humanFriendlyTitle(tagValue);
|
||||
tagElement.innerHTML = `${humanFriendlyTagValue}`;
|
||||
const tagMessage = `Stop filtering by tag "${humanFriendlyTagValue}"`;
|
||||
const tagMessage = $t("stop-filtering-by-tag", {TAG: humanFriendlyTagValue});
|
||||
tagElement.setAttribute('aria-label', tagMessage);
|
||||
tagElement.setAttribute('title', tagMessage);
|
||||
if (resetFilter)
|
||||
|
@ -462,7 +469,22 @@
|
|||
}
|
||||
});
|
||||
|
||||
window.onload = async () => {
|
||||
function updateUIText() {
|
||||
footer.innerHTML = $t("powered-by-kiwix-html");
|
||||
const searchText = $t("search");
|
||||
document.getElementById('searchFilter').placeholder = searchText;
|
||||
document.getElementById('searchButton').value = searchText;
|
||||
document.getElementById('categoryFilter').children[0].innerHTML = $t("book-filtering-all-categories");
|
||||
document.getElementById('languageFilter').children[0].innerHTML = $t("book-filtering-all-languages");
|
||||
const feedLogoElem = document.getElementById('feedLogo');
|
||||
const libraryOpdsFeedHint = $t("library-opds-feed");
|
||||
for (const attr of ["alt", "aria-label", "title"] ) {
|
||||
feedLogoElem.setAttribute(attr, libraryOpdsFeedHint);
|
||||
}
|
||||
}
|
||||
|
||||
async function onload() {
|
||||
initUILanguageSelector(getUserLanguage(), changeUILanguage);
|
||||
iso = new Isotope( '.book__list', {
|
||||
itemSelector: '.book',
|
||||
getSortData:{
|
||||
|
@ -478,6 +500,7 @@
|
|||
}
|
||||
});
|
||||
footer = document.getElementById('kiwixfooter');
|
||||
updateUIText();
|
||||
fadeOutDiv = document.getElementById('fadeOut');
|
||||
loader = document.querySelector('.loader');
|
||||
await loadAndDisplayOptions('#languageFilter', `${root}/catalog/v2/languages`, 'language');
|
||||
|
@ -507,7 +530,14 @@
|
|||
}
|
||||
}
|
||||
updateFeedLink();
|
||||
setCookie(filterCookieName, params.toString());
|
||||
setCookie(filterCookieName, params.toString(), oneDayDelta);
|
||||
};
|
||||
|
||||
// required by i18n.js:setUserLanguage()
|
||||
window.setPermanentGlobalCookie = function(name, value) {
|
||||
document.cookie = `${name}=${value};path=${root};max-age=31536000`;
|
||||
}
|
||||
|
||||
window.onload = () => { setUserLanguage(getUserLanguage(), onload); }
|
||||
})();
|
||||
|
||||
|
|
|
@ -44,10 +44,6 @@
|
|||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.kiwix #ui_language {
|
||||
float: left;
|
||||
}
|
||||
|
||||
#kiwix_button_show_toggle {
|
||||
display: none;
|
||||
}
|
||||
|
@ -84,7 +80,6 @@ label[for="kiwix_button_show_toggle"],
|
|||
float: right;
|
||||
}
|
||||
|
||||
.kiwix #ui_language,
|
||||
.kiwix #kiwixtoolbar button,
|
||||
.kiwix #kiwixtoolbar input[type="submit"] {
|
||||
box-sizing: border-box !important;
|
||||
|
@ -134,6 +129,79 @@ a.suggest, a.suggest:visited, a.suggest:hover, a.suggest:active {
|
|||
column-count: 1 !important;
|
||||
}
|
||||
|
||||
.modal-wrapper {
|
||||
position: fixed;
|
||||
z-index: 100;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
align-content: center;
|
||||
background-color: rgba(0, 0, 0, 30%);
|
||||
}
|
||||
|
||||
.modal {
|
||||
color: #444343;
|
||||
height: 280px;
|
||||
width: 250px;
|
||||
margin: 15px;
|
||||
background-color: #f7f7f7;
|
||||
border: 1px solid #ececec;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.modal-heading {
|
||||
background-color: #f0f0f0;
|
||||
height: 20%;
|
||||
width: 100%;
|
||||
border-bottom: 1px solid #ececec;
|
||||
display: grid;
|
||||
grid-template-columns: 3fr 1fr;
|
||||
}
|
||||
|
||||
.modal-title {
|
||||
display: flex;
|
||||
font-size: 15px;
|
||||
align-items: center;
|
||||
padding-left: 20px;
|
||||
font-family: poppins;
|
||||
}
|
||||
|
||||
.modal-close-button {
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.modal-content {
|
||||
padding: 20px;
|
||||
}
|
||||
|
||||
#uiLanguageSelector {
|
||||
display: none;
|
||||
}
|
||||
|
||||
#uiLanguageSelector .modal {
|
||||
height: 140px;
|
||||
}
|
||||
|
||||
#uiLanguageSelector .modal-heading {
|
||||
height: 40%;
|
||||
}
|
||||
|
||||
#uiLanguageSelector .modal-content #ui_language {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
#uiLanguageSelectorButton {
|
||||
margin: 0px 12px 6px 12px;
|
||||
float: right;
|
||||
}
|
||||
|
||||
@media(min-width:420px) {
|
||||
.kiwix_button_cont {
|
||||
display: inline-block !important;
|
||||
|
|
|
@ -416,16 +416,6 @@ function makeURL(search, hash) {
|
|||
return url;
|
||||
}
|
||||
|
||||
function initUILanguageSelector() {
|
||||
const languageSelector = document.getElementById("ui_language");
|
||||
for (const lang of uiLanguages ) {
|
||||
const lang_name = Object.getOwnPropertyNames(lang)[0];
|
||||
const lang_code = lang[lang_name];
|
||||
const is_selected = lang_code == viewerState.uiLanguage;
|
||||
languageSelector.appendChild(new Option(lang_name, lang_code, is_selected, is_selected));
|
||||
}
|
||||
}
|
||||
|
||||
function updateUILanguageSelector(userLang) {
|
||||
console.log(`updateUILanguageSelector(${userLang})`);
|
||||
const languageSelector = document.getElementById("ui_language");
|
||||
|
@ -446,6 +436,7 @@ function handle_history_state_change(event) {
|
|||
}
|
||||
|
||||
function changeUILanguage() {
|
||||
window.modalUILanguageSelector.close();
|
||||
const s = document.getElementById("ui_language");
|
||||
const lang = s.options[s.selectedIndex].value;
|
||||
viewerState.uiLanguage = lang;
|
||||
|
@ -481,7 +472,7 @@ function setupViewer() {
|
|||
document.getElementById("kiwix_serve_taskbar_library_button").remove();
|
||||
}
|
||||
|
||||
initUILanguageSelector();
|
||||
initUILanguageSelector(viewerState.uiLanguage, changeUILanguage);
|
||||
setupSuggestions();
|
||||
|
||||
// cybook hack
|
||||
|
|
|
@ -10,11 +10,11 @@
|
|||
href="{{root}}/skin/index.css?KIWIXCACHEID"
|
||||
rel="Stylesheet"
|
||||
/>
|
||||
<link
|
||||
rel="alternate"
|
||||
type="application/atom+xml"
|
||||
<link
|
||||
rel="alternate"
|
||||
type="application/atom+xml"
|
||||
title="Library OPDS Feed"
|
||||
id="headFeedLink"
|
||||
id="headFeedLink"
|
||||
href="{{root}}/catalog/v2/entries"
|
||||
/>
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="{{root}}/skin/favicon/apple-touch-icon.png?KIWIXCACHEID">
|
||||
|
@ -37,13 +37,31 @@
|
|||
src: url("{{root}}/skin/fonts/Roboto.ttf?KIWIXCACHEID") format("truetype");
|
||||
}
|
||||
</style>
|
||||
<script type="module" src="{{root}}/skin/i18n.js?KIWIXCACHEID" defer></script>
|
||||
<script type="text/javascript" src="{{root}}/skin/languages.js?KIWIXCACHEID" defer></script>
|
||||
<script src="{{root}}/skin/isotope.pkgd.min.js?KIWIXCACHEID" defer></script>
|
||||
<script src="{{root}}/skin/iso6391To3.js?KIWIXCACHEID"></script>
|
||||
<script type="text/javascript" src="{{root}}/skin/index.js?KIWIXCACHEID" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
<a href="{{root}}/catalog/v2/entries" id="feedLink">
|
||||
<img src="{{root}}/skin/feed.png?KIWIXCACHEID" class="feedLogo" alt="Library OPDS Feed" aria-label="Library OPDS Feed" title="Library OPDS Feed">
|
||||
<img src="{{root}}/skin/feed.png?KIWIXCACHEID"
|
||||
class="feedLogo"
|
||||
id="feedLogo"
|
||||
alt="Library OPDS Feed"
|
||||
aria-label="Library OPDS Feed"
|
||||
title="Library OPDS Feed">
|
||||
</a>
|
||||
<a onclick="window.modalUILanguageSelector.show()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
id="uiLanguageSelectorButton"
|
||||
width="30"
|
||||
height="30"
|
||||
viewBox="0 0 20 20">
|
||||
<g fill="#36c">
|
||||
<path d="M20 18h-1.44a.61.61 0 0 1-.4-.12.81.81 0 0 1-.23-.31L17 15h-5l-1 2.54a.77.77 0 0 1-.22.3.59.59 0 0 1-.4.14H9l4.55-11.47h1.89zm-3.53-4.31L14.89 9.5a11.62 11.62 0 0 1-.39-1.24q-.09.37-.19.69l-.19.56-1.58 4.19zm-6.3-1.58a13.43 13.43 0 0 1-2.91-1.41 11.46 11.46 0 0 0 2.81-5.37H12V4H7.31a4 4 0 0 0-.2-.56C6.87 2.79 6.6 2 6.6 2l-1.47.5s.4.89.6 1.5H0v1.33h2.15A11.23 11.23 0 0 0 5 10.7a17.19 17.19 0 0 1-5 2.1q.56.82.87 1.38a23.28 23.28 0 0 0 5.22-2.51 15.64 15.64 0 0 0 3.56 1.77zM3.63 5.33h4.91a8.11 8.11 0 0 1-2.45 4.45 9.11 9.11 0 0 1-2.46-4.45z"/>
|
||||
</g>
|
||||
</svg>
|
||||
</a>
|
||||
<div class='kiwixNav'>
|
||||
<div class="kiwixNav__filters">
|
||||
|
@ -61,7 +79,7 @@
|
|||
<form id='kiwixSearchForm' class='kiwixNav__SearchForm'>
|
||||
<input type="text" name="q" placeholder="Search" id="searchFilter" class='kiwixSearch filter'>
|
||||
<span class="kiwixButton tagFilterLabel"></span>
|
||||
<input type="submit" class="kiwixButton kiwixButtonHover" value="Search"/>
|
||||
<input type="submit" class="kiwixButton kiwixButtonHover" id="searchButton" value="Search"/>
|
||||
</form>
|
||||
</div>
|
||||
<div class="kiwixHomeBody">
|
||||
|
@ -76,7 +94,11 @@
|
|||
<script>
|
||||
function closeModal() {
|
||||
for(modal of document.getElementsByClassName('modal-wrapper')) {
|
||||
modal.remove();
|
||||
if ( modal.id == "uiLanguageSelector" ) {
|
||||
window.modalUILanguageSelector.close();
|
||||
} else {
|
||||
modal.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -29,9 +29,17 @@
|
|||
<body style="margin:0" onload="setupViewer()">
|
||||
<div class="kiwix" style="display:none" id="kiwixtoolbarwrapper">
|
||||
<div id="kiwixtoolbar" class="ui-widget-header">
|
||||
<select id="ui_language" class="kiwix" onchange="changeUILanguage()">
|
||||
</select>
|
||||
<div class="kiwix_centered">
|
||||
<a id="uiLanguageSelectorButton" onclick="window.modalUILanguageSelector.show()">
|
||||
<svg xmlns="http://www.w3.org/2000/svg"
|
||||
width="30"
|
||||
height="30"
|
||||
viewBox="0 0 20 20">
|
||||
<g fill="#36c">
|
||||
<path d="M20 18h-1.44a.61.61 0 0 1-.4-.12.81.81 0 0 1-.23-.31L17 15h-5l-1 2.54a.77.77 0 0 1-.22.3.59.59 0 0 1-.4.14H9l4.55-11.47h1.89zm-3.53-4.31L14.89 9.5a11.62 11.62 0 0 1-.39-1.24q-.09.37-.19.69l-.19.56-1.58 4.19zm-6.3-1.58a13.43 13.43 0 0 1-2.91-1.41 11.46 11.46 0 0 0 2.81-5.37H12V4H7.31a4 4 0 0 0-.2-.56C6.87 2.79 6.6 2 6.6 2l-1.47.5s.4.89.6 1.5H0v1.33h2.15A11.23 11.23 0 0 0 5 10.7a17.19 17.19 0 0 1-5 2.1q.56.82.87 1.38a23.28 23.28 0 0 0 5.22-2.51 15.64 15.64 0 0 0 3.56 1.77zM3.63 5.33h4.91a8.11 8.11 0 0 1-2.45 4.45 9.11 9.11 0 0 1-2.46-4.45z"/>
|
||||
</g>
|
||||
</svg>
|
||||
</a>
|
||||
<div class="kiwix_searchform">
|
||||
<form class="kiwixsearch" method="GET" action="javascript:performSearch()" id="kiwixsearchform">
|
||||
<label for="kiwixsearchbox">🔍</label>
|
||||
|
|
|
@ -59,11 +59,11 @@ const ResourceCollection resources200Compressible{
|
|||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/css/autoComplete.css" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/css/autoComplete.css?cacheid=08951e06" },
|
||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/i18n.js" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/i18n.js?cacheid=6da2bca0" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/i18n.js?cacheid=2cf0f8c5" },
|
||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/index.css" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/index.css?cacheid=316dbc21" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/index.css?cacheid=f0ee124c" },
|
||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/index.js" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/index.js?cacheid=b0cc9d6b" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/index.js?cacheid=042058df" },
|
||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/iso6391To3.js" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/iso6391To3.js?cacheid=ecde2bb3" },
|
||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/isotope.pkgd.min.js" },
|
||||
|
@ -71,13 +71,16 @@ const ResourceCollection resources200Compressible{
|
|||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/mustache.min.js" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/mustache.min.js?cacheid=bd23c4fb" },
|
||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css?cacheid=eb3bec90" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css?cacheid=8fc2cc83" },
|
||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/viewer.js" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=03fd97ee" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=b9a574d4" },
|
||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/fonts/Poppins.ttf?cacheid=af705837" },
|
||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/fonts/Roboto.ttf" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/fonts/Roboto.ttf?cacheid=84d10248" },
|
||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/i18n/test.json" },
|
||||
// TODO: implement cache management of i18n resources
|
||||
//{ STATIC_CONTENT, "/ROOT%23%3F/skin/i18n/test.json?cacheid=unknown" },
|
||||
|
||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/catalog/search" },
|
||||
|
||||
|
@ -141,9 +144,6 @@ const ResourceCollection resources200Uncompressible{
|
|||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/search-icon.svg?cacheid=b10ae7ed" },
|
||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/search_results.css" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/search_results.css?cacheid=76d39c84" },
|
||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/i18n/test.json" },
|
||||
// TODO: implement cache management of i18n resources
|
||||
//{ STATIC_CONTENT, "/ROOT%23%3F/skin/i18n/test.json?cacheid=unknown" },
|
||||
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/languages.js" },
|
||||
{ STATIC_CONTENT, "/ROOT%23%3F/skin/languages.js?cacheid=fe100348" },
|
||||
|
||||
|
@ -270,7 +270,7 @@ TEST_F(ServerTest, CacheIdsOfStaticResources)
|
|||
const std::vector<UrlAndExpectedResult> testData{
|
||||
{
|
||||
/* url */ "/ROOT%23%3F/",
|
||||
R"EXPECTEDRESULT( href="/ROOT%23%3F/skin/index.css?cacheid=316dbc21"
|
||||
R"EXPECTEDRESULT( href="/ROOT%23%3F/skin/index.css?cacheid=f0ee124c"
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/ROOT%23%3F/skin/favicon/apple-touch-icon.png?cacheid=f86f8df3">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/ROOT%23%3F/skin/favicon/favicon-32x32.png?cacheid=79ded625">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/ROOT%23%3F/skin/favicon/favicon-16x16.png?cacheid=a986fedc">
|
||||
|
@ -280,10 +280,12 @@ R"EXPECTEDRESULT( href="/ROOT%23%3F/skin/index.css?cacheid=316dbc21"
|
|||
<meta name="msapplication-config" content="/ROOT%23%3F/skin/favicon/browserconfig.xml?cacheid=f29a7c4a">
|
||||
src: url("/ROOT%23%3F/skin/fonts/Poppins.ttf?cacheid=af705837") format("truetype");
|
||||
src: url("/ROOT%23%3F/skin/fonts/Roboto.ttf?cacheid=84d10248") format("truetype");
|
||||
<script type="module" src="/ROOT%23%3F/skin/i18n.js?cacheid=2cf0f8c5" defer></script>
|
||||
<script type="text/javascript" src="/ROOT%23%3F/skin/languages.js?cacheid=fe100348" defer></script>
|
||||
<script src="/ROOT%23%3F/skin/isotope.pkgd.min.js?cacheid=2e48d392" defer></script>
|
||||
<script src="/ROOT%23%3F/skin/iso6391To3.js?cacheid=ecde2bb3"></script>
|
||||
<script type="text/javascript" src="/ROOT%23%3F/skin/index.js?cacheid=b0cc9d6b" defer></script>
|
||||
<img src="/ROOT%23%3F/skin/feed.png?cacheid=56a672b1" class="feedLogo" alt="Library OPDS Feed" aria-label="Library OPDS Feed" title="Library OPDS Feed">
|
||||
<script type="text/javascript" src="/ROOT%23%3F/skin/index.js?cacheid=042058df" defer></script>
|
||||
<img src="/ROOT%23%3F/skin/feed.png?cacheid=56a672b1"
|
||||
)EXPECTEDRESULT"
|
||||
},
|
||||
{
|
||||
|
@ -293,19 +295,19 @@ R"EXPECTEDRESULT( background-image: url('../skin/search-icon.svg?cacheid=b10a
|
|||
},
|
||||
{
|
||||
/* url */ "/ROOT%23%3F/skin/index.js",
|
||||
R"EXPECTEDRESULT( <img src="../skin/download.png?cacheid=a39aa502" alt="direct download" />
|
||||
<img src="../skin/hash.png?cacheid=f836e872" alt="download hash" />
|
||||
<img src="../skin/magnet.png?cacheid=73b6bddf" alt="download magnet" />
|
||||
<img src="../skin/bittorrent.png?cacheid=4f5c6882" alt="download torrent" />
|
||||
R"EXPECTEDRESULT( <img src="${root}/skin/download.png?cacheid=a39aa502" alt="${$t("direct-download-alt-text")}" />
|
||||
<img src="${root}/skin/hash.png?cacheid=f836e872" alt="${$t("hash-download-alt-text")}" />
|
||||
<img src="${root}/skin/magnet.png?cacheid=73b6bddf" alt="${$t("magnet-alt-text")}" />
|
||||
<img src="${root}/skin/bittorrent.png?cacheid=4f5c6882" alt="${$t("torrent-download-alt-text")}" />
|
||||
)EXPECTEDRESULT"
|
||||
},
|
||||
{
|
||||
/* url */ "/ROOT%23%3F/viewer",
|
||||
R"EXPECTEDRESULT( <link type="text/css" href="./skin/taskbar.css?cacheid=eb3bec90" rel="Stylesheet" />
|
||||
R"EXPECTEDRESULT( <link type="text/css" href="./skin/taskbar.css?cacheid=8fc2cc83" rel="Stylesheet" />
|
||||
<link type="text/css" href="./skin/css/autoComplete.css?cacheid=08951e06" rel="Stylesheet" />
|
||||
<script type="module" src="./skin/i18n.js?cacheid=6da2bca0" defer></script>
|
||||
<script type="module" src="./skin/i18n.js?cacheid=2cf0f8c5" defer></script>
|
||||
<script type="text/javascript" src="./skin/languages.js?cacheid=fe100348" defer></script>
|
||||
<script type="text/javascript" src="./skin/viewer.js?cacheid=03fd97ee" defer></script>
|
||||
<script type="text/javascript" src="./skin/viewer.js?cacheid=b9a574d4" defer></script>
|
||||
<script type="text/javascript" src="./skin/autoComplete.min.js?cacheid=1191aaaf"></script>
|
||||
const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032";
|
||||
<label for="kiwix_button_show_toggle"><img src="./skin/caret.png?cacheid=22b942b4" alt=""></label>
|
||||
|
@ -358,6 +360,10 @@ TEST_F(ServerTest, 400)
|
|||
const char* urls404[] = {
|
||||
"/",
|
||||
"/zimfile",
|
||||
"/ROOT",
|
||||
"/ROOT%23%",
|
||||
"/ROOT%23%3",
|
||||
"/ROOT%23%3Fxyz",
|
||||
"/ROOT%23%3F/skin/non-existent-skin-resource",
|
||||
"/ROOT%23%3F/skin/autoComplete.min.js?cacheid=wrongcacheid",
|
||||
"/ROOT%23%3F/catalog",
|
||||
|
@ -1267,6 +1273,36 @@ TEST_F(ServerTest, UserLanguageControl)
|
|||
}
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, SlashlessRootURLIsRedirectedToSlashfulURL)
|
||||
{
|
||||
const std::pair<const char*, const char*> test_data[] = {
|
||||
// URL redirect
|
||||
{ "/ROOT%23%3F", "/ROOT%23%3F/" },
|
||||
{ "/ROOT%23%3F?abcd=123&xyz=890", "/ROOT%23%3F/?abcd=123&xyz=890" }
|
||||
};
|
||||
|
||||
for ( const auto& t : test_data )
|
||||
{
|
||||
const TestContext ctx{ {"url", t.first} };
|
||||
const auto g = zfs1_->GET(t.first);
|
||||
ASSERT_EQ(302, g->status) << ctx;
|
||||
ASSERT_TRUE(g->has_header("Location")) << ctx;
|
||||
ASSERT_EQ(g->get_header_value("Location"), t.second) << ctx;
|
||||
ASSERT_EQ(getCacheControlHeader(*g), "max-age=0, must-revalidate") << ctx;
|
||||
ASSERT_FALSE(g->has_header("ETag")) << ctx;
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, EmptyRootIsNotRedirected)
|
||||
{
|
||||
ZimFileServer::Cfg serverCfg;
|
||||
serverCfg.root = "";
|
||||
|
||||
resetServer(serverCfg);
|
||||
|
||||
ASSERT_EQ(200, zfs1_->GET("/")->status);
|
||||
}
|
||||
|
||||
TEST_F(ServerTest, RandomPageRedirectsToAnExistingArticle)
|
||||
{
|
||||
auto g = zfs1_->GET("/ROOT%23%3F/random?content=zimfile");
|
||||
|
|
|
@ -68,10 +68,18 @@ public: // types
|
|||
DEFAULT_OPTIONS = WITH_TASKBAR | WITH_LIBRARY_BUTTON
|
||||
};
|
||||
|
||||
struct Cfg
|
||||
{
|
||||
std::string root = "ROOT#?";
|
||||
Options options = DEFAULT_OPTIONS;
|
||||
|
||||
Cfg(Options opts = DEFAULT_OPTIONS) : options(opts) {}
|
||||
};
|
||||
|
||||
public: // functions
|
||||
ZimFileServer(int serverPort, Options options, std::string libraryFilePath);
|
||||
ZimFileServer(int serverPort, Cfg cfg, std::string libraryFilePath);
|
||||
ZimFileServer(int serverPort,
|
||||
Options options,
|
||||
Cfg cfg,
|
||||
const FilePathCollection& zimpaths,
|
||||
std::string indexTemplateString = "");
|
||||
~ZimFileServer();
|
||||
|
@ -95,12 +103,12 @@ private: // data
|
|||
std::unique_ptr<kiwix::NameMapper> nameMapper;
|
||||
std::unique_ptr<kiwix::Server> server;
|
||||
std::unique_ptr<httplib::Client> client;
|
||||
const Options options = DEFAULT_OPTIONS;
|
||||
const Cfg cfg;
|
||||
};
|
||||
|
||||
ZimFileServer::ZimFileServer(int serverPort, Options _options, std::string libraryFilePath)
|
||||
ZimFileServer::ZimFileServer(int serverPort, Cfg _cfg, std::string libraryFilePath)
|
||||
: manager(&this->library)
|
||||
, options(_options)
|
||||
, cfg(_cfg)
|
||||
{
|
||||
if ( kiwix::isRelativePath(libraryFilePath) )
|
||||
libraryFilePath = kiwix::computeAbsolutePath(kiwix::getCurrentDirectory(), libraryFilePath);
|
||||
|
@ -109,11 +117,11 @@ ZimFileServer::ZimFileServer(int serverPort, Options _options, std::string libra
|
|||
}
|
||||
|
||||
ZimFileServer::ZimFileServer(int serverPort,
|
||||
Options _options,
|
||||
Cfg _cfg,
|
||||
const FilePathCollection& zimpaths,
|
||||
std::string indexTemplateString)
|
||||
: manager(&this->library)
|
||||
, options(_options)
|
||||
, cfg(_cfg)
|
||||
{
|
||||
for ( const auto& zimpath : zimpaths ) {
|
||||
if (!manager.addBookFromPath(zimpath, zimpath, "", false))
|
||||
|
@ -125,19 +133,19 @@ ZimFileServer::ZimFileServer(int serverPort,
|
|||
void ZimFileServer::run(int serverPort, std::string indexTemplateString)
|
||||
{
|
||||
const std::string address = "127.0.0.1";
|
||||
if (options & NO_NAME_MAPPER) {
|
||||
if (cfg.options & NO_NAME_MAPPER) {
|
||||
nameMapper.reset(new kiwix::IdNameMapper());
|
||||
} else {
|
||||
nameMapper.reset(new kiwix::HumanReadableNameMapper(library, false));
|
||||
}
|
||||
server.reset(new kiwix::Server(&library, nameMapper.get()));
|
||||
server->setRoot("ROOT#?");
|
||||
server->setRoot(cfg.root);
|
||||
server->setAddress(address);
|
||||
server->setPort(serverPort);
|
||||
server->setNbThreads(2);
|
||||
server->setVerbose(false);
|
||||
server->setTaskbar(options & WITH_TASKBAR, options & WITH_LIBRARY_BUTTON);
|
||||
server->setBlockExternalLinks(options & BLOCK_EXTERNAL_LINKS);
|
||||
server->setTaskbar(cfg.options & WITH_TASKBAR, cfg.options & WITH_LIBRARY_BUTTON);
|
||||
server->setBlockExternalLinks(cfg.options & BLOCK_EXTERNAL_LINKS);
|
||||
server->setMultiZimSearchLimit(3);
|
||||
if (!indexTemplateString.empty()) {
|
||||
server->setIndexTemplateString(indexTemplateString);
|
||||
|
@ -171,9 +179,9 @@ protected:
|
|||
resetServer(ZimFileServer::DEFAULT_OPTIONS);
|
||||
}
|
||||
|
||||
void resetServer(ZimFileServer::Options options) {
|
||||
void resetServer(ZimFileServer::Cfg cfg) {
|
||||
zfs1_.reset();
|
||||
zfs1_.reset(new ZimFileServer(SERVER_PORT, options, ZIMFILES));
|
||||
zfs1_.reset(new ZimFileServer(SERVER_PORT, cfg, ZIMFILES));
|
||||
}
|
||||
|
||||
void TearDown() override {
|
||||
|
|
Loading…
Reference in New Issue