Compare commits

..

2 Commits

Author SHA1 Message Date
renaud gaudin
795bfecb9e trigger here 2023-04-17 13:44:55 +00:00
renaud gaudin
4efa093af8 Revert "Unlink and remove some linked python3 files"
This reverts commit 95bde675ef.
2023-04-17 13:43:34 +00:00
43 changed files with 161 additions and 634 deletions

View File

@@ -3,12 +3,12 @@ name: CI
on:
push:
branches:
- main
- can-revert
pull_request:
jobs:
macOS:
runs-on: macos-11
runs-on: macos-12
env:
HOME: /Users/runner
steps:
@@ -18,14 +18,11 @@ jobs:
- name: Install packages
run: |
brew update
brew unlink python3
# upgrade from python@3.11.2_1 to python@3.11.3 fails to overwrite those
rm -f /usr/local/bin/2to3 /usr/local/bin/2to3-3.11 /usr/local/bin/idle3 /usr/local/bin/idle3.11 /usr/local/bin/pydoc3 /usr/local/bin/pydoc3.11 /usr/local/bin/python3 /usr/local/bin/python3-config /usr/local/bin/python3.11 /usr/local/bin/python3.11-config
brew install pkg-config ninja meson
- name: Install dependencies
env:
ARCHIVE_NAME: deps2_macos_native_dyn_libkiwix.tar.xz
ARCHIVE_NAME: deps2_osx_native_dyn_libkiwix.tar.xz
run: |
wget -O- https://tmp.kiwix.org/ci/${{env.ARCHIVE_NAME}} | tar -xJ -C ${{env.HOME}}
@@ -42,92 +39,3 @@ jobs:
SKIP_BIG_MEMORY_TEST: 1
LD_LIBRARY_PATH: ${{env.HOME}}/BUILD_native_dyn/INSTALL/lib:${{env.HOME}}/BUILD_native_dyn/INSTALL/lib64
run: meson test -C build --verbose
Linux:
strategy:
fail-fast: false
matrix:
name:
- native_static
- native_dyn
- android_arm
- android_arm64
- win32_static
- win32_dyn
include:
- name: native_static
target: native_static
image_variant: focal
lib_postfix: '/x86_64-linux-gnu'
- name: native_dyn
target: native_dyn
image_variant: focal
lib_postfix: '/x86_64-linux-gnu'
- name: android_arm
target: android_arm
image_variant: focal
lib_postfix: '/arm-linux-androideabi'
- name: android_arm64
target: android_arm64
image_variant: focal
lib_postfix: '/aarch64-linux-android'
- name: win32_static
target: win32_static
image_variant: f35
lib_postfix: '64'
- name: win32_dyn
target: win32_dyn
image_variant: f35
lib_postfix: '64'
env:
HOME: /home/runner
runs-on: ubuntu-20.04
container:
image: "ghcr.io/kiwix/kiwix-build_ci_${{matrix.image_variant}}:37"
steps:
- name: Checkout code
uses: actions/checkout@v3
- name: Install deps
shell: bash
run: |
ARCHIVE_NAME=deps2_${OS_NAME}_${{matrix.target}}_libkiwix.tar.xz
wget -O- http://tmp.kiwix.org/ci/${ARCHIVE_NAME} | tar -xJ -C /home/runner
- name: Compile
shell: bash
run: |
meson --version
if [[ "${{matrix.target}}" =~ .*_dyn ]]; then
MESON_OPTION="--default-library=shared"
else
MESON_OPTION="--default-library=static"
fi
if [[ "${{matrix.target}}" =~ native_.* ]]; then
MESON_OPTION="$MESON_OPTION -Db_coverage=true"
else
MESON_OPTION="$MESON_OPTION --cross-file $HOME/BUILD_${{matrix.target}}/meson_cross_file.txt"
fi
if [[ "${{matrix.target}}" =~ android_.* ]]; then
MESON_OPTION="$MESON_OPTION -Dstatic-linkage=true"
fi
meson . build ${MESON_OPTION}
cd build
ninja
env:
PKG_CONFIG_PATH: "/home/runner/BUILD_${{matrix.target}}/INSTALL/lib/pkgconfig:/home/runner/BUILD_${{matrix.target}}/INSTALL/lib${{matrix.lib_postfix}}/pkgconfig"
CPPFLAGS: "-I/home/runner/BUILD_${{matrix.target}}/INSTALL/include"
- name: Test
if: startsWith(matrix.target, 'native_')
shell: bash
run: |
cd build
meson test --verbose
ninja coverage
env:
LD_LIBRARY_PATH: "/home/runner/BUILD_${{matrix.target}}/INSTALL/lib:/home/runner/BUILD_${{matrix.target}}/INSTALL/lib${{matrix.lib_postfix}}"
SKIP_BIG_MEMORY_TEST: 1
- name: Publish coverage
if: startsWith(matrix.target, 'native_')
uses: codecov/codecov-action@v3
with:
token: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -16,6 +16,7 @@ jobs:
- ubuntu-kinetic
- ubuntu-jammy
- ubuntu-focal
- ubuntu-bionic
steps:
- uses: actions/checkout@v3
@@ -62,6 +63,14 @@ jobs:
args: --no-sign
ppa: ${{ steps.ppa.outputs.ppa }}
- uses: legoktm/gh-action-build-deb@ubuntu-bionic
if: matrix.distro == 'ubuntu-bionic'
name: Build package for ubuntu-bionic
id: build-ubuntu-bionic
with:
args: --no-sign
ppa: ${{ steps.ppa.outputs.ppa }}
- uses: actions/upload-artifact@v3
with:
name: Packages for ${{ matrix.distro }}

View File

@@ -1,21 +0,0 @@
# Read the Docs configuration file
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
# Required
version: 2
# Set the version of Python and other tools you might need
build:
os: ubuntu-22.04
tools:
python: "3.11"
# Build documentation in the docs/ directory with Sphinx
sphinx:
configuration: docs/conf.py
# We recommend specifying your dependencies to enable reproducible builds:
# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
python:
install:
- requirements: docs/requirements.txt

View File

@@ -1,45 +1,3 @@
libkiwix 12.1.1
===============
* Revert API break introduced in libkiwix 12.1.0
libkiwix 12.1.0
===============
* Server:
- Introduce a `/nojs` endpoint to browse catalog and zim files with a browser without js (@juuz0 #897)
- Translate the viewer (@veloman-yunkan #871 #846)
- Display `mul` on tile when zim is multi-languages (@juuz0 #934)
- Suggestion links point to the `/content` endpoint (@veloman-yunkan #862)
- Correctly compress web fonts in http answers (@kelson42 #856)
- Correctly encode link in suggestions (@veloman-yunkan #859 #860 #963)
- Correctly encode url redirection (@veloman-yunkan #866 #890)
- Properly handle user language, through cookies and http headers (@veloman-yunkan #849 #869)
- Fix url encoding (@veloman-yunkan #870)
- Fix viewer for viewer for SeaMonkey (@veloman-yunkan #887)
- Make the downloader threadsafe (@mgautierfr #886)
- Add RSS feed in the main page (pointing to the catalog) (@juuz0 #882 #920)
- Correctly set the mimetype for json and ico (@veloman-yunkan #892)
- `count=-1` correspond to unlimited count (instead of 0) (@veloman-yunkan #894)
- Keep the navigation bar on top (@juuz0 #896)
- Make the viewer's iframe "safe" (@veloman-yunkan #906 #930)
- Correctly escape search link in XML Opds output (@veloman-yunkan #936)
- Store values needed for the viewer js in the url fragment instead of the query string (@juuz0 #907)
- Get rid of legacy OPDS API usage in the viewer (@veloman-yunkan #939)
- Fix charset encoding declaration in OPDS response MIME types (@veloman-yunkan #942)
- Fix PDF in the viewer (@veloman-yunkan #940)
- Fix external links handling in the viewer (@veloman-yunkan #959)
- Add tests of searching with accents (@mgautierfs #954)
* Fix handling of missing illustration in the book (@veloman-yunkan #961)
* Add support for multi languages zim files (@veloman-yunkan #904)
* Fix includes for openbsd (@bentley #949)
* Fix pathes in git to allow git clone on Windows (@adamlamar #868)
* Switch to `main` as principal branch (instead of `master`) (@kelson42)
* Remove libkiwix android publisher from the repository (@kelson42 #884)
* Various fixes of meson and CI. (@mgautierfr @kelson42)
libkiwix 12.0.0
===============

View File

@@ -184,7 +184,7 @@ class Downloader
* @param options: A series of pair <option_name, option_value> to pass to aria.
* @return: The newly created Download.
*/
Download* startDownload(const std::string& uri, const std::vector<std::pair<std::string, std::string>>& options = {});
std::shared_ptr<Download> startDownload(const std::string& uri, const std::vector<std::pair<std::string, std::string>>& options = {});
/**
* Get a download corrsponding to a download id (did)
@@ -194,7 +194,7 @@ class Downloader
* @return: The Download corresponding to did.
* @throw: Throw std::out_of_range if did is not found.
*/
Download* getDownload(const std::string& did);
std::shared_ptr<Download> getDownload(const std::string& did);
/**
* Get the number of downloads currently managed.
@@ -204,11 +204,11 @@ class Downloader
/**
* Get the ids of the managed downloads.
*/
std::vector<std::string> getDownloadIds();
std::vector<std::string> getDownloadIds() const;
private:
mutable std::mutex m_lock;
std::map<std::string, std::unique_ptr<Download>> m_knownDownloads;
std::map<std::string, std::shared_ptr<Download>> m_knownDownloads;
std::shared_ptr<Aria2> mp_aria;
};
}

View File

@@ -1,5 +1,5 @@
project('libkiwix', 'cpp',
version : '12.1.1',
version : '12.0.0',
license : 'GPLv3+',
default_options : ['c_std=c11', 'cpp_std=c++11', 'werror=true'])
@@ -36,7 +36,7 @@ else
endif
libzim_dep = dependency('libzim', version : '>=8.1.0', static:static_deps)
if not compiler.has_header_symbol('zim/zim.h', 'LIBZIM_WITH_XAPIAN', dependencies: libzim_dep)
if not compiler.has_header_symbol('zim/zim.h', 'LIBZIM_WITH_XAPIAN')
error('Libzim seems to be compiled without xapian. Xapian support is mandatory.')
endif

View File

@@ -117,12 +117,11 @@ void Book::updateFromXml(const pugi::xml_node& node, const std::string& baseDir)
m_articleCount = strtoull(ATTR("articleCount"), 0, 0);
m_mediaCount = strtoull(ATTR("mediaCount"), 0, 0);
m_size = strtoull(ATTR("size"), 0, 0) << 10;
const std::string faviconMimeType = ATTR("faviconMimeType");
const std::string faviconBase64EncodedData = ATTR("favicon");
if ( !faviconMimeType.empty() && !faviconBase64EncodedData.empty() ) {
std::string favicon_mimetype = ATTR("faviconMimeType");
if (! favicon_mimetype.empty()) {
const auto favicon = std::make_shared<Illustration>();
favicon->data = base64_decode(faviconBase64EncodedData);
favicon->mimeType = faviconMimeType;
favicon->data = base64_decode(ATTR("favicon"));
favicon->mimeType = favicon_mimetype;
favicon->url = ATTR("faviconUrl");
m_illustrations.assign(1, favicon);
}

View File

@@ -157,7 +157,7 @@ void Downloader::close()
mp_aria->close();
}
std::vector<std::string> Downloader::getDownloadIds() {
std::vector<std::string> Downloader::getDownloadIds() const {
std::unique_lock<std::mutex> lock(m_lock);
std::vector<std::string> ret;
for(auto& p:m_knownDownloads) {
@@ -166,37 +166,37 @@ std::vector<std::string> Downloader::getDownloadIds() {
return ret;
}
Download* Downloader::startDownload(const std::string& uri, const std::vector<std::pair<std::string, std::string>>& options)
std::shared_ptr<Download> Downloader::startDownload(const std::string& uri, const std::vector<std::pair<std::string, std::string>>& options)
{
std::unique_lock<std::mutex> lock(m_lock);
for (auto& p: m_knownDownloads) {
auto& d = p.second;
auto& uris = d->getUris();
if (std::find(uris.begin(), uris.end(), uri) != uris.end())
return d.get();
return d;
}
std::vector<std::string> uris = {uri};
auto gid = mp_aria->addUri(uris, options);
m_knownDownloads[gid] = std::unique_ptr<Download>(new Download(mp_aria, gid));
return m_knownDownloads[gid].get();
m_knownDownloads[gid] = std::make_shared<Download>(mp_aria, gid);
return m_knownDownloads[gid];
}
Download* Downloader::getDownload(const std::string& did)
std::shared_ptr<Download> Downloader::getDownload(const std::string& did)
{
std::unique_lock<std::mutex> lock(m_lock);
try {
return m_knownDownloads.at(did).get();
return m_knownDownloads.at(did);
} catch(std::exception& e) {
for (auto gid : mp_aria->tellWaiting()) {
if (gid == did) {
m_knownDownloads[gid] = std::unique_ptr<Download>(new Download(mp_aria, gid));
return m_knownDownloads[gid].get();
m_knownDownloads[gid] = std::make_shared<Download>(mp_aria, gid);
return m_knownDownloads[gid];
}
}
for (auto gid : mp_aria->tellActive()) {
if (gid == did) {
m_knownDownloads[gid] = std::unique_ptr<Download>(new Download(mp_aria, gid));
return m_knownDownloads[gid].get();
m_knownDownloads[gid] = std::make_shared<Download>(mp_aria, gid);
return m_knownDownloads[gid];
}
}
throw e;

View File

@@ -38,7 +38,6 @@ std::map<std::string, std::string> iso639_3 = {
{"dty", "डोटेली"},
{"eml", "emiliân-rumagnōl"},
{"fbs", "српскохрватски"},
{"guw", "Gungbe"},
{"hbs", "srpskohrvatski"},
{"ido", "ido"},
{"kbp", "kabɩ"},

View File

@@ -26,7 +26,7 @@ kiwix_sources = [
'server/request_context.cpp',
'server/response.cpp',
'server/internalServer.cpp',
'server/internalServer_catalog.cpp',
'server/internalServer_catalog_v2.cpp',
'server/i18n.cpp',
'opds_catalog.cpp',
'version.cpp'

View File

@@ -150,17 +150,17 @@ string OPDSDumper::dumpOPDSFeedV2(const std::vector<std::string>& bookIds, const
const auto booksData = getBooksData(library, nameMapper, bookIds, rootLocation, partial);
const char* const endpoint = partial ? "/partial_entries" : "/entries";
const std::string url = endpoint + (query.empty() ? "" : "?" + query);
const kainjow::mustache::object template_data{
{"date", gen_date_str()},
{"endpoint_root", endpointRoot},
{"feed_id", gen_uuid(libraryId + endpoint + "?" + query)},
{"filter", onlyAsNonEmptyMustacheValue(query)},
{"self_url", url},
{"query", query.empty() ? "" : "?" + query},
{"totalResults", to_string(m_totalResults)},
{"startIndex", to_string(m_startIndex)},
{"itemsPerPage", to_string(m_count)},
{"books", booksData }
{"books", booksData },
{"dump_partial_entries", MustacheData(partial)}
};
return render_template(RESOURCE::templates::catalog_v2_entries_xml, template_data);

View File

@@ -19,7 +19,7 @@
#include "internalServer.h"
#ifndef _WIN32
#ifdef __FreeBSD__
#include <netinet/in.h>
#endif
@@ -1046,6 +1046,56 @@ std::unique_ptr<Response> InternalServer::handle_catch(const RequestContext& req
+ urlNotFoundMsg;
}
std::unique_ptr<Response> InternalServer::handle_catalog(const RequestContext& request)
{
if (m_verbose.load()) {
printf("** running handle_catalog");
}
std::string host;
std::string url;
try {
host = request.get_header("Host");
url = request.get_url_part(1);
} catch (const std::out_of_range&) {
return HTTP404Response(*this, request)
+ urlNotFoundMsg;
}
if (url == "v2") {
return handle_catalog_v2(request);
}
if (url != "searchdescription.xml" && url != "root.xml" && url != "search") {
return HTTP404Response(*this, request)
+ urlNotFoundMsg;
}
if (url == "searchdescription.xml") {
auto response = ContentResponse::build(*this, RESOURCE::opensearchdescription_xml, get_default_data(), "application/opensearchdescription+xml");
return std::move(response);
}
zim::Uuid uuid;
kiwix::OPDSDumper opdsDumper(mp_library, mp_nameMapper);
opdsDumper.setRootLocation(m_root);
opdsDumper.setLibraryId(getLibraryId());
std::vector<std::string> bookIdsToDump;
if (url == "root.xml") {
uuid = zim::Uuid::generate(host);
bookIdsToDump = mp_library->filter(kiwix::Filter().valid(true).local(true).remote(true));
} else if (url == "search") {
bookIdsToDump = search_catalog(request, opdsDumper);
uuid = zim::Uuid::generate();
}
auto response = ContentResponse::build(
*this,
opdsDumper.dumpOPDSFeed(bookIdsToDump, request.get_query()),
"application/atom+xml; profile=opds-catalog; kind=acquisition; charset=utf-8");
return std::move(response);
}
std::vector<std::string>
InternalServer::search_catalog(const RequestContext& request,
kiwix::OPDSDumper& opdsDumper)

View File

@@ -33,74 +33,6 @@
namespace kiwix {
namespace
{
enum OPDSResponseKind
{
OPDS_ENTRY,
OPDS_NAVIGATION_FEED,
OPDS_ACQUISITION_FEED
};
const std::string opdsMimeType[] = {
"application/atom+xml;type=entry;profile=opds-catalog;charset=utf-8",
"application/atom+xml;profile=opds-catalog;kind=navigation;charset=utf-8",
"application/atom+xml;profile=opds-catalog;kind=acquisition;charset=utf-8"
};
} // unnamed namespace
std::unique_ptr<Response> InternalServer::handle_catalog(const RequestContext& request)
{
if (m_verbose.load()) {
printf("** running handle_catalog");
}
std::string host;
std::string url;
try {
host = request.get_header("Host");
url = request.get_url_part(1);
} catch (const std::out_of_range&) {
return HTTP404Response(*this, request)
+ urlNotFoundMsg;
}
if (url == "v2") {
return handle_catalog_v2(request);
}
if (url != "searchdescription.xml" && url != "root.xml" && url != "search") {
return HTTP404Response(*this, request)
+ urlNotFoundMsg;
}
if (url == "searchdescription.xml") {
auto response = ContentResponse::build(*this, RESOURCE::opensearchdescription_xml, get_default_data(), "application/opensearchdescription+xml");
return std::move(response);
}
zim::Uuid uuid;
kiwix::OPDSDumper opdsDumper(mp_library, mp_nameMapper);
opdsDumper.setRootLocation(m_root);
opdsDumper.setLibraryId(getLibraryId());
std::vector<std::string> bookIdsToDump;
if (url == "root.xml") {
uuid = zim::Uuid::generate(host);
bookIdsToDump = mp_library->filter(kiwix::Filter().valid(true).local(true).remote(true));
} else if (url == "search") {
bookIdsToDump = search_catalog(request, opdsDumper);
uuid = zim::Uuid::generate();
}
auto response = ContentResponse::build(
*this,
opdsDumper.dumpOPDSFeed(bookIdsToDump, request.get_query()),
opdsMimeType[OPDS_ACQUISITION_FEED]);
return std::move(response);
}
std::unique_ptr<Response> InternalServer::handle_catalog_v2(const RequestContext& request)
{
if (m_verbose.load()) {
@@ -158,7 +90,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_root(const RequestCo
{"category_list_feed_id", gen_uuid(libraryId + "/categories")},
{"language_list_feed_id", gen_uuid(libraryId + "/languages")}
},
opdsMimeType[OPDS_NAVIGATION_FEED]
"application/atom+xml;profile=opds-catalog;kind=navigation"
);
}
@@ -172,7 +104,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_entries(const Reques
return ContentResponse::build(
*this,
opdsFeed,
opdsMimeType[OPDS_ACQUISITION_FEED]
"application/atom+xml;profile=opds-catalog;kind=acquisition"
);
}
@@ -192,7 +124,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_complete_entry(const
return ContentResponse::build(
*this,
opdsFeed,
opdsMimeType[OPDS_ENTRY]
"application/atom+xml;type=entry;profile=opds-catalog"
);
}
@@ -204,7 +136,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_categories(const Req
return ContentResponse::build(
*this,
opdsDumper.categoriesOPDSFeed(),
opdsMimeType[OPDS_NAVIGATION_FEED]
"application/atom+xml;profile=opds-catalog;kind=navigation"
);
}
@@ -216,7 +148,7 @@ std::unique_ptr<Response> InternalServer::handle_catalog_v2_languages(const Requ
return ContentResponse::build(
*this,
opdsDumper.languagesOPDSFeed(),
opdsMimeType[OPDS_NAVIGATION_FEED]
"application/atom+xml;profile=opds-catalog;kind=navigation"
);
}

View File

@@ -5,7 +5,6 @@ skin/i18n/de.json
skin/i18n/dga.json
skin/i18n/el.json
skin/i18n/en.json
skin/i18n/fi.json
skin/i18n/fr.json
skin/i18n/he.json
skin/i18n/hy.json

View File

@@ -11,8 +11,5 @@
"library-button-text": "স্বাগত পাতায় চলুন",
"home-button-text": "'{{BOOK_TITLE}}'-এর প্রধান পাতায় চলুন",
"searchbox-tooltip": "'{{BOOK_TITLE}}' অনুসন্ধান করুন",
"search": "অনুসন্ধান",
"welcome-to-kiwix-server": "কিউইক্স সার্ভারে স্বাগতম",
"download-links-title": "বই ডাউনলোড করুন",
"preview-book": "প্রাকদর্শন"
"search": "অনুসন্ধান"
}

View File

@@ -1,11 +1,10 @@
{
"@metadata": {
"authors": [
"Alhaji Yakubu",
"Amire80"
"Alhaji Yakubu"
]
},
"welcome-page-overzealous-filter": "Duoro kyebe. <a href=\"{{URL}}\">E na boɔra ka fo</a>?",
"welcome-page-overzealous-filter": "Duoro kyebe. E na boɔra ka fo <a href=\"?lang=\"></a>",
"search": "Bo",
"book-filtering-all-categories": "Zagre zaa",
"book-filtering-all-languages": "Kɔkɔrɛɛ zaa",
@@ -16,6 +15,7 @@
"hash-download-alt-text": "Tage bonmannaa",
"magnet-link-text": "Kurimaraa sobie",
"magnet-alt-text": "Tage kurimaraa",
"library-opds-feed": "Gamadie OPDS diibu",
"filter-by-tag": "Guy yi kpuli {{TAG}}",
"stop-filtering-by-tag": "Bare gyɛɛbo kpuli {{TAG}}"
}

View File

@@ -1,11 +1,10 @@
{
"@metadata": {
"authors": [
"Kelson",
"Norhorn"
]
},
"welcome-page-overzealous-filter": "Κανένα αποτέλεσμα. Θέλετε να <a href=\"{{URL}}\">επαναφέρετε το φίλτρο</a>;",
"welcome-page-overzealous-filter": "Κανένα αποτέλεσμα. Θέλετε να <a href=\"?lang=\">επαναφέρετε το φίλτρο</a>;",
"powered-by-kiwix-html": "Με την υποστήριξη by&nbsp;<a href=\"https://kiwix.org\">Kiwix</a>",
"search": "Αναζήτηση",
"book-filtering-all-categories": "Όλες οι κατηγορίες",

View File

@@ -1,30 +0,0 @@
{
"@metadata": {
"authors": [
"MITO",
"Nike",
"Pyscowicz"
]
},
"name": "suomi",
"suggest-full-text-search": "sisältää '{{{SEARCH_TERMS}}}'...",
"url-not-found": "Pyydettyä URL-osoitetta \"{{url}}\" ei löytynyt tältä palvelimelta.",
"400-page-title": "Virheellinen pyyntö",
"400-page-heading": "Virheellinen pyyntö",
"404-page-title": "Sisältöä ei löytynyt",
"404-page-heading": "Ei löytynyt",
"500-page-title": "Sisäinen palvelinvirhe",
"500-page-heading": "Sisäinen palvelinvirhe",
"library-button-text": "Siirry tervetulosivulle",
"home-button-text": "Siirry kirjan '{{BOOK_TITLE}}' etusivulle",
"random-page-button-text": "Siirry satunnaiselle sivulle",
"searchbox-tooltip": "Hae '{{BOOK_TITLE}}'",
"search": "Hae",
"book-filtering-all-categories": "Kaikki luokat",
"book-filtering-all-languages": "Kaikki kielet",
"download": "Lataa",
"torrent-download-link-text": "Torrent-tiedosto",
"filter-by-tag": "Suodata tunnisteen ”{{TAG}}” mukaan",
"download-links-title": "Lataa kirja",
"preview-book": "Esikatsele"
}

View File

@@ -31,7 +31,7 @@
"random-page-button-text": "Aller à une page sélectionnée aléatoirement",
"searchbox-tooltip": "Rechercher « {{BOOK_TITLE}} »",
"confusion-of-tongues": "Deux livres ou plus dans des langues différentes participeraient à la recherche, ce qui pourrait conduire à des résultats confus.",
"welcome-page-overzealous-filter": "Aucun résultat. Souhaitez-vous <a href=\"{{URL}}\">réinitialiser le filtre</a>?",
"welcome-page-overzealous-filter": "Aucun résultat. Souhaitez-vous <a href=\"?lang=\">réinitialiser le filtre</a>?",
"powered-by-kiwix-html": "Propulsé par <a href=\"https://kiwix.org/\">Kiwix</a>",
"search": "Rechercher",
"book-filtering-all-categories": "Toutes les catégories",
@@ -46,12 +46,7 @@
"magnet-alt-text": "télécharger le lien Magnet",
"torrent-download-link-text": "Fichier torrent",
"torrent-download-alt-text": "télécharger le torrent",
"library-opds-feed-all-entries": "Flux OPDS de la bibliothèque Toutes les entrées",
"library-opds-feed": "Flux OPDS de la bibliothèque",
"filter-by-tag": "Filtrer par la balise « {{TAG}} »",
"stop-filtering-by-tag": "Arrêter le filtrage par la balise « {{TAG}} »",
"library-opds-feed-parameterised": "Flux OPDS de la bibliothèque Entrées correspondant à {{#LANG}}:\n ▪ Langue: {{LANG}} {{/LANG}}{{#CATEGORY}}\n ▪ Catégorie: {{CATEGORY}} {{/CATEGORY}}{{#TAG}}\n ▪ Étiquette: {{TAG}} {{/TAG}}{{#Q}}\n ▪ Requête: {{Q}} {{/Q}}",
"welcome-to-kiwix-server": "Bienvenue sur le Serveur Kiwix",
"download-links-heading": "Liens de téléchargement pour <b><i>{{BOOK_TITLE}}</i></b>",
"download-links-title": "Télécharger le livre",
"preview-book": "Aperçu"
"stop-filtering-by-tag": "Arrêter le filtrage par la balise « {{TAG}} »"
}

View File

@@ -30,7 +30,7 @@
"random-page-button-text": "מעבר לדף שנבחר אקראית",
"searchbox-tooltip": "חיפוש \"{{BOOK_TITLE}}\"",
"confusion-of-tongues": "שני ספרים או יותר בשפות שונות ישתתפו בחיפוש, מה שעלול להוביל לתוצאות מבלבלות.",
"welcome-page-overzealous-filter": "אין תוצאות. האם <a href=\"{{URL}}\">לאפס את המסנן</a>?",
"welcome-page-overzealous-filter": "אין תוצאות. האם <a href=\"?lang=\">לאפס את המסנן</a>?",
"powered-by-kiwix-html": "מופעל על־ידי&nbsp;<a href=\"https://kiwix.org\">Kiwix</a>",
"search": "חיפוש",
"book-filtering-all-categories": "כל הקטגוריות",
@@ -45,12 +45,7 @@
"magnet-alt-text": "הורדת magnet",
"torrent-download-link-text": "קובץ טורנט",
"torrent-download-alt-text": "הורדת טורנט",
"library-opds-feed-all-entries": "הזנת ספריית OPDS - כל הרשומות",
"library-opds-feed": "הזנת OPDS של ספרייה",
"filter-by-tag": "סינון לפי התג \"{{TAG}}\"",
"stop-filtering-by-tag": "להפסיק סינון לפי התג \"{{TAG}}\"",
"library-opds-feed-parameterised": "הזנת ספריית OPDS - רשומות שתואמות ל{{#LANG}}\nשפה: {{LANG}} {{/LANG}}{{#CATEGORY}}\nקטגוריה: {{CATEGORY}} {{/CATEGORY}}{{#TAG}}\nתג: {{TAG}} {{/TAG}}{{#Q}}\nשאילתה: {{Q}} {{/Q}}",
"welcome-to-kiwix-server": "ברוך בואך לשרת קיוויקס",
"download-links-heading": "הורדת קישורים עבור <b><i>{{BOOK_TITLE}}</i></b>",
"download-links-title": "הורדת ספר",
"preview-book": "תצוגה מקדימה"
"stop-filtering-by-tag": "להפסיק סינון לפי התג \"{{TAG}}\""
}

View File

@@ -1,36 +1,10 @@
{
"@metadata": {
"authors": [
"Kelson",
"McDutchie"
]
},
"name": "interlingua",
"suggest-full-text-search": "continente '{{{SEARCH_TERMS}}}'...",
"no-such-book": "Necun tal libro: {{BOOK_NAME}}",
"too-many-books": "Troppo de libros demandate ({{NB_BOOKS}}); le limite es {{LIMIT}}",
"no-book-found": "Necun libro corresponde al criterios de selection",
"url-not-found": "Le URL reuqestate \"{{url}}\" non ha essite trovate sur iste servitor.",
"suggest-search": "Facer un recerca in texto complete de <a href=\"{{{SEARCH_URL}}}\">{{PATTERN}}</a>",
"random-article-failure": "Ups! Non poteva eliger un articulo aleatori :(",
"invalid-raw-data-type": "{{DATATYPE}} non es un request valide pro contento crude.",
"no-value-for-arg": "Necun valor fornite pro le argumento {{ARGUMENT}}",
"no-query": "Necun consulta fornite.",
"raw-entry-not-found": "Non pote trovar le entrata {{ENTRY}} del typo {{DATATYPE}}",
"400-page-title": "Requesta invalide",
"400-page-heading": "Requesta invalide",
"404-page-title": "Contento non trovate",
"404-page-heading": "Non trovate",
"500-page-title": "Error interne del servitor",
"500-page-heading": "Error interne del servitor",
"fulltext-search-unavailable": "Le recerca in texto complete es indisponibile",
"no-search-results": "Le motor de recerca in texto complete non es disponibile pro iste contento.",
"library-button-text": "Ir al pagina de benvenita",
"home-button-text": "Ir al pagina principal de ''{{BOOK_TITLE}}",
"random-page-button-text": "Ir a un pagina seligite aleatorimente",
"searchbox-tooltip": "Cercar '{{BOOK_TITLE}}'",
"confusion-of-tongues": "Duo o plus libros in differente linguas participarea in le recerca, lo que pote menar a resultatos confuse.",
"welcome-page-overzealous-filter": "Nulle resultato. Vole tu <a href=\"{{URL}}\">reinitialisar le filtro</a>?",
"welcome-page-overzealous-filter": "Nulle resultato. Vole tu <a href=\"?lang=\">reinitialisar le filtro</a>?",
"powered-by-kiwix-html": "Actionate per&nbsp;<a href=\"https://kiwix.org\">Kiwix</a>",
"search": "Cercar",
"book-filtering-all-categories": "Tote le categorias",
@@ -45,12 +19,7 @@
"magnet-alt-text": "ligamine \"magnet\" de discargamento",
"torrent-download-link-text": "File Torrent",
"torrent-download-alt-text": "discargar Torrent",
"library-opds-feed-all-entries": "Fluxo OPDS del bibliotheca Tote le entratas",
"library-opds-feed": "Fluxo OPDS del bibliotheca",
"filter-by-tag": "Filtrar per etiquetta \"{{TAG}}\"",
"stop-filtering-by-tag": "Non plus filtrar per etiquetta \"{{TAG}}\"",
"library-opds-feed-parameterised": "Fluxo OPDS del bibliotheca Entratas correspondente a {{#LANG}}\nLingua {{LANG}} {{/LANG}}{{#CATEGORY}}\nCategoria: {{CATEGORY}} {{/CATEGORY}}{{#TAG}}\nEtiquetta: {{TAG}} {{/TAG}}{{#Q}}\nConsulta: {{Q}} {{/Q}}",
"welcome-to-kiwix-server": "Benvenite al servitor Kiwix",
"download-links-heading": "Discargar ligamines pro <b><i>{{BOOK_TITLE}}</i></b>",
"download-links-title": "Discargar libro",
"preview-book": "Previsualisation"
"stop-filtering-by-tag": "Non plus filtrar per etiquetta \"{{TAG}}\""
}

View File

@@ -2,13 +2,12 @@
"@metadata": {
"authors": [
"Albano",
"Beta16",
"McDutchie"
"Beta16"
]
},
"name": "italiano",
"suggest-full-text-search": "contenente '{{{SEARCH_TERMS}}}'...",
"no-such-book": "Nessun libro con questo nome: {{BOOK_NAME}}",
"no-such-book": "Nessun libro del genere: {{BOOK_NAME}}",
"too-many-books": "Troppi libri richiesti ({{NB_BOOKS}}) dove il limite è {{LIMIT}}",
"no-book-found": "Nessun libro corrisponde ai criteri di selezione",
"url-not-found": "L'URL richiesto \"{{url}}\" non è stato trovato in questo server.",
@@ -28,7 +27,5 @@
"book-filtering-all-categories": "Tutte le categorie",
"book-filtering-all-languages": "Tutte le lingue",
"count-of-matching-books": "{{COUNT}} libro/i",
"download": "Scarica",
"download-links-title": "Scarica libro",
"preview-book": "Anteprima"
"download": "Scarica"
}

View File

@@ -28,6 +28,5 @@
"magnet-link-text": "マグネットリンク",
"magnet-alt-text": "マグネットをダウンロード",
"torrent-download-link-text": "Torrentファイル",
"torrent-download-alt-text": "Torrentをダウンロード",
"preview-book": "プレビュー"
"torrent-download-alt-text": "Torrentをダウンロード"
}

View File

@@ -14,6 +14,5 @@
"500-page-title": "내부 서버 오류",
"500-page-heading": "내부 서버 오류",
"fulltext-search-unavailable": "전문 검색을 사용할 수 없습니다",
"random-page-button-text": "무작위로 선택된 문서로 이동",
"preview-book": "미리 보기"
"random-page-button-text": "무작위로 선택된 문서로 이동"
}

View File

@@ -1,7 +1,6 @@
{
"@metadata": {
"authors": [
"Kelson",
"Robby",
"Volvox"
]
@@ -17,7 +16,7 @@
"home-button-text": "Gitt op d'Haaptsäit vun '{{BOOK_TITLE}}'",
"random-page-button-text": "Gitt op eng zoufälleg gewielte Säit",
"searchbox-tooltip": "No '{{BOOK_TITLE}}' sichen",
"welcome-page-overzealous-filter": "Kee Resultat. Wëllt Dir <a href=\"{{URL}}\">de Filter zrécksetzen</a>?",
"welcome-page-overzealous-filter": "Kee Resultat. Wëllt Dir <a href=\"?lang=\">de Filter zrécksetzen</a>?",
"search": "Sichen",
"book-filtering-all-categories": "All Kategorien",
"book-filtering-all-languages": "All Sproochen",

View File

@@ -1,8 +1,7 @@
{
"@metadata": {
"authors": [
"Bjankuloski06",
"Kelson"
"Bjankuloski06"
]
},
"name": "македонски",
@@ -30,7 +29,7 @@
"random-page-button-text": "Оди на случајно избрана страница",
"searchbox-tooltip": "Пребарај го „{{BOOK_TITLE}}“",
"confusion-of-tongues": "Во пребарувањето ќе учествуваат две или повеќе книги на различни јазици, што може да довете до збунувачки исход.",
"welcome-page-overzealous-filter": "Нема исход. Дали би сакале да го <a href=\"{{URL}}\">поништите филтерот</a>?",
"welcome-page-overzealous-filter": "Нема исход. Дали би сакале да го <a href=\"?lang=\">поништите филтерот</a>?",
"powered-by-kiwix-html": "Овозможено од&nbsp;<a href=\"https://kiwix.org\">Кивикс</a>",
"search": "Пребарај",
"book-filtering-all-categories": "Сите категории",
@@ -45,12 +44,7 @@
"magnet-alt-text": "преземи магнет",
"torrent-download-link-text": "Торентна податотека",
"torrent-download-alt-text": "преземи торент",
"library-opds-feed-all-entries": "Библиотечен тековник на OPDS — Сите ставки",
"library-opds-feed": "Библиотечен OPDS-тековник",
"filter-by-tag": "Филтрирај по ознаката „{{TAG}}“",
"stop-filtering-by-tag": "Запри филтрирање по ознаката „{{TAG}}“",
"library-opds-feed-parameterised": "Библиотечен тековник на OPDS — ставки што одговараат на {{#LANG}}\nЈазик: {{LANG}} {{/LANG}}{{#CATEGORY}}\nКатегорија: {{CATEGORY}} {{/CATEGORY}}{{#TAG}}\nОзнака: {{TAG}} {{/TAG}}{{#Q}}\nБарање: {{Q}} {{/Q}}",
"welcome-to-kiwix-server": "Добре дојдовте на Опслужувачот на Кивикс",
"download-links-heading": "Врски за преземање на <b><i>{{BOOK_TITLE}}</i></b>",
"download-links-title": "Преземи книга",
"preview-book": "Преглед"
"stop-filtering-by-tag": "Запри филтрирање по ознаката „{{TAG}}“"
}

View File

@@ -1,7 +1,6 @@
{
"@metadata": {
"authors": [
"Kelson",
"McDutchie",
"Vistaus"
]
@@ -10,7 +9,7 @@
"no-book-found": "Er zijn geen boeken die overeenkomen met de zoekcriteria",
"no-value-for-arg": "Er is geen waarde opgegeven bij {{ARGUMENT}}",
"no-query": "Er is geen zoekterm opgegeven.",
"welcome-page-overzealous-filter": "Geen resultaat. Wilt u <a href=\"{{URL}}\">het filter resetten</a>?",
"welcome-page-overzealous-filter": "Geen resultaat. Wilt u <a href=\"?lang=\">het filter resetten</a>?",
"powered-by-kiwix-html": "Mogelijk gemaakt door <a href=\"https://kiwix.org\">Kiwix</a>",
"search": "Zoeken",
"book-filtering-all-categories": "Alle categorieën",
@@ -25,6 +24,7 @@
"magnet-alt-text": "magnet-link van de download",
"torrent-download-link-text": "Torrent-bestand",
"torrent-download-alt-text": "torrent downloaden",
"library-opds-feed": "OPDS-feed van de bibliotheek",
"filter-by-tag": "Filteren op tag \"{{TAG}}\"",
"stop-filtering-by-tag": "Stoppen met filteren op tag \"{{TAG}}\""
}

View File

@@ -1,7 +1,6 @@
{
"@metadata": {
"authors": [
"Amire80",
"Lancine.kounfantoh.fofana"
]
},
@@ -30,21 +29,5 @@
"random-page-button-text": "ߕߊ߯ ߓߍ߲߬ߛߋ߲߬ߡߊ߬ ߞߐߜߍ߫ ߛߎߥߊ߲ߘߌߣߍ߲ ߠߎ߬ ߞߊ߲߬",
"searchbox-tooltip": "ߕߌߙߌ߲ߠߌ߲ {{BOOK_TITLE}}",
"confusion-of-tongues": "ߞߊ߬ߝߊ߫ ߝߌ߬ߟߊ߬ ߥߟߊ߫ ߦߙߌߞߊ ߞߊ߲߫ ߜߘߍ ߟߎ߬ ߘߐ߫߸ ߏ߬ ߟߎ߫ ߘߌߣߊ߬ ߕߘߍ߬ ߢߌߣߌ߲ߠߌ߲ ߘߐ߫߸ ߡߍ߲ ߠߎ߬ ߛߌ߫ ߞߣߐ߬ߝߟߌ ߟߊߘߏ߲߬ ߠߊ߫ ߞߐߝߟߌ ߘߐ߫.",
"welcome-page-overzealous-filter": "ߞߐߝߟߌ߫ ߕߴߦߋ߲߬. ߊ߬ ߝߐ߫ ߌ ߦߴߊ߬ ߝߍ߬ ߞߊ߬ <a href=\"{{URL}}\">ߛߍ߲ߛߍ߲ߟߊ߲ ߘߐߛߌ߰ ߕߎ߲߯</a>؟",
"search": "ߢߌߣߌ߲ߠߌ߲",
"book-filtering-all-categories": "ߦߌߟߡߊ ߟߎ߬ ߓߍ߯",
"book-filtering-all-languages": "ߞߊ߲ ߠߎ߬ ߓߍ߯",
"count-of-matching-books": "ߞߊ߬ߝߊ {{COUNT}}(ߟߎ߫)",
"download": "ߟߊ߬ߖߌ߰ߒ߬ߞߎ߲߬ߠߌ߲",
"direct-download-link-text": "ߒߕߋߟߋ߲ߡߊ߬",
"direct-download-alt-text": "ߟߊ߬ߖߌ߰ߒ߬ߞߎ߲߬ߠߌ߲߫ ߝߊ߲ߞߢߊ",
"hash-download-alt-text": "ߤߊߛ߭ ߟߊߖߌ߰ ߌ ߞߎ߲߬",
"magnet-link-text": "ߡߊߢߍߕ ߛߘߌ߬ߜߋ߲",
"magnet-alt-text": "ߡߊߢߍߕ ߟߊߖߌ߰ ߌ ߞߎ߲߬",
"torrent-download-link-text": "ߕߏߙߍ߲ߕ ߞߐߕߐ߮",
"torrent-download-alt-text": "ߕߏߙߍ߲ߕ ߟߊߖߌ߰ ߌ ߞߎ߲߬",
"welcome-to-kiwix-server": "ߌ ߣߌ߫ ߛߣߍ߫ ߞߥߌߞߛ ߡߊߛߐߟߊ߲ ߞߣߐ߫",
"download-links-heading": "<b><i>{{BOOK_TITLE}}</i></b> ߛߘߌ߬ߜߋ߲ ߠߊߖߌ߰ ߌ ߞߎ߲߬",
"download-links-title": "ߞߊ߬ߝߊ ߟߊߖߌ߰ ߌ ߞߎ߲߬",
"preview-book": "ߊ߬ ߘߐߜߍ߫ ߡߎߣߎ߲߬"
"welcome-page-overzealous-filter": "ߞߐߝߟߌ߫ ߕߴߦߋ߲߬. ߊ߬ ߝߐ߫ ߌ ߦߴߊ߬ ߝߍ߬ ߞߊ߬ <a href=\"?lang=\">ߛߍ߲ߛߍ߲ߟߊ߲ ߘߐߛߌ߰ ߕߎ߲߯</a>؟"
}

View File

@@ -1,8 +1,7 @@
{
"@metadata": {
"authors": [
"Strebski",
"WaldiSt"
"Strebski"
]
},
"name": "Polski",
@@ -24,8 +23,5 @@
"library-button-text": "Przejdź do strony powitalnej",
"home-button-text": "Przejdź do głównej strony '{{BOOK_TITLE}}'",
"random-page-button-text": "Przejdź do losowo wybranej strony",
"searchbox-tooltip": "Szukaj '{{BOOK_TITLE}}'",
"welcome-to-kiwix-server": "Witamy na serwerze Kiwix",
"download-links-title": "Pobierz książkę",
"preview-book": "Podgląd"
"searchbox-tooltip": "Szukaj '{{BOOK_TITLE}}'"
}

View File

@@ -45,9 +45,9 @@
"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-all-entries": "Hint for the library OPDS feed for all entries",
"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",
"library-opds-feed-all-entries": "Hint for the library OPDS feed for all entries",
"library-opds-feed-parameterised": "Hint for the library OPDS feed for filtered entries",
"welcome-to-kiwix-server": "Title shown in browser's title bar/page tab",
"download-links-heading": "Heading for no-js download page",

View File

@@ -1,7 +1,6 @@
{
"@metadata": {
"authors": [
"Kelson",
"L2212"
]
},
@@ -29,28 +28,5 @@
"home-button-text": "Bae a sa pàgina printzipale de '{{BOOK_TITLE}}'",
"random-page-button-text": "Bae a una pàgina seletzionada a manera casuale",
"searchbox-tooltip": "Chirca '{{BOOK_TITLE}}'",
"confusion-of-tongues": "Duos o prus libros in limbas diferentes diant pigare parte a sa chirca, cosa chi diat pòdere causare resurtados confusionosos.",
"welcome-page-overzealous-filter": "Perunu resurtadu. Boles <a href=\"{{URL}}\">resetare su filtru</a>?",
"powered-by-kiwix-html": "Alimentadu dae&nbsp;<a href=\"https://kiwix.org\">Kiwix</a>",
"search": "Chirca",
"book-filtering-all-categories": "Totu sas categorias",
"book-filtering-all-languages": "Totu sas limbas",
"count-of-matching-books": "{{COUNT}} libru/os",
"download": "Iscàrriga",
"direct-download-link-text": "Diretu",
"direct-download-alt-text": "iscarrigamentu diretu",
"hash-download-link-text": "Hash SHA256",
"hash-download-alt-text": "hash de s'iscarrigamentu",
"magnet-link-text": "Ligàmene Magnet",
"magnet-alt-text": "ligàmene \"magnet\" de iscarrigamentu",
"torrent-download-link-text": "Documentu Torrent",
"torrent-download-alt-text": "iscàrriga su torrent",
"library-opds-feed-all-entries": "Flussu OPDS de sa biblioteca Totu sos elementos",
"filter-by-tag": "Filtra pro eticheta \"{{TAG}}\"",
"stop-filtering-by-tag": "Non filtres prus pro eticheta \"{{TAG}}\"",
"library-opds-feed-parameterised": "Flussu OPDS de sa biblioteca - elementos chi currispondet cun {{#LANG}}\nLimba: {{LANG}} {{/LANG}}{{#CATEGORY}}\nCategoria: {{CATEGORY}} {{/CATEGORY}}{{#TAG}}\nEticheta: {{TAG}} {{/TAG}}{{#Q}}\nChirca: {{Q}} {{/Q}}",
"welcome-to-kiwix-server": "Bene bènnidu a su serbidore de Kiwix",
"download-links-heading": "Ligàmenes de iscarrigamentu pro <b><i>{{BOOK_TITLE}}</i></b>",
"download-links-title": "Iscàrriga su libru",
"preview-book": "Antiprima"
"confusion-of-tongues": "Duos o prus libros in limbas diferentes diant pigare parte a sa chirca, cosa chi diat pòdere causare resurtados confusionosos."
}

View File

@@ -1,26 +0,0 @@
{
"@metadata": {
"authors": [
"Saraiki"
]
},
"name": "سرائیکی",
"400-page-title": "غلط ارداس",
"400-page-heading": "غلط ارداس",
"404-page-title": "مواد کائنی لبھیا",
"404-page-heading": "کائنی لبھا",
"500-page-title": "اندرلا سرور نقص",
"500-page-heading": "اندرلا سرور نقص",
"search": "ڳولو",
"book-filtering-all-categories": "ساریاں ونکیاں",
"book-filtering-all-languages": "ساریاں زباناں",
"count-of-matching-books": "{{COUNT}} کتاب(اں)",
"download": "ڈاؤن لوڈ",
"direct-download-link-text": "ڈائرکٹ",
"direct-download-alt-text": "ڈائرکٹ ڈاؤن لوڈ",
"hash-download-alt-text": "ڈاؤن لوڈ ہیش",
"torrent-download-link-text": "ٹورنٹ فائل",
"torrent-download-alt-text": "ٹورںٹ ݙاؤن لوڈ کرو",
"download-links-title": "کتاب ڈاؤن لوڈ کرو",
"preview-book": "پیشگی ݙکھالا"
}

View File

@@ -1,8 +1,7 @@
{
"@metadata": {
"authors": [
"Eleassar",
"Kelson"
"Eleassar"
]
},
"name": "slovenščina",
@@ -30,7 +29,7 @@
"random-page-button-text": "Pojdite na naključno izbrano stran",
"searchbox-tooltip": "Poiščite »{{BOOK_TITLE}}«",
"confusion-of-tongues": "V iskanju bi bili uporabljeni dve ali več knjig v različnih jezikih, kar lahko pripelje do nejasnih zadetkov.",
"welcome-page-overzealous-filter": "Ni zadetkov. Želite <a href=\"{{URL}}\">ponastaviti filter</a>?",
"welcome-page-overzealous-filter": "Ni zadetkov. Želite <a href=\"?lang=\">ponastaviti filter</a>?",
"powered-by-kiwix-html": "Omogoča <a href=\"https://kiwix.org\">Kiwix</a>",
"search": "Išči",
"book-filtering-all-categories": "Vse kategorije",
@@ -45,12 +44,7 @@
"magnet-alt-text": "prenesi magnet",
"torrent-download-link-text": "Torrent datoteka",
"torrent-download-alt-text": "prenesi torrent",
"library-opds-feed-all-entries": "Knjižnični vir OPDS Vsi vnosi",
"library-opds-feed": "Vir OPDS knjižnice",
"filter-by-tag": "Filtriraj po oznaki »{{TAG}}«",
"stop-filtering-by-tag": "Ustavi filtriranje po oznaki »{{TAG}}«",
"library-opds-feed-parameterised": "Knjižnični vir OPDS vnosi, ki se ujemajo z {{#LANG}}\nJezik: {{LANG}} {{/LANG}}{{#CATEGORY}}\nKategorija: {{CATEGORY}} {{/CATEGORY}} {{#TAG}}\nOznaka: {{TAG}} {{/TAG}}{{#Q}}\nPoizvedba: {{Q}} {{/Q}}",
"welcome-to-kiwix-server": "Pozdravljeni na strežniku Kiwix",
"download-links-heading": "Povezave za prenos za <b><i>{{BOOK_TITLE}}</i></b>",
"download-links-title": "Prenesi knjigo",
"preview-book": "Predogled"
"stop-filtering-by-tag": "Ustavi filtriranje po oznaki »{{TAG}}«"
}

View File

@@ -30,28 +30,5 @@
"home-button-text": "Gå till huvudsidan för \"{{BOOK_TITLE}}\"",
"random-page-button-text": "Gå till en slumpmässigt utvald sida",
"searchbox-tooltip": "Sök efter \"{{BOOK_TITLE}}\"",
"confusion-of-tongues": "Två eller fler böcker på olika språk skulle delta i sökningen, vilket kan ge förvirrande resultat.",
"welcome-page-overzealous-filter": "Inga resultat. Vill du <a href=\"{{URL}}\">återställa filtret</a>?",
"powered-by-kiwix-html": "Drivs av&nbsp;<a href=\"https://kiwix.org\">Kiwix</a>",
"search": "Sök",
"book-filtering-all-categories": "Alla kategorier",
"book-filtering-all-languages": "Alla språk",
"count-of-matching-books": "{{COUNT}} böcker",
"download": "Ladda ned",
"direct-download-link-text": "Direkt",
"direct-download-alt-text": "direktnedladdning",
"hash-download-link-text": "Sha256-hash",
"hash-download-alt-text": "ladda ned hash",
"magnet-link-text": "Magnetlänk",
"magnet-alt-text": "ladda ned magnet",
"torrent-download-link-text": "Torrent-fil",
"torrent-download-alt-text": "ladda ned torrent",
"library-opds-feed-all-entries": "Library OPDS Feed - Alla poster",
"filter-by-tag": "Filtrera efter taggen \"{{TAG}}\"",
"stop-filtering-by-tag": "Sluta filtrera efter taggen \"{{TAG}}\"",
"library-opds-feed-parameterised": "Library OPDS Feed - poster som matchar {{#LANG}}\nSpråk: {{LANG}} {{/LANG}}{{#CATEGORY}}\nKategori: {{CATEGORY}} {{/CATEGORY}}{{#TAG}}\nTagg: {{TAG}} {{/TAG}}{{#Q}}\nFråga: {{Q}} {{/Q}}",
"welcome-to-kiwix-server": "Välkommen till Kiwix Server",
"download-links-heading": "Nedladdningslänkar för <b><i>{{BOOK_TITLE}}</i></b>",
"download-links-title": "Ladda ned bok",
"preview-book": "Förhandsgranska"
"confusion-of-tongues": "Två eller fler böcker på olika språk skulle delta i sökningen, vilket kan ge förvirrande resultat."
}

View File

@@ -1,7 +1,6 @@
{
"@metadata": {
"authors": [
"Kelson",
"Kly",
"Winston Sung"
]
@@ -31,7 +30,7 @@
"random-page-button-text": "前往隨機選取頁面",
"searchbox-tooltip": "在{{BOOK_TITLE}}搜尋",
"confusion-of-tongues": "搜索裡有加入兩本或更多不同語言的書籍,這可能會導致混淆結果。",
"welcome-page-overzealous-filter": "沒有結果。您想要<a href=\"{{URL}}\">重新設定篩選</a>嗎?",
"welcome-page-overzealous-filter": "沒有結果。您想要<a href=\"?lang=\">重新設定篩選</a>嗎?",
"powered-by-kiwix-html": "由 <a href=\"https://kiwix.org\">Kiwix</a> 提供技術支援",
"search": "搜尋",
"book-filtering-all-categories": "所有分類",
@@ -46,12 +45,7 @@
"magnet-alt-text": "下載 magnet",
"torrent-download-link-text": "Torrent 檔案",
"torrent-download-alt-text": "下載 torrent",
"library-opds-feed-all-entries": "圖書館 OPDS 摘要 - 所有項目",
"library-opds-feed": "圖書館 OPDS 訊息來源",
"filter-by-tag": "依標籤「{{TAG}}」篩選",
"stop-filtering-by-tag": "停止依標籤「{{TAG}}」篩選",
"library-opds-feed-parameterised": "圖書館 OPDS 摘要 - 項目符合 {{#LANG}}\n語言{{LANG}} {{/LANG}}{{#CATEGORY}}\n分類{{CATEGORY}} {{/CATEGORY}}{{#TAG}}\n標籤{{TAG}} {{/TAG}}{{#Q}}\n查詢{{Q}} {{/Q}}",
"welcome-to-kiwix-server": "歡迎來到 Kiwix 伺服器",
"download-links-heading": "下載<b><i>{{BOOK_TITLE}}</i></b>的連結",
"download-links-title": "下載書籍",
"preview-book": "預覽"
"stop-filtering-by-tag": "停止依標籤「{{TAG}}」篩選"
}

View File

@@ -51,7 +51,7 @@
}
function queryUrlBuilder() {
let url = `${root}/catalog/v2/entries?`;
let url = `${root}/catalog/search?`;
url += Object.keys(incrementalLoadingParams).map(key => `${key}=${incrementalLoadingParams[key]}`).join("&");
params.forEach((value, key) => {url+= value ? `&${key}=${value}` : ''});
return (url);
@@ -131,13 +131,8 @@
const title = getInnerHtml(book, 'title');
const description = getInnerHtml(book, 'summary');
const id = getInnerHtml(book, 'id');
const langCodesList = getInnerHtml(book, 'language').split(',');
const langCode = langCodesList.length == 1 ? langCodesList[0] : 'mul';
let language = languages[langCode];
if (langCode == 'mul') {
const mulLangList = langCodesList.filter(x => languages.hasOwnProperty(x)).map(x => languages[x]);
language = mulLangList.join(', ');
}
const langCode = getInnerHtml(book, 'language');
const language = languages[langCode];
const tags = getInnerHtml(book, 'tags');
const tagList = tags.split(';').filter(tag => {return !(tag.startsWith('_'))});
const tagFilterLinks = tagList.map((tagValue) => generateTagLink(tagValue));
@@ -267,7 +262,7 @@
}
async function getBookCount(query) {
const url = `${root}/catalog/v2/entries?${query}&count=0`;
const url = `${root}/catalog/search?${query}`;
return await fetch(url).then(async (resp) => {
const data = new window.DOMParser().parseFromString(await resp.text(), 'application/xml');
return parseInt(data.querySelector('totalResults').innerHTML);

View File

@@ -14,9 +14,6 @@ const uiLanguages = [
{
"English": "en"
},
{
"suomi": "fi"
},
{
"français": "fr"
},
@@ -26,9 +23,6 @@ const uiLanguages = [
{
"Հայերեն": "hy"
},
{
"interlingua": "ia"
},
{
"italiano": "it"
},

View File

@@ -54,22 +54,6 @@ function gotoRandomPage() {
gotoUrl(`/random?content=${currentBook}`);
}
// URI-encodes only the specified special symbols (note, however, that '%' is
// always considered a special symbol).
function quasiUriEncode(s, specialSymbols) {
if ( specialSymbols.match(/[A-Za-z0-9]/) ) {
throw "Alphanumeric symbols cannot be special";
}
// Set's guarantee of iterating in insertion order ensures that
// all %s in s will be encoded first.
for ( const c of new Set('%' + specialSymbols) ) {
s = s.replaceAll(c, encodeURIComponent(c));
}
return s;
}
function performSearch() {
const searchbox = document.getElementById('kiwixsearchbox');
const q = encodeURIComponent(searchbox.value);
@@ -220,30 +204,14 @@ function handle_visual_viewport_change() {
contentIframe.height = wh - contentIframe.offsetTop - 4;
}
function setIframeUrl(path) {
try {
// Don't do anything if we are already at the requested URL.
// This is needed to break the infinite ping-pong played by
// handle_location_hash_change() and handle_content_url_change()
// (when either top-window or content window/iframe URL changes the other
// one is updated too).
if ( path == contentIframe.contentWindow.location.pathname )
return;
} catch ( error ) {
// This happens in Firefox when a PDF file is displayed in the iframe
// (sandboxing of the iframe content and cross-origin mismatch with the
// builtin PDF viewer result in preventing access to the attributes of
// contentIframe.contentWindow.location).
// Fall through and load the requested URL.
}
contentIframe.contentWindow.location.replace(path);
}
function handle_location_hash_change() {
const hash = window.location.hash.slice(1);
console.log("handle_location_hash_change: " + hash);
updateCurrentBookIfNeeded(hash);
setIframeUrl(userUrl2IframeUrl(hash));
const iframeContentUrl = userUrl2IframeUrl(hash);
if ( iframeContentUrl != contentIframe.contentWindow.location.pathname ) {
contentIframe.contentWindow.location.replace(iframeContentUrl);
}
updateSearchBoxForLocationChange();
previousScrollTop = Infinity;
history.replaceState(viewerState, null);
@@ -275,10 +243,9 @@ function matchingAncestorElement(el, context, selector) {
const block_path = `${root}/catch/external`;
function blockLink(url) {
return viewerSettings.linkBlockingEnabled
? block_path + "?source=" + encodeURIComponent(url)
: url;
function blockLink(target) {
const encodedHref = encodeURIComponent(target.href);
target.setAttribute("href", block_path + "?source=" + encodedHref);
}
function isExternalUrl(url) {
@@ -295,14 +262,9 @@ function onClickEvent(e) {
const target = matchingAncestorElement(e.target, iframeDocument, "a");
if (target !== null && "href" in target) {
if ( isExternalUrl(target.href) ) {
const possiblyBlockedLink = blockLink(target.href);
if ( e.ctrlKey || e.shiftKey ) {
// The link will be loaded in a new tab/window - update the link
// and let the browser handle the rest.
target.setAttribute("href", possiblyBlockedLink);
} else {
// Load the external URL in the viewer window (rather than iframe)
contentIframe.contentWindow.parent.location = possiblyBlockedLink;
target.setAttribute("target", "_top");
if ( viewerSettings.linkBlockingEnabled ) {
return blockLink(target);
}
}
}
@@ -351,8 +313,8 @@ let viewerSetupComplete = false;
function on_content_load() {
if ( viewerSetupComplete ) {
handle_content_url_change();
setup_external_link_blocker();
}
setup_external_link_blocker();
}
function htmlDecode(input) {
@@ -402,13 +364,8 @@ function setupSuggestions() {
const uriEncodedBookName = encodeURIComponent(currentBook);
let url;
if (data.value.kind == "path") {
// The double quote and backslash symbols are included in the list
// of special symbols to URI-encode so that the resulting URL can
// be safely quoted inside a dynamically executed piece of
// Javascript code a few lines later.
const path = htmlDecode(data.value.path);
const quasiUriEncodedPath = quasiUriEncode(path, '#?"\\');
url = `/content/${uriEncodedBookName}/${quasiUriEncodedPath}`;
const path = encodeURIComponent(htmlDecode(data.value.path));
url = `/content/${uriEncodedBookName}/${path}`;
} else {
const pattern = encodeURIComponent(htmlDecode(data.value.value));
url = `/search?content=${uriEncodedBookName}&pattern=${pattern}`;

View File

@@ -6,7 +6,7 @@
<id>{{feed_id}}</id>
<link rel="self"
href="{{endpoint_root}}{{self_url}}"
href="{{endpoint_root}}/{{#dump_partial_entries}}partial_{{/dump_partial_entries}}entries{{{query}}}"
type="application/atom+xml;profile=opds-catalog;kind=acquisition"/>
<link rel="start"
href="{{endpoint_root}}/root.xml"

View File

@@ -32,7 +32,6 @@
articleCount="284"
mediaCount="2"
size="123"
faviconMimeType="image/png;favicon_attribute_is_absent"
></book>
<book
id="charlesray"
@@ -49,6 +48,5 @@
articleCount="284"
mediaCount="2"
size="556"
favicon="faviconMimeType_attribute_is_absent"
></book>
</library>

View File

@@ -728,7 +728,7 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_range)
const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entries?start=1&count=1");
EXPECT_EQ(r->status, 200);
EXPECT_EQ(maskVariableOPDSFeedData(r->body),
CATALOG_V2_ENTRIES_PREAMBLE("?start=1&amp;count=1")
CATALOG_V2_ENTRIES_PREAMBLE("?start=1&count=1")
" <title>Filtered Entries (start=1&amp;count=1)</title>\n"
" <updated>YYYY-MM-DDThh:mm:ssZ</updated>\n"
" <totalResults>3</totalResults>\n"
@@ -793,24 +793,6 @@ TEST_F(LibraryServerTest, catalog_v2_entries_filtered_by_language)
}
}
TEST_F(LibraryServerTest, catalog_v2_entries_multiple_filters)
{
{
const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entries?lang=fra&category=jazz");
EXPECT_EQ(r->status, 200);
EXPECT_EQ(maskVariableOPDSFeedData(r->body),
CATALOG_V2_ENTRIES_PREAMBLE("?lang=fra&amp;category=jazz")
" <title>Filtered Entries (lang=fra&amp;category=jazz)</title>\n"
" <updated>YYYY-MM-DDThh:mm:ssZ</updated>\n"
" <totalResults>1</totalResults>\n"
" <startIndex>0</startIndex>\n"
" <itemsPerPage>1</itemsPerPage>\n"
CHARLES_RAY_CATALOG_ENTRY
"</feed>\n"
);
}
}
TEST_F(LibraryServerTest, catalog_v2_individual_entry_access)
{
const auto r = zfs1_->GET("/ROOT%23%3F/catalog/v2/entry/raycharles");
@@ -1211,7 +1193,7 @@ TEST_F(LibraryServerTest, noJS) {
FILTERS_HTML("")
HOME_BODY_0_RESULTS
FINAL_HTML_TEXT);
// no_js_download
r = zfs1_->GET("/ROOT%23%3F/nojs/download/zimfile");
EXPECT_EQ(r->status, 200);

View File

@@ -63,7 +63,7 @@ const ResourceCollection resources200Compressible{
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/index.css" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/index.css?cacheid=e4d76d16" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/index.js" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/index.js?cacheid=07b06fca" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/index.js?cacheid=d38d9ef1" },
{ 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" },
@@ -73,7 +73,7 @@ const ResourceCollection resources200Compressible{
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/taskbar.css?cacheid=bbdaf425" },
{ DYNAMIC_CONTENT, "/ROOT%23%3F/skin/viewer.js" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/viewer.js?cacheid=bb748367" },
{ 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" },
@@ -147,7 +147,7 @@ const ResourceCollection resources200Uncompressible{
{ 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/languages.js" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/languages.js?cacheid=648526e1" },
{ STATIC_CONTENT, "/ROOT%23%3F/skin/languages.js?cacheid=b00b12db" },
{ ZIM_CONTENT, "/ROOT%23%3F/raw/zimfile/meta/Title" },
{ ZIM_CONTENT, "/ROOT%23%3F/raw/zimfile/meta/Description" },
@@ -285,10 +285,10 @@ R"EXPECTEDRESULT( href="/ROOT%23%3F/skin/index.css?cacheid=e4d76d16"
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=648526e1" defer></script>
<script type="text/javascript" src="/ROOT%23%3F/skin/languages.js?cacheid=b00b12db" 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=07b06fca" defer></script>
<script type="text/javascript" src="/ROOT%23%3F/skin/index.js?cacheid=d38d9ef1" defer></script>
<img src="/ROOT%23%3F/skin/feed.svg?cacheid=055b333f"
<img src="/ROOT%23%3F/skin/langSelector.svg?cacheid=00b59961"
)EXPECTEDRESULT"
@@ -311,8 +311,8 @@ R"EXPECTEDRESULT( <img src="${root}/skin/download
R"EXPECTEDRESULT( <link type="text/css" href="./skin/taskbar.css?cacheid=bbdaf425" rel="Stylesheet" />
<link type="text/css" href="./skin/css/autoComplete.css?cacheid=08951e06" rel="Stylesheet" />
<script type="module" src="./skin/i18n.js?cacheid=2cf0f8c5" defer></script>
<script type="text/javascript" src="./skin/languages.js?cacheid=648526e1" defer></script>
<script type="text/javascript" src="./skin/viewer.js?cacheid=bb748367" defer></script>
<script type="text/javascript" src="./skin/languages.js?cacheid=b00b12db" 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";
<img src="./skin/langSelector.svg?cacheid=00b59961">
@@ -497,13 +497,8 @@ TEST_F(ServerTest, MimeTypes)
{ "/skin/blank.html", "text/html" },
{ "/skin/index.css", "text/css" },
{ "/skin/index.js", "application/javascript" },
{ "/catalog/root.xml", "application/atom+xml;profile=opds-catalog;kind=acquisition;charset=utf-8" },
{ "/catalog/v2/searchdescription.xml", "application/opensearchdescription+xml" },
{ "/catalog/v2/root.xml", "application/atom+xml;profile=opds-catalog;kind=navigation;charset=utf-8" },
{ "/catalog/v2/languages", "application/atom+xml;profile=opds-catalog;kind=navigation;charset=utf-8" },
{ "/catalog/v2/categories", "application/atom+xml;profile=opds-catalog;kind=navigation;charset=utf-8" },
{ "/catalog/v2/entries", "application/atom+xml;profile=opds-catalog;kind=acquisition;charset=utf-8" },
{ "/catalog/v2/entry/6f1d19d0-633f-087b-fb55-7ac324ff9baf", "application/atom+xml;type=entry;profile=opds-catalog;charset=utf-8" },
{ "/catalog/v2/root.xml", "application/atom+xml;profile=opds-catalog;kind=navigation" },
{ "/skin/search-icon.svg", "image/svg+xml" },
{ "/skin/bittorrent.png", "image/png" },
{ "/skin/favicon/favicon.ico", "image/x-icon" },
@@ -1056,9 +1051,6 @@ R"EXPECTEDRESPONSE(const uiLanguages = [
{
"English": "en"
},
{
"suomi": "fi"
},
{
"français": "fr"
},
@@ -1068,9 +1060,6 @@ R"EXPECTEDRESPONSE(const uiLanguages = [
{
"Հայերեն": "hy"
},
{
"interlingua": "ia"
},
{
"italiano": "it"
},

View File

@@ -2,7 +2,6 @@
#define CPPHTTPLIB_ZLIB_SUPPORT 1
#include "./httplib.h"
#include "gtest/gtest.h"
#include "../src/tools/stringTools.h"
#define SERVER_PORT 8101
#include "server_testing_tools.h"
@@ -717,7 +716,7 @@ struct TestData
std::string getPattern() const
{
return kiwix::urlDecode(extractQueryValue("pattern"), true);
return extractQueryValue("pattern");
}
std::string getLang() const
@@ -1457,33 +1456,6 @@ TEST(ServerSearchTest, searchResults)
{ "", 40, false },
}
},
// Be sure that searching with accented query return the same things than non accented query.
{
/* query */ "pattern=j%C3%A0zz"
"&books.filter.lang=eng"
"&books.filter.title=Ray%20Charles",
/* start */ -1,
/* resultsPerPage */ 5,
/* totalResultCount */ 44,
/* firstResultIndex */ 1,
/* results */ {
LARGE_SEARCH_RESULTS[0],
LARGE_SEARCH_RESULTS[1],
LARGE_SEARCH_RESULTS[2],
LARGE_SEARCH_RESULTS[3],
LARGE_SEARCH_RESULTS[4],
},
/* pagination */ {
{ "1", 0, true },
{ "2", 5, false },
{ "3", 10, false },
{ "4", 15, false },
{ "5", 20, false },
{ "", 40, false },
}
},
};
ZimFileServer zfs(SERVER_PORT, ZimFileServer::DEFAULT_OPTIONS,