Wed, 08 Jul 2020 18:12:32 -0700
6 |
--------------------------------------------------------------------------------
/debian/rules:
--------------------------------------------------------------------------------
1 | #!/usr/bin/make -f
2 | export DEB_BUILD_MAINT_OPTIONS = hardening=+all
3 |
4 | %:
5 | dh $@ --buildsystem=meson
6 |
7 | override_dh_auto_test:
8 | dh_auto_test -- -t 3
9 |
--------------------------------------------------------------------------------
/.codecov.yml:
--------------------------------------------------------------------------------
1 | codecov:
2 | notify:
3 | require_ci_to_pass: yes
4 |
5 | coverage:
6 | status:
7 | project:
8 | default:
9 | threshold: 1%
10 |
11 | ignore:
12 | - "test"
13 |
--------------------------------------------------------------------------------
/static/templates/viewer_settings.js:
--------------------------------------------------------------------------------
1 | const viewerSettings = {
2 | toolbarEnabled: {{enable_toolbar}},
3 | linkBlockingEnabled: {{enable_link_blocking}},
4 | libraryButtonEnabled: {{enable_library_button}}
5 | }
6 |
--------------------------------------------------------------------------------
/meson_options.txt:
--------------------------------------------------------------------------------
1 | option('static-linkage', type : 'boolean', value : false,
2 | description : 'Link statically with the dependencies.')
3 | option('doc', type : 'boolean', value : false,
4 | description : 'Build the documentations.')
5 |
--------------------------------------------------------------------------------
/docs/meson.build:
--------------------------------------------------------------------------------
1 |
2 | sphinx = find_program('sphinx-build', native:true)
3 |
4 | sphinx_target = run_target('doc',
5 | command: [sphinx, '-bhtml',
6 | meson.current_source_dir(),
7 | meson.current_build_dir()])
8 |
--------------------------------------------------------------------------------
/static/skin/blank.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Blank page
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/static/templates/suggestion.json:
--------------------------------------------------------------------------------
1 | [
2 | {{#suggestions}}{{^first}},{{/first}}
3 | {
4 | "value" : "{{value}}",
5 | "label" : "{{label}}",
6 | "kind" : "{{kind}}"
7 | {{#path}}
8 | , "path" : "{{path}}"
9 | {{/path}}
10 | }{{/suggestions}}
11 | ]
12 |
--------------------------------------------------------------------------------
/static/templates/catalog_v2_partial_entry.xml:
--------------------------------------------------------------------------------
1 |
2 | urn:uuid:{{id}}
3 | {{title}}
4 | {{updated}}
5 |
8 |
9 |
--------------------------------------------------------------------------------
/include/meson.build:
--------------------------------------------------------------------------------
1 | headers = [
2 | 'book.h',
3 | 'bookmark.h',
4 | 'common.h',
5 | 'library.h',
6 | 'manager.h',
7 | 'downloader.h',
8 | 'search_renderer.h',
9 | 'server.h',
10 | 'kiwixserve.h',
11 | 'name_mapper.h',
12 | 'tools.h',
13 | 'version.h',
14 | 'i18n.h'
15 | ]
16 |
17 | install_headers(headers, subdir:'kiwix')
18 |
--------------------------------------------------------------------------------
/scripts/format_code.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/bash
2 |
3 | # Compute 'src' path
4 | SCRIPT_DIR=$(dirname "$0")
5 | REPO_DIR=$(readlink -f "$SCRIPT_DIR"/..)
6 | DIRS="src include"
7 |
8 | # Apply formating to all *.cpp and *.h files
9 | cd "$REPO_DIR"
10 | for FILE in $(find $DIRS -name '*.h' -o -name '*.cpp')
11 | do
12 | echo $FILE
13 | clang-format -i -style=file "$FILE"
14 | done
15 |
--------------------------------------------------------------------------------
/.clang-format:
--------------------------------------------------------------------------------
1 | BasedOnStyle: Google
2 | BinPackArguments: false
3 | BinPackParameters: false
4 | BreakBeforeBinaryOperators: All
5 | BreakBeforeBraces: Linux
6 | DerivePointerAlignment: false
7 | SpacesInContainerLiterals: false
8 | Standard: Cpp11
9 |
10 | AllowShortFunctionsOnASingleLine: Inline
11 | AllowShortIfStatementsOnASingleLine: false
12 | AllowShortLoopsOnASingleLine: false
13 |
--------------------------------------------------------------------------------
/test/kiwixserve.cpp:
--------------------------------------------------------------------------------
1 | #include "gtest/gtest.h"
2 | #include "../include/kiwixserve.h"
3 |
4 | TEST(KiwixServeTest, PortTest)
5 | {
6 | kiwix::KiwixServe kiwixServe("libraryPath", 8181);
7 | EXPECT_EQ(kiwixServe.getPort(), 8181);
8 | kiwixServe.setPort(8484);
9 | EXPECT_EQ(kiwixServe.getPort(), 8484);
10 | EXPECT_EQ(kiwixServe.setPort(0), -1);
11 | EXPECT_EQ(kiwixServe.setPort(3456789), -1);
12 | }
13 |
--------------------------------------------------------------------------------
/test/data/customized_resources.txt:
--------------------------------------------------------------------------------
1 | /non-existent-item text/plain ./test/helloworld.txt
2 | / text/html ./test/welcome.html
3 | /skin/index.css application/json ./test/helloworld.txt
4 | /zimfile/A/Ray_Charles ray/charles ./test/welcome.html
5 | /content/zimfile/A/Ray_Charles charles/ray ./test/welcome.html
6 | /search text/html ./test/helloworld.txt
7 |
--------------------------------------------------------------------------------
/docs/index.rst:
--------------------------------------------------------------------------------
1 | .. libkiwix documentation master file, created by
2 | sphinx-quickstart on Fri Jul 24 15:40:50 2020.
3 | You can adapt this file completely to your liking, but it should at least
4 | contain the root `toctree` directive.
5 |
6 | Welcome to libkiwix's documentation!
7 | ==================================
8 |
9 | .. toctree::
10 | :maxdepth: 2
11 | :caption: Contents:
12 |
13 | usage
14 | api/ref_api
15 |
--------------------------------------------------------------------------------
/scripts/meson.build:
--------------------------------------------------------------------------------
1 |
2 | res_manager = find_program('kiwix-resources')
3 | res_compiler = find_program('kiwix-compile-resources')
4 |
5 | install_data(res_compiler.path(), install_dir:get_option('bindir'))
6 |
7 | install_man('kiwix-compile-resources.1')
8 |
9 | i18n_compiler = find_program('kiwix-compile-i18n')
10 |
11 | install_data(i18n_compiler.path(), install_dir:get_option('bindir'))
12 |
13 | install_man('kiwix-compile-i18n.1')
14 |
--------------------------------------------------------------------------------
/test/data/corner_cases/c#.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | C#
6 |
7 |
8 | C# (pronounced see sharp) is a general-purpose, high-level multi-paradigm programming language. C# encompasses static typing, strong typing, lexically scoped, imperative, declarative, functional, generic, object-oriented (class-based), and component-oriented programming disciplines
9 |
10 |
11 |
--------------------------------------------------------------------------------
/subprojects/gtest.wrap:
--------------------------------------------------------------------------------
1 | [wrap-file]
2 | directory = googletest-release-1.8.1
3 |
4 | source_url = https://github.com/google/googletest/archive/release-1.8.1.zip
5 | source_filename = gtest-1.8.1.zip
6 | source_hash = 927827c183d01734cc5cfef85e0ff3f5a92ffe6188e0d18e909c5efebf28a0c7
7 |
8 | patch_url = https://wrapdb.mesonbuild.com/v1/projects/gtest/1.8.1/1/get_zip
9 | patch_filename = gtest-1.8.1-1-wrap.zip
10 | patch_hash = f79f5fd46e09507b3f2e09a51ea6eb20020effe543335f5aee59f30cc8d15805
11 |
--------------------------------------------------------------------------------
/docs/usage.rst:
--------------------------------------------------------------------------------
1 | Libkiwix programming
2 | ====================
3 |
4 | Introduction
5 | ------------
6 |
7 | libkiwix is written in C++. To use the library, you need the include files of libkiwix have
8 | to link against libzim.
9 |
10 | Errors are handled with exceptions. When something goes wrong, libkiwix throws an error,
11 | which is always derived from std::exception.
12 |
13 | All classes are defined in the namespace kiwix.
14 |
15 | libkiwix is a set of tools to manage zim files and provide some common functionnality.
16 |
--------------------------------------------------------------------------------
/static/skin/favicon/site.webmanifest:
--------------------------------------------------------------------------------
1 | {
2 | "name": "",
3 | "short_name": "",
4 | "icons": [
5 | {
6 | "src": "android-chrome-192x192.png",
7 | "sizes": "192x192",
8 | "type": "image/png"
9 | },
10 | {
11 | "src": "android-chrome-512x512.png",
12 | "sizes": "512x512",
13 | "type": "image/png"
14 | }
15 | ],
16 | "theme_color": "#ffffff",
17 | "background_color": "#ffffff",
18 | "display": "standalone"
19 | }
20 |
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | daysUntilClose: false
2 | staleLabel: stale
3 |
4 | issues:
5 | daysUntilStale: 60
6 | markComment: >
7 | This issue has been automatically marked as stale because it has not had
8 | recent activity. It will be now be reviewed manually. Thank you
9 | for your contributions.
10 | pulls:
11 | daysUntilStale: 7
12 | markComment: >
13 | This pull request has been automatically marked as stale because it has not had
14 | recent activity. It will be now be reviewed manually. Thank you
15 | for your contributions.
16 |
--------------------------------------------------------------------------------
/static/skin/download-white.svg:
--------------------------------------------------------------------------------
1 |
2 |
7 |
--------------------------------------------------------------------------------
/scripts/kiwix-compile-i18n.1:
--------------------------------------------------------------------------------
1 | .TH KIWIX-COMPILE-I18N "1" "January 2022" "Kiwix" "User Commands"
2 | .SH NAME
3 | kiwix-compile-i18n \- helper to compile Kiwix i18n (internationalization) data
4 | .SH SYNOPSIS
5 | \fBkiwix\-compile\-i18n\fR [\-h] \-\-cxxfile CXXFILE i18n_resource_files ...\fR
6 | .SH DESCRIPTION
7 | .TP
8 | i18n_resource_files ...
9 | The list of i18n resources to compile.
10 | .TP
11 | \fB\-h\fR, \fB\-\-help\fR
12 | show a help message and exit
13 | .TP
14 | \fB\-\-cxxfile\fR CXXFILE
15 | The Cpp file name to generate
16 | .TP
17 | .SH AUTHOR
18 | Veloman Yunkan
19 |
--------------------------------------------------------------------------------
/static/skin/favicon/browserconfig.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | #da532c
11 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/include/common.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef _KIWIX_COMMON_H_
3 | #define _KIWIX_COMMON_H_
4 |
5 | #include
6 |
7 | #ifdef __GNUC__
8 | #define DEPRECATED __attribute__((deprecated))
9 | #elif defined(_MSC_VER)
10 | #define DEPRECATED __declspec(deprecated)
11 | #else
12 | #praga message("WARNING: You need to implement DEPRECATED for this compiler")
13 | #define DEPRECATED
14 | #endif
15 |
16 |
17 | namespace kiwix {
18 |
19 | enum class IpMode { IPV4, IPV6, ALL, AUTO }; // AUTO: Server decides the protocol
20 | typedef zim::size_type size_type;
21 | typedef zim::offset_type offset_type;
22 |
23 | }
24 |
25 | #endif //_KIWIX_COMMON_H_
26 |
--------------------------------------------------------------------------------
/.readthedocs.yaml:
--------------------------------------------------------------------------------
1 | # Read the Docs configuration file
2 | # See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
3 |
4 | # Required
5 | version: 2
6 |
7 | # Set the version of Python and other tools you might need
8 | build:
9 | os: ubuntu-22.04
10 | tools:
11 | python: "3.11"
12 |
13 | # Build documentation in the docs/ directory with Sphinx
14 | sphinx:
15 | configuration: docs/conf.py
16 |
17 | # We recommend specifying your dependencies to enable reproducible builds:
18 | # https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
19 | python:
20 | install:
21 | - requirements: docs/requirements.txt
22 |
--------------------------------------------------------------------------------
/src/subprocess_unix.h:
--------------------------------------------------------------------------------
1 | #ifndef KIWIX_SUBPROCESS_UNIX_H_
2 | #define KIWIX_SUBPROCESS_UNIX_H_
3 |
4 | #include "subprocess.h"
5 |
6 | #include
7 | #include
8 |
9 | class UnixImpl : public SubprocessImpl
10 | {
11 | private:
12 | int m_pid;
13 | std::atomic m_running;
14 | std::atomic m_shouldQuit;
15 | std::thread m_waitingThread;
16 |
17 | public:
18 | UnixImpl();
19 | virtual ~UnixImpl();
20 |
21 | void run(commandLine_t& commandLine);
22 | bool kill();
23 | bool isRunning();
24 |
25 | static void* waitForPID(void* self);
26 | };
27 |
28 | #endif //KIWIX_SUBPROCESS_UNIX_H_
29 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: kiwix
4 | patreon: # Replace with a single Patreon username
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # https://kiwix.org/support-us/
13 |
--------------------------------------------------------------------------------
/static/opensearchdescription.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Zim catalog search
4 | Search zim files in the catalog.
5 |
10 |
11 |
--------------------------------------------------------------------------------
/scripts/kiwix-compile-resources.1:
--------------------------------------------------------------------------------
1 | .TH KIWIX-COMPILE-RESOURCES "1" "August 2017" "Kiwix" "User Commands"
2 | .SH NAME
3 | kiwix-compile-resources \- helper to compile and generate some Kiwix resources
4 | .SH SYNOPSIS
5 | \fBkiwix\-compile\-resources\fR [\-h] [\-\-cxxfile CXXFILE] [\-\-hfile HFILE] resource_file ...\fR
6 | .SH DESCRIPTION
7 | .TP
8 | resource_file
9 | The list of resources to compile.
10 | .TP
11 | \fB\-h\fR, \fB\-\-help\fR
12 | show a help message and exit
13 | .TP
14 | \fB\-\-cxxfile\fR CXXFILE
15 | The Cpp file name to generate
16 | .TP
17 | \fB\-\-hfile\fR HFILE
18 | The h file name to generate
19 | .SH AUTHOR
20 | Matthieu Gautier
21 |
--------------------------------------------------------------------------------
/static/catalog_v2_searchdescription.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Zim catalog search
4 | Search zim files in the catalog.
5 |
10 |
11 |
--------------------------------------------------------------------------------
/AUTHORS:
--------------------------------------------------------------------------------
1 | Automactic
2 | Ayoub DARDORY
3 | Cristian Patrasciuc
4 | Dattaz
5 | Elad Keyshawn
6 | Emmanuel Engelhart
7 | Isaac
8 | jleow00
9 | Julian Harty
10 | Kiran Mathew Koshy
11 | Kunal Mehta
12 | Matthieu Gautier
13 | Rashiq Ahmad
14 | Renaud Gaudin
15 | Shivam
16 | Steve Wills
17 | Synhershko
18 |
--------------------------------------------------------------------------------
/static/ft_opensearchdescription.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | Fulltext articles search
4 | Search for articles in the Library.
5 |
10 |
11 |
--------------------------------------------------------------------------------
/include/kiwixserve.h:
--------------------------------------------------------------------------------
1 | #ifndef KIWIXLIB_KIWIX_SERVE_H_
2 | #define KIWIXLIB_KIWIX_SERVE_H_
3 |
4 | #include
5 | #include
6 |
7 | class Subprocess;
8 | namespace kiwix {
9 |
10 | class KiwixServe
11 | {
12 | public:
13 | KiwixServe(const std::string& libraryPath, int port = 8181);
14 | ~KiwixServe();
15 |
16 | void run();
17 | void shutDown();
18 | bool isRunning();
19 | int getPort() { return m_port; }
20 | int setPort(int port);
21 |
22 | private:
23 | std::unique_ptr mp_kiwixServe;
24 | int m_port;
25 | std::string m_libraryPath;
26 | };
27 |
28 | }; //end namespace kiwix
29 |
30 | #endif // KIWIXLIB_KIWIX_SERVE_H_
31 |
--------------------------------------------------------------------------------
/src/subprocess_windows.h:
--------------------------------------------------------------------------------
1 | #ifndef KIWIX_SUBPROCESS_WINDOWS_H_
2 | #define KIWIX_SUBPROCESS_WINDOWS_H_
3 |
4 | #include "subprocess.h"
5 |
6 | #include
7 | #include
8 |
9 | class WinImpl : public SubprocessImpl
10 | {
11 | private:
12 | int m_pid;
13 | bool m_running;
14 | HANDLE m_subprocessHandle;
15 | HANDLE m_waitingThreadHandle;
16 | CRITICAL_SECTION m_criticalSection;
17 |
18 | public:
19 | WinImpl();
20 | virtual ~WinImpl();
21 |
22 | void run(commandLine_t& commandLine);
23 | bool kill();
24 | bool isRunning();
25 |
26 | static DWORD WINAPI waitForPID(void* self);
27 | };
28 |
29 | #endif //KIWIX_SUBPROCESS_WINDOWS_H_
30 |
--------------------------------------------------------------------------------
/static/skin/i18n/ms.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "Tofeiku"
5 | ]
6 | },
7 | "name": "Bahasa Melayu",
8 | "404-page-heading": "Tidak Dijumpai",
9 | "500-page-title": "Ralat Pelayan Dalaman",
10 | "500-page-heading": "Ralat Pelayan Dalaman",
11 | "library-button-text": "Pergi ke laman selamat datang",
12 | "searchbox-tooltip": "Cari '{{BOOK_TITLE}}'",
13 | "search": "Cari",
14 | "book-filtering-all-categories": "Semua kategori",
15 | "book-filtering-all-languages": "Semua bahasa",
16 | "download": "Muat turun",
17 | "direct-download-link-text": "Langsung",
18 | "direct-download-alt-text": "muat turun langsung",
19 | "download-links-title": "Muat turun buku"
20 | }
21 |
--------------------------------------------------------------------------------
/static/templates/error.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | {{PAGE_TITLE}}
6 | {{#CSS_URL}}
7 |
8 | {{/CSS_URL}}{{#KIWIX_RESPONSE_DATA}} {{/KIWIX_RESPONSE_DATA}}
12 |
13 |
14 | {{PAGE_HEADING}}
15 | {{#details}}
16 |
17 | {{{p}}}
18 |
19 | {{/details}}
20 |
21 |
22 |
--------------------------------------------------------------------------------
/static/skin/i18n/dga.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "Alhaji Yakubu"
5 | ]
6 | },
7 | "welcome-page-overzealous-filter": "Duoro kyebe. E na boɔra ka fo?",
8 | "search": "Bo",
9 | "book-filtering-all-categories": "Zagre zaa",
10 | "book-filtering-all-languages": "Kɔkɔrɛɛ zaa",
11 | "count-of-matching-books": "{{COUNT}} gama",
12 | "download": "Tagebo",
13 | "direct-download-link-text": "Toribu",
14 | "direct-download-alt-text": "Toribu tagebo",
15 | "hash-download-alt-text": "Tage bonmannaa",
16 | "magnet-link-text": "Kurimaraa sobie",
17 | "magnet-alt-text": "Tage kurimaraa",
18 | "filter-by-tag": "Guy yi kpuli {{TAG}}",
19 | "stop-filtering-by-tag": "Bare gyɛɛbo kpuli {{TAG}}"
20 | }
21 |
--------------------------------------------------------------------------------
/static/templates/catalog_entries.xml:
--------------------------------------------------------------------------------
1 |
4 | {{feed_id}}
5 | {{^filter}}All zims{{/filter}}{{#filter}}Filtered zims ({{filter}}){{/filter}}
6 | {{date}}
7 | {{#filter}}
8 | {{totalResults}}
9 | {{startIndex}}
10 | {{itemsPerPage}}
11 | {{/filter}}
12 |
13 |
14 | {{#books}}{{{entry}}}{{/books}}
15 |
--------------------------------------------------------------------------------
/test/data/lib_for_server_search_test.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/static/navigation_feed.tmpl:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{id}}
4 |
7 |
10 | {{title}}
11 | {{updated}}
12 |
13 | {{author_name}}
14 | {{author_uri}}
15 |
16 |
17 | {{#entries}}
18 |
19 | {{title}}
20 |
23 | {{updated}}
24 | {{id}}
25 |
26 | {{/entries}}
27 |
28 |
--------------------------------------------------------------------------------
/src/subprocess.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef KIWIX_SUBPROCESS_H_
3 | #define KIWIX_SUBPROCESS_H_
4 |
5 | #include
6 | #include
7 | #include
8 |
9 | typedef std::vector commandLine_t;
10 |
11 | class SubprocessImpl
12 | {
13 | public:
14 | virtual void run(commandLine_t& commandLine) = 0;
15 | virtual bool kill() = 0;
16 | virtual bool isRunning() = 0;
17 | virtual ~SubprocessImpl() = default;
18 | };
19 |
20 | class Subprocess
21 | {
22 | private:
23 | // Impl depends of the system (window, unix, ...)
24 | std::unique_ptr mp_impl;
25 | Subprocess(std::unique_ptr impl, commandLine_t& commandLine);
26 |
27 | public:
28 | static std::unique_ptr run(commandLine_t& commandLine);
29 | ~Subprocess();
30 |
31 | bool isRunning();
32 | bool kill();
33 | };
34 |
35 |
36 | #endif // KIWIX_SUBPROCESS_H_
37 |
--------------------------------------------------------------------------------
/src/subprocess.cpp:
--------------------------------------------------------------------------------
1 |
2 |
3 | #include "subprocess.h"
4 |
5 | #ifdef _WIN32
6 | # include "subprocess_windows.h"
7 | #else
8 | # include "subprocess_unix.h"
9 | #endif
10 |
11 | Subprocess::Subprocess(std::unique_ptr impl, commandLine_t& commandLine) :
12 | mp_impl(std::move(impl))
13 | {
14 | mp_impl->run(commandLine);
15 | }
16 |
17 | Subprocess::~Subprocess()
18 | {
19 | mp_impl->kill();
20 | }
21 |
22 | std::unique_ptr Subprocess::run(commandLine_t& commandLine)
23 | {
24 | #ifdef _WIN32
25 | auto impl = std::unique_ptr(new WinImpl);
26 | #else
27 | auto impl = std::unique_ptr(new UnixImpl);
28 | #endif
29 | return std::unique_ptr(new Subprocess(std::move(impl), commandLine));
30 | }
31 |
32 | bool Subprocess::isRunning()
33 | {
34 | return mp_impl->isRunning();
35 | }
36 |
37 | bool Subprocess::kill()
38 | {
39 | return mp_impl->kill();
40 | }
41 |
--------------------------------------------------------------------------------
/include/kiwix.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Emmanuel Engelhart
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #ifndef KIWIX_H
21 | #define KIWIX_H
22 |
23 | #include "library.h"
24 |
25 | #endif
26 |
--------------------------------------------------------------------------------
/src/server/microhttpd_wrapper.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2020 Emmanuel Engelhart
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #include
21 |
22 | #if MHD_VERSION < 0x00097002
23 | typedef int MHD_Result;
24 | #endif
25 |
--------------------------------------------------------------------------------
/static/templates/catalog_v2_categories.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | {{feed_id}}
5 |
8 |
11 | List of categories
12 | {{date}}
13 |
14 | {{#categories}}
15 |
16 | {{name}}
17 |
20 | {{updated}}
21 | {{id}}
22 | All entries with category of '{{name}}'.
23 |
24 | {{/categories}}
25 |
26 |
--------------------------------------------------------------------------------
/src/tools/networkTools.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2012 Emmanuel Engelhart
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #ifndef KIWIX_NETWORKTOOLS_H
21 | #define KIWIX_NETWORKTOOLS_H
22 |
23 | #include
24 |
25 | namespace kiwix
26 | {
27 | std::string download(const std::string& url);
28 | }
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/static/templates/sexy500.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{PAGE_TITLE}}
7 |
8 |
12 |
13 |
14 |
15 |
19 |
20 |
21 | {{PAGE_HEADING}}
22 | {{PAGE_TEXT}}
23 | {{url_path}}
24 |
25 | {{#error}}
26 |
29 | {{/error}}
30 |
31 |
32 |
--------------------------------------------------------------------------------
/static/templates/no_js_download.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | {{translations.download-links-title}}
8 |
9 |
16 |
17 |
18 | {{{translations.download-links-heading}}}
19 |
20 |
21 | {{translations.direct-download-link-text}}
22 |
23 |
24 | {{translations.hash-download-link-text}}
25 |
26 |
27 | {{translations.magnet-link-text}}
28 |
29 |
30 | {{translations.torrent-download-link-text}}
31 |
32 |
33 |
--------------------------------------------------------------------------------
/include/opds_catalog.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Veloman Yunkan
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #ifndef KIWIX_OPDS_CATALOG_H
21 | #define KIWIX_OPDS_CATALOG_H
22 |
23 |
24 | #include "library.h"
25 |
26 | namespace kiwix
27 | {
28 |
29 | std::string getSearchUrl(const Filter& f);
30 |
31 | } // namespace kiwix
32 |
33 | #endif // KIWIX_OPDS_CATALOG_H
34 |
--------------------------------------------------------------------------------
/static/i18n_resources_list.txt:
--------------------------------------------------------------------------------
1 | skin/i18n/ar.json
2 | skin/i18n/bn.json
3 | skin/i18n/br.json
4 | skin/i18n/cs.json
5 | skin/i18n/dag.json
6 | skin/i18n/de.json
7 | skin/i18n/dga.json
8 | skin/i18n/el.json
9 | skin/i18n/en.json
10 | skin/i18n/es.json
11 | skin/i18n/fi.json
12 | skin/i18n/fr.json
13 | skin/i18n/ha.json
14 | skin/i18n/he.json
15 | skin/i18n/hi.json
16 | skin/i18n/hu.json
17 | skin/i18n/hy.json
18 | skin/i18n/ia.json
19 | skin/i18n/id.json
20 | skin/i18n/ig.json
21 | skin/i18n/it.json
22 | skin/i18n/ja.json
23 | skin/i18n/ko.json
24 | skin/i18n/ku-latn.json
25 | skin/i18n/lb.json
26 | skin/i18n/mk.json
27 | skin/i18n/ms.json
28 | skin/i18n/nb.json
29 | skin/i18n/nl.json
30 | skin/i18n/nqo.json
31 | skin/i18n/or.json
32 | skin/i18n/pl.json
33 | skin/i18n/pt-br.json
34 | skin/i18n/pt.json
35 | skin/i18n/ro.json
36 | skin/i18n/ru.json
37 | skin/i18n/sc.json
38 | skin/i18n/sk.json
39 | skin/i18n/skr-arab.json
40 | skin/i18n/sl.json
41 | skin/i18n/sq.json
42 | skin/i18n/sv.json
43 | skin/i18n/sw.json
44 | skin/i18n/te.json
45 | skin/i18n/test.json
46 | skin/i18n/tr.json
47 | skin/i18n/zh-hans.json
48 | skin/i18n/zh-hant.json
49 |
--------------------------------------------------------------------------------
/static/templates/catalog_v2_entries.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 | {{feed_id}}
7 |
8 |
11 |
14 |
17 |
18 | {{^filter}}All Entries{{/filter}}{{#filter}}Filtered Entries ({{filter}}){{/filter}}
19 | {{date}}
20 | {{#filter}}
21 | {{totalResults}}
22 | {{startIndex}}
23 | {{itemsPerPage}}
24 | {{/filter}}
25 | {{#books}}{{{entry}}}{{/books}}
26 |
--------------------------------------------------------------------------------
/static/skin/i18n/ja.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "MathXplore",
5 | "もなー(偽物)"
6 | ]
7 | },
8 | "name": "日本語",
9 | "no-query": "クエリを指定していません。",
10 | "400-page-title": "無効なリクエストです",
11 | "400-page-heading": "無効なリクエストです",
12 | "404-page-title": "コンテンツが見つかりませんでした",
13 | "404-page-heading": "見つかりません",
14 | "500-page-title": "内部サーバーエラー",
15 | "500-page-heading": "内部サーバーエラー",
16 | "fulltext-search-unavailable": "全文検索は利用できません",
17 | "no-search-results": "このコンテンツでは全文検索エンジンが利用できません",
18 | "library-button-text": "ウェルカムページに移動",
19 | "random-page-button-text": "無作為に選ばれたページに移動する",
20 | "search": "検索",
21 | "book-filtering-all-categories": "すべてのカテゴリー",
22 | "book-filtering-all-languages": "すべての言語",
23 | "download": "ダウンロード",
24 | "direct-download-link-text": "直ダウンロードリンク",
25 | "direct-download-alt-text": "直ダウンロード",
26 | "hash-download-link-text": "Sha256 ハッシュ",
27 | "hash-download-alt-text": "ハッシュをダウンロード",
28 | "magnet-link-text": "マグネットリンク",
29 | "magnet-alt-text": "マグネットをダウンロード",
30 | "torrent-download-link-text": "Torrentファイル",
31 | "torrent-download-alt-text": "Torrentをダウンロード",
32 | "preview-book": "プレビュー"
33 | }
34 |
--------------------------------------------------------------------------------
/static/templates/catalog_v2_languages.xml:
--------------------------------------------------------------------------------
1 |
2 |
6 | {{feed_id}}
7 |
10 |
13 | List of languages
14 | {{date}}
15 |
16 | {{#languages}}
17 |
18 | {{lang_self_name}}
19 | {{{lang_code}}}
20 | {{book_count}}
21 |
24 | {{updated}}
25 | {{id}}
26 |
27 | {{/languages}}
28 |
29 |
--------------------------------------------------------------------------------
/static/templates/catalog_v2_entry.xml:
--------------------------------------------------------------------------------
1 |
2 | urn:uuid:{{id}}
3 | {{title}}
4 | {{updated}}
5 | {{description}}
6 | {{language}}
7 | {{name}}
8 | {{flavour}}
9 | {{category}}
10 | {{tags}}
11 | {{article_count}}
12 | {{media_count}}
13 | {{#icons}}
16 | {{/icons}}
17 |
18 | {{author_name}}
19 |
20 |
21 | {{publisher_name}}
22 |
23 | {{book_date}}
24 | {{#url}}
25 |
26 | {{/url}}
27 |
28 |
--------------------------------------------------------------------------------
/static/skin/polyfills.js:
--------------------------------------------------------------------------------
1 | // A few browsers do not support the use of String.prototype.replaceAll method.
2 | // Hence we define it once we verify that it isn't supported. For documentation
3 | // see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll
4 | if (!String.prototype.replaceAll) {
5 | String.prototype.replaceAll = function (pattern, replacement) {
6 | // verify parameter: It must either be a string or a RegExp with a global flag.
7 | if (typeof pattern[Symbol.replace] === 'function') {
8 | // the pattern is a RegExp check for the presence of g flag.
9 | if (pattern.global) {
10 | return this.replace(pattern, replacement);
11 | } else {
12 | throw new TypeError('Global flag for regular expressions')
13 | }
14 | }
15 | // the pattern is not a RegExp, hence it must be a string.
16 | if (typeof pattern !== 'string') {
17 | throw new TypeError('pattern must either be a string or a RegExp with a global (g) flag.')
18 | }
19 | return this.replace(new RegExp(pattern, 'g'), replacement);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/static/skin/search-icon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/src/tools/regexTools.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Emmanuel Engelhart
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #ifndef KIWIX_REGEXTOOLS_H
21 | #define KIWIX_REGEXTOOLS_H
22 |
23 | #include
24 |
25 | bool matchRegex(const std::string& content, const std::string& regex);
26 | std::string replaceRegex(const std::string& content,
27 | const std::string& replacement,
28 | const std::string& regex);
29 |
30 | #endif
31 |
--------------------------------------------------------------------------------
/static/skin/feed.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
23 |
--------------------------------------------------------------------------------
/include/version.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Emmanuel Engelhart
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #ifndef KIWIX_VERSION_H
21 | #define KIWIX_VERSION_H
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | namespace kiwix
28 | {
29 | typedef std::vector> LibVersions;
30 | LibVersions getVersions();
31 | void printVersions(std::ostream& out = std::cout);
32 | }
33 |
34 | #endif // KIWIX_VERSION_H
35 |
--------------------------------------------------------------------------------
/static/templates/captured_external.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{external_link_detected}}
7 |
8 |
9 |
13 |
14 |
15 |
16 |
20 |
21 |
22 | {{external_link_detected}}
23 | {{external_link_intro}}
24 | {{ url }}
25 |
26 |
27 | {{advice.p1}}
28 | {{advice.p2}}
29 | {{advice.p3}}
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/static/templates/sexy404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | {{PAGE_TITLE}}
7 |
8 | {{#KIWIX_RESPONSE_DATA}} {{/KIWIX_RESPONSE_DATA}}
12 |
13 |
14 |
15 |
19 |
20 |
21 | {{PAGE_HEADING}}
22 | {{path_was_not_found_msg}}
23 | {{url_path}}
24 |
25 |
26 | {{advice.p1}}
27 | {{advice.p2}}
28 |
29 | - {{advice.p3}}
30 | - {{advice.p4}}
31 |
32 | {{advice.p5}}
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/static/skin/i18n/hy.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "Kareyac"
5 | ]
6 | },
7 | "name": "Հայերեն",
8 | "suggest-full-text-search": "որոնել '{{{SEARCH_TERMS}}}'...",
9 | "no-such-book": "Գիրքը բացակայում է՝ {{BOOK_NAME}}",
10 | "url-not-found": "Սխալ հասցե՝ {{url}}",
11 | "suggest-search": "Որոնել {{PATTERN}}",
12 | "400-page-title": "Անվավեր հարցում",
13 | "400-page-heading": "Անվավեր հարցում",
14 | "404-page-title": "Սխալ հասցե",
15 | "404-page-heading": "Սխալ հասցե",
16 | "500-img-text": "Էջը չի աշխատում",
17 | "library-button-text": "Գրադարանի էջ",
18 | "home-button-text": "Դեպի '{{BOOK_TITLE}}'֊ի գլխավոր էջը",
19 | "random-page-button-text": "Բացել պատահական էջ",
20 | "searchbox-tooltip": "Որոնել '{{BOOK_TITLE}}'֊ում",
21 | "book-filtering-all-categories": "Բոլոր կատեգորիաներ",
22 | "book-category.wikibooks": "Վիքիգրքեր",
23 | "book-category.wikinews": "Վիքիլուրեր",
24 | "book-category.wikipedia": "Վիքիպեդիա",
25 | "book-category.wikiquote": "Վիքիքաղվածք",
26 | "book-category.wikisource": "Վիքիդարան",
27 | "book-category.wikispecies": "Վիքիցեղեր",
28 | "book-category.wikiversity": "Վիքիլսարան",
29 | "book-category.wikivoyage": "Վիքիճամփորդ",
30 | "book-category.wiktionary": "Վիքիբառարան",
31 | "book-category.other": "Այլ"
32 | }
33 |
--------------------------------------------------------------------------------
/src/aria2.h:
--------------------------------------------------------------------------------
1 |
2 |
3 | #ifndef KIWIXLIB_ARIA2_H_
4 | #define KIWIXLIB_ARIA2_H_
5 |
6 | #ifdef _WIN32
7 | // winsock2.h need to be included before windows.h (included by curl.h)
8 | # include
9 | #endif
10 |
11 | #include "subprocess.h"
12 | #include "xmlrpc.h"
13 |
14 | #include
15 | #include
16 |
17 | namespace kiwix {
18 |
19 | class Aria2
20 | {
21 | private:
22 | std::unique_ptr mp_aria;
23 | int m_port;
24 | std::string m_secret;
25 | std::string doRequest(const MethodCall& methodCall);
26 |
27 | public:
28 | explicit Aria2(std::string sessionFileDir);
29 | virtual ~Aria2() = default;
30 | void close();
31 |
32 | std::string addUri(const std::vector& uri, const std::vector>& options = {});
33 | std::string tellStatus(const std::string& gid, const std::vector& statusKey);
34 | static std::string getNewRpcSecret();
35 | std::vector tellActive();
36 | std::vector tellWaiting();
37 | void saveSession();
38 | void shutdown();
39 | void pause(const std::string& gid);
40 | void unpause(const std::string& gid);
41 | void remove(const std::string& gid);
42 | };
43 |
44 | }; //end namespace kiwix
45 |
46 | #endif // KIWIXLIB_ARIA2_H_
47 |
--------------------------------------------------------------------------------
/test/data/create_corner_cases_zim_file:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | cd "$(dirname "$0")"
4 |
5 | # The following symbols (that would be nice to include in testing) are not
6 | # allowed under NTFS and/or FAT32 filesystems, and would result in the
7 | # impossibility to git clone (or rather checkout) the libkiwix repository under
8 | # Windows:
9 | #
10 | # ?
11 | # =
12 | # + (that's a pity, since the + symbol in a ZIM filename is replaced with the
13 | # text 'plus' when the ZIM file is added to kiwix-serve's library and it
14 | # would be nice to test that functionality)
15 | #
16 | # Assuming that tests are NOT run under Windows, above symbols can be included
17 | # in testing if the file is renamed while copying to the build directory (see
18 | # test/meson.build), though that would make maintenance slightly more confusing.
19 | zimfilename='corner_cases#&.zim'
20 |
21 | rm -f "$zimfilename"
22 | zimwriterfs --withoutFTIndex --dont-check-arguments \
23 | -w empty.html \
24 | -I empty.png \
25 | -l en \
26 | -t "ZIM corner cases" \
27 | -d "" \
28 | -c "" \
29 | -p "" \
30 | corner_cases \
31 | "$zimfilename" \
32 | && echo "$zimfilename was successfully created" \
33 | || echo '!!! Failed to create' "$zimfilename" '!!!' >&2
34 |
--------------------------------------------------------------------------------
/static/skin/search_results.css:
--------------------------------------------------------------------------------
1 | body{
2 | background-color: white;
3 | color: #000000;
4 | font: small/normal Arial,Helvetica,Sans-Serif;
5 | margin-top: 0.5em;
6 | font-size: 90%;
7 | }
8 |
9 | a{
10 | color: #04c;
11 | }
12 |
13 | a:visited {
14 | color: #639
15 | }
16 |
17 | a:hover {
18 | text-decoration: underline
19 | }
20 |
21 | h1 {
22 | font-size: 120%;
23 | }
24 |
25 | ul {
26 | margin:0;
27 | padding:0
28 | }
29 |
30 | .results {
31 | font-size: 110%;
32 | }
33 |
34 | .results li {
35 | list-style-type:none;
36 | margin-top: 0.5em;
37 | }
38 |
39 | .results a {
40 | font-size: 110%;
41 | text-decoration: underline
42 | }
43 |
44 | cite {
45 | font-style:normal;
46 | word-wrap:break-word;
47 | display: block;
48 | font-size: 100%;
49 | }
50 |
51 | .informations {
52 | color: #388222;
53 | font-size: 100%;
54 | }
55 |
56 | .footer {
57 | padding: 0;
58 | margin-top: 1em;
59 | width: 100%;
60 | float: left
61 | }
62 |
63 | .footer a, .footer span {
64 | display: block;
65 | padding: .3em .7em;
66 | margin: 0 .38em 0 0;
67 | text-align:center;
68 | text-decoration: none;
69 | }
70 |
71 | .footer a:hover {
72 | background: #ededed;
73 | }
74 |
75 | .footer ul, .footer li {
76 | list-style:none;
77 | margin: 0;
78 | padding: 0;
79 | }
80 |
81 | .footer li {
82 | float: left;
83 | }
84 |
85 | .selected {
86 | background: #ededed;
87 | }
88 |
--------------------------------------------------------------------------------
/static/skin/i18n/el.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "Kelson",
5 | "Norhorn",
6 | "Ανώνυμος Βικιπαιδιστής"
7 | ]
8 | },
9 | "name": "Αγγλικά",
10 | "no-such-book": "Δεν υπάρχει τέτοιο βιβλίο: {{BOOK_NAME}}",
11 | "welcome-page-overzealous-filter": "Κανένα αποτέλεσμα. Θέλετε να επαναφέρετε το φίλτρο;",
12 | "powered-by-kiwix-html": "Με την υποστήριξη by Kiwix",
13 | "search": "Αναζήτηση",
14 | "book-filtering-all-categories": "Όλες οι κατηγορίες",
15 | "book-filtering-all-languages": "Όλες οι γλώσσες",
16 | "count-of-matching-books": "{{COUNT}} βιβλίο(α)",
17 | "download": "Λήψη",
18 | "direct-download-link-text": "Απευθείας",
19 | "direct-download-alt-text": "άμεση λήψη",
20 | "hash-download-alt-text": "λήψη αναγνωριστικού",
21 | "magnet-alt-text": "λήψη μαγνήτη",
22 | "torrent-download-link-text": "Αρχείο torrent",
23 | "torrent-download-alt-text": "λήψη torrent",
24 | "filter-by-tag": "Φίλτρο ανά ετικέτα \"{{TAG}}\"",
25 | "stop-filtering-by-tag": "Διακοπή φίλτρου ανά ετικέτα \"{{TAG}}\"",
26 | "welcome-to-kiwix-server": "Καλώς ορίσατε στον διακομιστή Kiwix",
27 | "download-links-heading": "Λήψη συνδέσμων για {{BOOK_TITLE}}",
28 | "download-links-title": "Κατεβάστε το βιβλίο",
29 | "preview-book": "Προεπισκόπηση",
30 | "unknown-error": "Άγνωστο σφάλμα"
31 | }
32 |
--------------------------------------------------------------------------------
/test/languageTools.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2023 Nikhil Tanwar (2002nikhiltanwar@gmail.com)
3 | *
4 | * This program is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU General Public License as
6 | * published by the Free Software Foundation; either version 2 of the
7 | * License, or (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
11 | * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
12 | * NON-INFRINGEMENT. See the GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 | *
18 | */
19 |
20 | #include "gtest/gtest.h"
21 | #include "../include/tools.h"
22 |
23 | namespace
24 | {
25 |
26 | TEST(LanguageToolsTest, englishTest)
27 | {
28 | EXPECT_EQ(kiwix::getLanguageSelfName("eng"), "English");
29 | }
30 |
31 | TEST(LanguageToolsTest, manualValuesTest)
32 | {
33 | EXPECT_EQ(kiwix::getLanguageSelfName("dty"), "डोटेली");
34 | }
35 |
36 | TEST(LanguageToolsTest, emptyStringTest)
37 | {
38 | EXPECT_EQ(kiwix::getLanguageSelfName(""), "Undetermined");
39 | }
40 |
41 | }
42 |
--------------------------------------------------------------------------------
/src/tools/pathTools.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2011 Emmanuel Engelhart
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #ifndef KIWIX_PATHTOOLS_H
21 | #define KIWIX_PATHTOOLS_H
22 |
23 | #include
24 |
25 | #ifdef _WIN32
26 | std::string WideToUtf8(const std::wstring& wstr);
27 | std::wstring Utf8ToWide(const std::string& str);
28 | #endif
29 |
30 | unsigned int getFileSize(const std::string& path);
31 | std::string getFileSizeAsString(const std::string& path);
32 | std::string makeTmpDirectory();
33 | bool copyFile(const std::string& sourcePath, const std::string& destPath);
34 | bool writeTextFile(const std::string& path, const std::string& content);
35 |
36 | #endif
37 |
38 |
--------------------------------------------------------------------------------
/src/html_dumper.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2023 Nikhil Tanwar <2002nikhiltanwar@gmail.com>
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #ifndef KIWIX_HTML_DUMPER_H
21 | #define KIWIX_HTML_DUMPER_H
22 |
23 | #include
24 |
25 | #include "library_dumper.h"
26 |
27 | namespace kiwix
28 | {
29 |
30 | /**
31 | * A class to dump Library in HTML format.
32 | */
33 | class HTMLDumper : public LibraryDumper
34 | {
35 | public:
36 | HTMLDumper(const Library* library, const NameMapper* NameMapper);
37 | ~HTMLDumper();
38 |
39 |
40 | /**
41 | * Dump library in HTML
42 | *
43 | * @return HTML content
44 | */
45 | std::string dumpPlainHTML(kiwix::Filter filter) const;
46 | };
47 |
48 | }
49 |
50 | #endif // KIWIX_HTML_DUMPER_H
51 |
--------------------------------------------------------------------------------
/static/skin/i18n/skr-arab.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "Saraiki"
5 | ]
6 | },
7 | "name": "سرائیکی",
8 | "400-page-title": "غلط ارداس",
9 | "400-page-heading": "غلط ارداس",
10 | "404-page-title": "مواد کائنی لبھیا",
11 | "404-page-heading": "کائنی لبھا",
12 | "new-404-page-title": "ورقہ کائنی لبھیا",
13 | "404-img-text": "کائنی لبھا!",
14 | "500-page-title": "اندرلا سرور نقص",
15 | "500-page-heading": "اندرلا سرور نقص",
16 | "search": "ڳولو",
17 | "book-filtering-all-categories": "ساریاں ونکیاں",
18 | "book-filtering-all-languages": "ساریاں زباناں",
19 | "count-of-matching-books": "{{COUNT}} کتاب(اں)",
20 | "download": "ڈاؤن لوڈ",
21 | "direct-download-link-text": "ڈائرکٹ",
22 | "direct-download-alt-text": "ڈائرکٹ ڈاؤن لوڈ",
23 | "hash-download-alt-text": "ڈاؤن لوڈ ہیش",
24 | "torrent-download-link-text": "ٹورنٹ فائل",
25 | "torrent-download-alt-text": "ٹورںٹ ݙاؤن لوڈ کرو",
26 | "download-links-title": "کتاب ڈاؤن لوڈ کرو",
27 | "preview-book": "پیشگی ݙکھالا",
28 | "book-category.vikidia": "وکی ڈیا",
29 | "book-category.wikibooks": "وکی کتاباں",
30 | "book-category.wikinews": "وکی خبراں",
31 | "book-category.wikipedia": "وکیپیڈیا",
32 | "book-category.wikiquote": "وکی ٻول",
33 | "book-category.wikisource": "وکی ماخذ",
34 | "book-category.wikispecies": "وکی سپیشیز",
35 | "book-category.wikiversity": "وکی ورسٹی",
36 | "book-category.wikivoyage": "وکی سیرسپاٹا",
37 | "book-category.wiktionary": "وکشنری",
38 | "book-category.other": "ٻیا"
39 | }
40 |
--------------------------------------------------------------------------------
/static/templates/search_result.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 | Search: {{query.pattern}}
7 | {{query.unpaginatedQuery}}&format=xml&start={{results.start}}&pageLength={{pagination.itemsPerPage}}
8 | Search result for {{query.pattern}}
9 | {{results.count}}
10 | {{results.start}}
11 | {{pagination.itemsPerPage}}
12 |
13 |
19 | {{#results.items}}
20 | -
21 | {{title}}
22 | {{absolutePath}}
23 | {{#snippet}}
24 | {{>snippet}}...
25 | {{/snippet}}
26 | {{#bookTitle}}
27 |
28 | {{bookTitle}}
29 |
30 | {{/bookTitle}}
31 | {{#wordCount}}
32 | {{wordCount}}
33 | {{/wordCount}}
34 |
35 | {{/results.items}}
36 |
37 |
38 |
--------------------------------------------------------------------------------
/static/skin/langSelector.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
26 |
--------------------------------------------------------------------------------
/static/skin/i18n/cs.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "Spotter"
5 | ]
6 | },
7 | "name": "Čeština",
8 | "suggest-full-text-search": "obsahující '{{{SEARCH_TERMS}}}'...",
9 | "no-such-book": "Žádná taková kniha: {{BOOK_NAME}}",
10 | "too-many-books": "Bylo požadováno příliš mnoho knih ({{NB_BOOKS}}), kde je limit {{LIMIT}}",
11 | "no-book-found": "Výběrovým kritériím nevyhovuje žádná kniha",
12 | "url-not-found": "Požadovaná adresa URL \"{{url}}\" nebyla na tomto serveru nalezena.",
13 | "suggest-search": "Proveďte fulltextové vyhledávání {{PATTERN}}",
14 | "random-article-failure": "Jejda! Nepodařilo se vybrat náhodný článek :(",
15 | "invalid-raw-data-type": "{{DATATYPE}} není platný požadavek na nezpracovaný obsah.",
16 | "no-value-for-arg": "Pro argument {{ARGUMENT}} nebyla zadána žádná hodnota",
17 | "no-query": "Nebyl poskytnut žádný dotaz.",
18 | "raw-entry-not-found": "Nelze najít položku {{DATATYPE}} {{ENTRY}}",
19 | "400-page-title": "Neplatný požadavek",
20 | "400-page-heading": "Neplatný požadavek",
21 | "404-page-title": "Obsah nenalezen",
22 | "404-page-heading": "Nenalezeno",
23 | "500-page-title": "Interní chyba serveru",
24 | "500-page-heading": "Interní chyba serveru",
25 | "fulltext-search-unavailable": "Fulltextové vyhledávání není k dispozici",
26 | "no-search-results": "Fulltextový vyhledávač není pro tento obsah dostupný.",
27 | "library-button-text": "Přejít na uvítací stránku",
28 | "home-button-text": "Přejít na hlavní stránku '{{BOOK_TITLE}}'",
29 | "random-page-button-text": "Přejít na náhodně vybranou stránku",
30 | "searchbox-tooltip": "Hledat '{{BOOK_TITLE}}'"
31 | }
32 |
--------------------------------------------------------------------------------
/debian/control:
--------------------------------------------------------------------------------
1 | Source: libkiwix
2 | Priority: optional
3 | Maintainer: Kiwix team
4 | Build-Depends: debhelper-compat (= 13),
5 | meson,
6 | pkgconf,
7 | libzim-dev (>= 9.0), libzim-dev (<< 10.0),
8 | libcurl4-gnutls-dev,
9 | libicu-dev,
10 | libgtest-dev,
11 | libkainjow-mustache-dev,
12 | libmicrohttpd-dev,
13 | libpugixml-dev,
14 | zlib1g-dev
15 | Standards-Version: 4.5.0
16 | Section: libs
17 | Homepage: https://github.com/kiwix/libkiwix
18 | Rules-Requires-Root: no
19 |
20 | Package: libkiwix-dev
21 | Section: libdevel
22 | Architecture: any
23 | Multi-Arch: same
24 | Depends: libkiwix14 (= ${binary:Version}), ${misc:Depends}, python3,
25 | libzim-dev (>= 9.0), libzim-dev (<< 10.0),
26 | libicu-dev,
27 | libpugixml-dev,
28 | libcurl4-gnutls-dev,
29 | libmicrohttpd-dev,
30 | zlib1g-dev
31 | Description: library of common code for Kiwix (development)
32 | Kiwix is an offline Wikipedia reader. libkiwix provides the
33 | software core for Kiwix, and contains the code shared by all
34 | Kiwix ports (Windows, Linux, OSX, Android, etc.).
35 | .
36 | This package contains development files.
37 |
38 | Package: libkiwix14
39 | Architecture: any
40 | Multi-Arch: same
41 | Depends: ${shlibs:Depends}, ${misc:Depends}, aria2
42 | Conflicts: libkiwix0, libkiwix3, libkiwix9, libkiwix10, libkiwix11, libkiwix12, libkiwix13
43 | Replaces: libkiwix0, libkiwix3, libkiwix9, libkiwix10, libkiwix11, libkiwix12, libkiwix13
44 | Description: library of common code for Kiwix
45 | Kiwix is an offline Wikipedia reader. libkiwix provides the
46 | software core for Kiwix, and contains the code shared by all
47 | Kiwix ports (Windows, Linux, OSX, Android, etc.).
48 |
--------------------------------------------------------------------------------
/src/subprocess_unix.cpp:
--------------------------------------------------------------------------------
1 |
2 |
3 | #include "subprocess_unix.h"
4 |
5 | #include
6 | #include
7 | #include
8 | #include
9 | #include
10 | #include
11 |
12 | UnixImpl::UnixImpl():
13 | m_pid(0),
14 | m_running(false),
15 | m_shouldQuit(false)
16 | {
17 | }
18 |
19 | UnixImpl::~UnixImpl()
20 | {
21 | kill();
22 | m_shouldQuit = true;
23 | m_waitingThread.join();
24 | }
25 |
26 | void* UnixImpl::waitForPID(void* _self)
27 | {
28 | UnixImpl* self = static_cast(_self);
29 | while (true) {
30 | if (!waitpid(self->m_pid, NULL, WNOHANG)) {
31 | break;
32 | }
33 | if (self->m_shouldQuit) {
34 | return nullptr;
35 | }
36 | std::this_thread::sleep_for(std::chrono::milliseconds(100));
37 | }
38 |
39 | self->m_running = false;
40 |
41 | return self;
42 | }
43 |
44 | void UnixImpl::run(commandLine_t& commandLine)
45 | {
46 | const char* binary = commandLine[0];
47 | int pid = fork();
48 | switch(pid) {
49 | case -1:
50 | std::cerr << "cannot fork" << std::endl;
51 | break;
52 | case 0:
53 | commandLine.push_back(NULL);
54 | if (execvp(binary, const_cast(commandLine.data()))) {
55 | perror("Cannot launch\n");
56 | _exit(-1);
57 | }
58 |
59 | break;
60 | default:
61 | m_pid = pid;
62 | m_running = true;
63 | m_waitingThread = std::thread(waitForPID, this);
64 | break;
65 | }
66 | }
67 |
68 | bool UnixImpl::kill()
69 | {
70 | return (::kill(m_pid, SIGKILL) == 0);
71 | }
72 |
73 | bool UnixImpl::isRunning()
74 | {
75 | return m_running;
76 | }
77 |
--------------------------------------------------------------------------------
/static/skin/i18n/sk.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "Yardom78"
5 | ]
6 | },
7 | "name": "slovenčina",
8 | "suggest-full-text-search": "obsahuje '{{{SEARCH_TERMS}}}'...",
9 | "no-such-book": "Žiadna kniha ako: {{BOOK_NAME}}",
10 | "too-many-books": "Príliš veľa požadovaných kníh ({{NB_BOOKS}}), limit je {{LIMIT}}",
11 | "no-book-found": "Kritériám výberu nevyhovuje žiadna kniha",
12 | "url-not-found": "Požadovaná adresa URL \"{{url}}\" na tomto serveri nebola nájdená.",
13 | "suggest-search": "Spustite hľadanie celého textu {{PATTERN}}",
14 | "random-article-failure": "Nepodarilo sa vybrať náhodný článok :(",
15 | "invalid-raw-data-type": "{{DATATYPE}} nie je platná požiadavka pre surový obsah.",
16 | "no-value-for-arg": "Pre argument {{ARGUMENT}} nebola poskytnutá žiadna hodnota",
17 | "no-query": "Nebol poskytnutý žiadny dopyt.",
18 | "raw-entry-not-found": "Nepodarilo sa nájsť {{DATATYPE}} položka {{ENTRY}}",
19 | "400-page-title": "Neplatná požiadavka",
20 | "400-page-heading": "Neplatná požiadavka",
21 | "404-page-title": "Obsah nebol nájdený",
22 | "404-page-heading": "Nenájdené",
23 | "500-page-title": "Chyba interného servera",
24 | "500-page-heading": "Chyba interného servera",
25 | "fulltext-search-unavailable": "Vyhľadávanie celého textu nie je dostupné",
26 | "no-search-results": "Funkcia na vyhľadávanie celého textu nie je pre tento obsah dostupná.",
27 | "library-button-text": "Prejsť na uvítaciu stránku",
28 | "home-button-text": "Prejsť na hlavnú stránku knihy {{BOOK_TITLE}}",
29 | "random-page-button-text": "Prejsť na náhodne vybranú stránku",
30 | "searchbox-tooltip": "Vyhľadať {{BOOK_TITLE}}"
31 | }
32 |
--------------------------------------------------------------------------------
/static/skin/i18n/hu.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "Eukarióta",
5 | "Urbalazs"
6 | ]
7 | },
8 | "name": "Magyar",
9 | "400-page-title": "Érvénytelen kérés",
10 | "400-page-heading": "Érvénytelen kérés",
11 | "404-page-title": "A tartalom nem található",
12 | "404-page-heading": "Nem található",
13 | "new-404-page-title": "Az oldal nem található",
14 | "new-404-page-heading": "Hoppá! Az oldal nem található.",
15 | "404-img-text": "Nem található!",
16 | "path-was-not-found": "A kért útvonal nem található:",
17 | "404-advice.p1": "A keresett tartalom továbbra is elérhető lehet, de előfordulhat, hogy más helyen található a ZIM-fájlon belül.",
18 | "search": "Keresés",
19 | "download": "Letöltés",
20 | "hash-download-link-text": "SHA-256 ellenőrzőösszeg",
21 | "hash-download-alt-text": "SHA-256 fájl-ellenőrzőösszeg megjelenítése",
22 | "torrent-download-link-text": "BitTorrent",
23 | "welcome-to-kiwix-server": "Üdvözli a Kiwix-kiszolgáló!",
24 | "download-links-heading": "Letöltési hivatkozások ehhez: {{BOOK_TITLE}}",
25 | "download-links-title": "Könyv letöltése",
26 | "preview-book": "Előnézet",
27 | "unknown-error": "Ismeretlen hiba",
28 | "book-category.wikibooks": "Wikikönyvek",
29 | "book-category.wikinews": "Wikihírek",
30 | "book-category.wikipedia": "Wikipédia",
31 | "book-category.wikiquote": "Wikidézet",
32 | "book-category.wikisource": "Wikiforrás",
33 | "book-category.wikispecies": "Wikifajok",
34 | "book-category.wikiversity": "Wikiegyetem",
35 | "book-category.wikivoyage": "Wikivoyage",
36 | "book-category.wiktionary": "Wikiszótár",
37 | "book-category.other": "Egyéb",
38 | "text-loading-content": "Tartalom betöltése"
39 | }
40 |
--------------------------------------------------------------------------------
/src/meson.build:
--------------------------------------------------------------------------------
1 | kiwix_sources = [
2 | 'book.cpp',
3 | 'bookmark.cpp',
4 | 'library.cpp',
5 | 'manager.cpp',
6 | 'libxml_dumper.cpp',
7 | 'opds_dumper.cpp',
8 | 'html_dumper.cpp',
9 | 'library_dumper.cpp',
10 | 'downloader.cpp',
11 | 'server.cpp',
12 | 'search_renderer.cpp',
13 | 'subprocess.cpp',
14 | 'aria2.cpp',
15 | 'tools/base64.cpp',
16 | 'tools/pathTools.cpp',
17 | 'tools/regexTools.cpp',
18 | 'tools/stringTools.cpp',
19 | 'tools/networkTools.cpp',
20 | 'tools/opdsParsingTools.cpp',
21 | 'tools/languageTools.cpp',
22 | 'tools/otherTools.cpp',
23 | 'tools/archiveTools.cpp',
24 | 'kiwixserve.cpp',
25 | 'name_mapper.cpp',
26 | 'server/byte_range.cpp',
27 | 'server/etag.cpp',
28 | 'server/request_context.cpp',
29 | 'server/response.cpp',
30 | 'server/internalServer.cpp',
31 | 'server/internalServer_catalog.cpp',
32 | 'server/i18n.cpp',
33 | 'opds_catalog.cpp',
34 | 'version.cpp'
35 | ]
36 | kiwix_sources += lib_resources
37 | kiwix_sources += i18n_resources
38 |
39 | if host_machine.system() == 'windows'
40 | kiwix_sources += 'subprocess_windows.cpp'
41 | else
42 | kiwix_sources += 'subprocess_unix.cpp'
43 | endif
44 |
45 | install_dir = get_option('libdir')
46 |
47 | config_h = configure_file(output : 'kiwix_config.h',
48 | configuration : conf,
49 | input : 'config.h.in')
50 | install_headers(config_h, subdir:'kiwix')
51 |
52 | libkiwix = library('kiwix',
53 | kiwix_sources,
54 | include_directories : inc,
55 | dependencies : all_deps,
56 | link_args: extra_libs,
57 | version: meson.project_version(),
58 | install: true,
59 | install_dir: install_dir)
60 |
--------------------------------------------------------------------------------
/static/skin/i18n/ku-latn.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "Bikarhêner"
5 | ]
6 | },
7 | "name": "kurdî",
8 | "suggest-full-text-search": "'{{{SEARCH_TERMS}}}' dihewîne...",
9 | "no-such-book": "Kitêbeke wisa nîne: {{BOOK_NAME}}",
10 | "too-many-books": "Pir zêde kitêb hatiye xwestin ({{NB_BOOKS}}) ku sînor {{LIMIT}} ye",
11 | "no-book-found": "Ti kitêbekê ku li krîterên te bê peyda nebû",
12 | "url-not-found": "URLya xwestî \"{{url}}\" li ser vê serverê nehate dîtin.",
13 | "suggest-search": "Ji bo {{PATTERN}} lêgerîneke nivîsa temamî pêk bîne",
14 | "random-article-failure": "Ha ho! Bi ser neket ku gotareke ketober bibijêre :(",
15 | "invalid-raw-data-type": "{{DATATYPE}} ne daxwazeke derbasdar e ji bo naveroka xav.",
16 | "no-value-for-arg": "Ti tişt nehatiye diyarkirin ji bo mijara {{ARGUMENT}}",
17 | "no-query": "Ti tiştekî xwestî nîne.",
18 | "raw-entry-not-found": "Hêmana {{ENTRY}} {{DATATYPE}} peyda nebû",
19 | "400-page-title": "Xwesteka nederbasdar",
20 | "400-page-heading": "Xwesteka nederbasdar",
21 | "404-page-title": "Naverok nehat dîtin",
22 | "404-page-heading": "Nehat dîtin",
23 | "500-page-title": "Çewtiya Serverê yê Daxilî",
24 | "500-page-heading": "Çewtiya Serverê yê Daxilî",
25 | "fulltext-search-unavailable": "Lêgerîna Temamê Nivîsê Neberdest e",
26 | "no-search-results": "Motora lêgerînê yê temamê metnê ne berdest e ji bo vê naverokê.",
27 | "library-button-text": "Here rûpela xêrhatinê",
28 | "home-button-text": "Here rûpela destpêkê yê {{BOOK_TITLE}}",
29 | "random-page-button-text": "Here rûpeleke ketober bijartî",
30 | "searchbox-tooltip": "Li {{BOOK_TITLE}} bigere",
31 | "confusion-of-tongues": "Du an zêdetir kitêbên bi zimanên cihê wê beşdarî lêgerînê bibin, ev jî dibe ku bibe sedema tevliheviya encaman."
32 | }
33 |
--------------------------------------------------------------------------------
/static/skin/i18n/pl.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "Strebski",
5 | "WaldiSt"
6 | ]
7 | },
8 | "name": "Polski",
9 | "suggest-full-text-search": "zawierający '{{{SEARCH_TERMS}}}'...",
10 | "no-such-book": "Brak takiej książki: {{BOOK_NAME}}",
11 | "url-not-found": "Żądany adres URL „{{url}}” nie został znaleziony na tym serwerze.",
12 | "suggest-search": "Wykonaj wyszukiwanie pełnotekstowe dla {{PATTERN}}",
13 | "random-article-failure": "Ups! Nie udało się wybrać losowego artykułu :(",
14 | "invalid-raw-data-type": "{{DATATYPE}} nie jest prawidłowym żądaniem zawartości nieprzetworzonej.",
15 | "raw-entry-not-found": "Nie można znaleźć {{DATATYPE}} wpisu {{ENTRY}}",
16 | "400-page-title": "Nieprawidłowe żądanie",
17 | "400-page-heading": "Nieprawidłowe żądanie",
18 | "404-page-title": "Zawartość nie została znaleziona",
19 | "404-page-heading": "Nie znaleziono",
20 | "500-page-title": "Wewnętrzny błąd serwera",
21 | "500-page-heading": "Wewnętrzny błąd serwera",
22 | "fulltext-search-unavailable": "Wyszukiwanie pełnotekstowe jest niedostępne",
23 | "no-search-results": "Wyszukiwarka pełnotekstowa nie jest dostępna dla tej zawartości.",
24 | "library-button-text": "Przejdź do strony powitalnej",
25 | "home-button-text": "Przejdź do głównej strony '{{BOOK_TITLE}}'",
26 | "random-page-button-text": "Przejdź do losowo wybranej strony",
27 | "searchbox-tooltip": "Szukaj '{{BOOK_TITLE}}'",
28 | "search": "Szukaj",
29 | "book-filtering-all-categories": "Wszystkie Kategorie",
30 | "book-filtering-all-languages": "Wszystkie języki",
31 | "download": "Pobierz",
32 | "direct-download-link-text": "Bezpośrednio",
33 | "direct-download-alt-text": "bezpośrednie pobieranie",
34 | "torrent-download-link-text": "Plik torrent",
35 | "welcome-to-kiwix-server": "Witamy na serwerze Kiwix",
36 | "download-links-title": "Pobierz książkę",
37 | "preview-book": "Podgląd",
38 | "book-category.other": "Inne"
39 | }
40 |
--------------------------------------------------------------------------------
/src/tools/opdsParsingTools.cpp:
--------------------------------------------------------------------------------
1 | #include "tools.h"
2 | #include
3 |
4 | namespace kiwix
5 | {
6 |
7 | namespace
8 | {
9 | #define VALUE(name) entryNode.child(name).child_value()
10 | FeedLanguages parseLanguages(const pugi::xml_document& doc)
11 | {
12 | pugi::xml_node feedNode = doc.child("feed");
13 | FeedLanguages langs;
14 |
15 | for (pugi::xml_node entryNode = feedNode.child("entry"); entryNode;
16 | entryNode = entryNode.next_sibling("entry")) {
17 | auto title = VALUE("title");
18 | auto code = VALUE("dc:language");
19 | langs.push_back({code, title});
20 | }
21 |
22 | return langs;
23 | }
24 |
25 | FeedCategories parseCategories(const pugi::xml_document& doc)
26 | {
27 | pugi::xml_node feedNode = doc.child("feed");
28 | FeedCategories categories;
29 |
30 | for (pugi::xml_node entryNode = feedNode.child("entry"); entryNode;
31 | entryNode = entryNode.next_sibling("entry")) {
32 | auto title = VALUE("title");
33 | categories.push_back(title);
34 | }
35 |
36 | return categories;
37 | }
38 |
39 | } // unnamed namespace
40 |
41 | FeedLanguages readLanguagesFromFeed(const std::string& content)
42 | {
43 | pugi::xml_document doc;
44 | pugi::xml_parse_result result
45 | = doc.load_buffer((void*)content.data(), content.size());
46 |
47 | if (result) {
48 | auto langs = parseLanguages(doc);
49 | return langs;
50 | }
51 |
52 | return FeedLanguages();
53 | }
54 |
55 | FeedCategories readCategoriesFromFeed(const std::string& content)
56 | {
57 | pugi::xml_document doc;
58 | pugi::xml_parse_result result
59 | = doc.load_buffer((void*)content.data(), content.size());
60 |
61 | FeedCategories categories;
62 | if (result) {
63 | categories = parseCategories(doc);
64 | return categories;
65 | }
66 |
67 | return categories;
68 | }
69 |
70 | } // namespace kiwix
71 |
--------------------------------------------------------------------------------
/src/library_dumper.cpp:
--------------------------------------------------------------------------------
1 | #include "library_dumper.h"
2 | #include "tools/stringTools.h"
3 | #include "tools/otherTools.h"
4 | #include "tools.h"
5 |
6 | namespace kiwix
7 | {
8 | /* Constructor */
9 | LibraryDumper::LibraryDumper(const Library* library, const NameMapper* nameMapper)
10 | : library(library),
11 | nameMapper(nameMapper)
12 | {
13 | }
14 | /* Destructor */
15 | LibraryDumper::~LibraryDumper()
16 | {
17 | }
18 |
19 | void LibraryDumper::setOpenSearchInfo(int totalResults, int startIndex, int count)
20 | {
21 | m_totalResults = totalResults;
22 | m_startIndex = startIndex,
23 | m_count = count;
24 | }
25 |
26 | kainjow::mustache::list LibraryDumper::getCategoryData() const
27 | {
28 | const auto now = gen_date_str();
29 | kainjow::mustache::list categoryData;
30 | for ( const auto& category : library->getBooksCategories() ) {
31 | const auto urlencodedCategoryName = urlEncode(category);
32 | categoryData.push_back(kainjow::mustache::object{
33 | {"name", category},
34 | {"urlencoded_name", urlencodedCategoryName},
35 | {"updated", now},
36 | {"id", gen_uuid(libraryId + "/categories/" + urlencodedCategoryName)}
37 | });
38 | }
39 | return categoryData;
40 | }
41 |
42 | kainjow::mustache::list LibraryDumper::getLanguageData() const
43 | {
44 | const auto now = gen_date_str();
45 | kainjow::mustache::list languageData;
46 | for ( const auto& langAndBookCount : library->getBooksLanguagesWithCounts() ) {
47 | const std::string languageCode = langAndBookCount.first;
48 | const int bookCount = langAndBookCount.second;
49 | const auto languageSelfName = getLanguageSelfName(languageCode);
50 | languageData.push_back(kainjow::mustache::object{
51 | {"lang_code", languageCode},
52 | {"lang_self_name", languageSelfName},
53 | {"book_count", to_string(bookCount)},
54 | {"updated", now},
55 | {"id", gen_uuid(libraryId + "/languages/" + languageCode)}
56 | });
57 | }
58 | return languageData;
59 | }
60 |
61 | } // namespace kiwix
62 |
--------------------------------------------------------------------------------
/src/bookmark.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Matthieu Gautier
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #include "bookmark.h"
21 | #include "book.h"
22 |
23 | #include
24 |
25 | namespace kiwix
26 | {
27 | /* Constructor */
28 | Bookmark::Bookmark()
29 | {
30 | }
31 |
32 | Bookmark::Bookmark(const Book& book, const std::string& path, const std::string& title):
33 | m_bookId(book.getId()),
34 | m_bookTitle(book.getTitle()),
35 | m_bookName(book.getName()),
36 | m_bookFlavour(book.getFlavour()),
37 | m_url(path),
38 | m_title(title),
39 | m_language(book.getCommaSeparatedLanguages()),
40 | m_date(book.getDate())
41 | {}
42 |
43 | /* Destructor */
44 | Bookmark::~Bookmark()
45 | {
46 | }
47 |
48 | void Bookmark::updateFromXml(const pugi::xml_node& node)
49 | {
50 | auto bookNode = node.child("book");
51 | m_bookId = bookNode.child("id").child_value();
52 | m_bookTitle = bookNode.child("title").child_value();
53 | m_bookName = bookNode.child("name").child_value();
54 | m_bookFlavour = bookNode.child("flavour").child_value();
55 | m_language = bookNode.child("language").child_value();
56 | m_date = bookNode.child("date").child_value();
57 | m_title = node.child("title").child_value();
58 | m_url = node.child("url").child_value();
59 | }
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/static/skin/blocklink.svg:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/static/resources_list.txt:
--------------------------------------------------------------------------------
1 | skin/caret.png
2 | skin/bittorrent.png
3 | skin/magnet.png
4 | skin/404.svg
5 | skin/500.svg
6 | skin/blocklink.svg
7 | skin/feed.svg
8 | skin/langSelector.svg
9 | skin/download.png
10 | skin/download-white.svg
11 | skin/hash.png
12 | skin/search-icon.svg
13 | skin/iso6391To3.js
14 | skin/isotope.pkgd.min.js
15 | skin/index.js
16 | skin/autoComplete/autoComplete.min.js
17 | skin/error.css
18 | skin/print.css
19 | skin/kiwix.css
20 | skin/taskbar.css
21 | skin/index.css
22 | skin/fonts/DMSans-Regular.ttf
23 | skin/fonts/Poppins.ttf
24 | skin/fonts/Roboto.ttf
25 | skin/search_results.css
26 | skin/blank.html
27 | skin/polyfills.js
28 | skin/viewer.js
29 | skin/i18n.js
30 | skin/languages.js
31 | skin/mustache.min.js
32 | viewer.html
33 | templates/search_result.html
34 | templates/search_result.xml
35 | templates/error.html
36 | templates/error.xml
37 | templates/index.html
38 | templates/suggestion.json
39 | templates/captured_external.html
40 | templates/catalog_entries.xml
41 | templates/catalog_v2_root.xml
42 | templates/catalog_v2_entries.xml
43 | templates/catalog_v2_entry.xml
44 | templates/catalog_v2_partial_entry.xml
45 | templates/catalog_v2_categories.xml
46 | templates/catalog_v2_languages.xml
47 | templates/url_of_search_results_css.tmpl
48 | templates/viewer_settings.js
49 | templates/no_js_library_page.html
50 | templates/no_js_download.html
51 | templates/sexy404.html
52 | templates/sexy500.html
53 | opensearchdescription.xml
54 | ft_opensearchdescription.xml
55 | catalog_v2_searchdescription.xml
56 | skin/autoComplete/css/autoComplete.css
57 | skin/favicon/android-chrome-192x192.png
58 | skin/favicon/android-chrome-512x512.png
59 | skin/favicon/apple-touch-icon.png
60 | skin/favicon/browserconfig.xml
61 | skin/favicon/favicon-16x16.png
62 | skin/favicon/favicon-32x32.png
63 | skin/favicon/favicon.ico
64 | skin/favicon/mstile-70x70.png
65 | skin/favicon/mstile-144x144.png
66 | skin/favicon/mstile-150x150.png
67 | skin/favicon/mstile-310x150.png
68 | skin/favicon/mstile-310x310.png
69 | skin/favicon/safari-pinned-tab.svg
70 | skin/favicon/site.webmanifest
71 |
--------------------------------------------------------------------------------
/static/skin/i18n/bn.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "Nokib Sarkar",
5 | "আফতাবুজ্জামান"
6 | ]
7 | },
8 | "name": "বাংলা",
9 | "404-page-heading": "পাওয়া যায়নি",
10 | "new-404-page-title": "পাতা পাওয়া যায়নি",
11 | "new-404-page-heading": "ওহ! পাতা খুঁজে পাওয়া যায়নি",
12 | "404-img-text": "পাওয়া যায়নি!",
13 | "path-was-not-found": "অনুরোধ করা পথটি পাওয়া যায়নি:",
14 | "404-advice.p1": "আপনি যে বিষয়বস্তু খুঁজছেন তা এখনও উপলব্ধ থাকতে পারে, তবে এটি জিম ফাইলের মধ্যে অন্য কোনও জায়গায় অবস্থিত হতে পারে।",
15 | "404-advice.p4": "আপনি যে তথ্য খুঁজছেন তার সাথে সম্পর্কিত কীওয়ার্ড বা শিরোনাম খুঁজুন।",
16 | "500-page-title": "অভ্যন্তরীণ সার্ভার ত্রুটি",
17 | "500-page-heading": "অভ্যন্তরীণ সার্ভার ত্রুটি",
18 | "external-link-intro": "আপনি অনলাইনে যাওয়ার জন্য কিউইক্সের জিম রিডার ছেড়ে দিতে চলেছেন",
19 | "external-link-advice.p1": "আপনি যে লিঙ্কটিতে প্রবেশ করার চেষ্টা করছেন তা আপনার অফলাইন প্যাকেজের অংশ নয় এবং এর জন্য ইন্টারনেট সংযোগ প্রয়োজন।",
20 | "external-link-advice.p2": "আপনি যদি অনলাইনে যেতে পারেন, তাহলে লিঙ্কটি খোলার চেষ্টা করতে পারেন।",
21 | "external-link-advice.p3": "অন্যথায়, আপনি আপনার ব্রাউজারের পিছন বোতাম ব্যবহার করে আপনার ZIM-এর অফলাইন বিষয়বস্তুতে ফিরে যেতে পারেন।",
22 | "search-result-book-info": "{{BOOK_TITLE}} থেকে",
23 | "word-count": "{{COUNT}}টি শব্দ",
24 | "library-button-text": "স্বাগত পাতায় চলুন",
25 | "home-button-text": "'{{BOOK_TITLE}}'-এর প্রধান পাতায় চলুন",
26 | "searchbox-tooltip": "'{{BOOK_TITLE}}' অনুসন্ধান করুন",
27 | "search": "অনুসন্ধান",
28 | "welcome-to-kiwix-server": "কিউইক্স সার্ভারে স্বাগতম",
29 | "download-links-title": "বই ডাউনলোড করুন",
30 | "preview-book": "প্রাকদর্শন",
31 | "book-category.wikibooks": "উইকিবই",
32 | "book-category.wikinews": "উইকিসংবাদ",
33 | "book-category.wikipedia": "উইকিপিডিয়া",
34 | "book-category.wikiquote": "উইকিউক্তি",
35 | "book-category.wikisource": "উইকিসংকলন",
36 | "book-category.wikispecies": "উইকিপ্রজাতি",
37 | "book-category.wikiversity": "উইকিবিশ্ববিদ্যালয়",
38 | "book-category.wikivoyage": "উইকিভ্রমণ",
39 | "book-category.wiktionary": "উইকিঅভিধান",
40 | "book-category.other": "অন্যান্য"
41 | }
42 |
--------------------------------------------------------------------------------
/src/kiwixserve.cpp:
--------------------------------------------------------------------------------
1 | #include "kiwixserve.h"
2 | #include "subprocess.h"
3 |
4 | #ifdef _WIN32
5 | # define KIWIXSERVE_CMD "kiwix-serve.exe"
6 | # include
7 | #else
8 | # define KIWIXSERVE_CMD "kiwix-serve"
9 | # include
10 | #endif
11 |
12 | #include "tools.h"
13 | #include "tools/pathTools.h"
14 | #include "tools/stringTools.h"
15 |
16 | namespace kiwix {
17 |
18 | KiwixServe::KiwixServe(const std::string& libraryPath, int port)
19 | : m_port(port),
20 | m_libraryPath(libraryPath)
21 | {
22 | }
23 |
24 | KiwixServe::~KiwixServe()
25 | {
26 | shutDown();
27 | }
28 |
29 | void KiwixServe::run()
30 | {
31 | #ifdef _WIN32
32 | int pid = GetCurrentProcessId();
33 | #else
34 | pid_t pid = getpid();
35 |
36 | #endif
37 |
38 | std::vector callCmd;
39 | std::string kiwixServeCmd = appendToDirectory(
40 | removeLastPathElement(getExecutablePath(true)),
41 | KIWIXSERVE_CMD);
42 | if (fileExists(kiwixServeCmd)) {
43 | // A local kiwix-serve exe exists (packaged with kiwix-desktop), use it.
44 | callCmd.push_back(kiwixServeCmd.c_str());
45 | } else {
46 | // Try to use a potential installed kiwix-serve.
47 | callCmd.push_back(KIWIXSERVE_CMD);
48 | }
49 | std::string attachProcessOpt = "-a" + to_string(pid);
50 | std::string portOpt = "-p" + to_string(m_port);
51 | callCmd.push_back(attachProcessOpt.c_str());
52 | callCmd.push_back(portOpt.c_str());
53 | callCmd.push_back("-l");
54 | callCmd.push_back(m_libraryPath.c_str());
55 | mp_kiwixServe = Subprocess::run(callCmd);
56 | }
57 |
58 | void KiwixServe::shutDown()
59 | {
60 | if (mp_kiwixServe)
61 | mp_kiwixServe->kill();
62 | }
63 |
64 | bool KiwixServe::isRunning()
65 | {
66 | if (mp_kiwixServe) {
67 | return (mp_kiwixServe->isRunning());
68 | }
69 | return false;
70 | }
71 |
72 | int KiwixServe::setPort(int port)
73 | {
74 | if (port >= 1 && port <= 65535) {
75 | m_port = port;
76 | } else {
77 | return -1;
78 | }
79 | return m_port;
80 | }
81 |
82 | }
83 |
--------------------------------------------------------------------------------
/static/skin/i18n/br.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "Adriendelucca",
5 | "Y-M D"
6 | ]
7 | },
8 | "name": "brezhoneg",
9 | "suggest-full-text-search": "E lec'h emañ \"{{{SEARCH_TERMS}}}\"...",
10 | "no-such-book": "N’eus ket eus al levr-mañ: {{BOOK_NAME}}",
11 | "no-book-found": "N’eus levr ebet a glot gant an dezverkoù-se",
12 | "url-not-found": "N’eo ket bet kavet an URL \"{{url}}\" goulennet war ar servijer-mañ.",
13 | "random-article-failure": "Chaous! N’hon eus ket gellet dibab ur pennad dre ziouer evidoc’h :(",
14 | "400-page-title": "Reked amwiriek",
15 | "400-page-heading": "Reked amwiriek",
16 | "404-page-heading": "N'eo ket bet kavet",
17 | "500-page-title": "Fazi diabarzh ar servijer",
18 | "500-page-heading": "Fazi diabarzh ar servijer",
19 | "search-results-page-title": "Klask: {{SEARCH_PATTERN}}",
20 | "search-results-page-header": "Disoc’hoù {{START}}-{{END}} diwar {{COUNT}} evit \"{{{SEARCH_PATTERN}}}\"",
21 | "empty-search-results-page-header": "Disoc’h ebet kavet evit \"{{{SEARCH_PATTERN}}}\"",
22 | "search-result-book-info": "diouzh {{BOOK_TITLE}}",
23 | "word-count": "{{COUNT}} a c’herioù",
24 | "library-button-text": "Mont d’ar bajenn degemer",
25 | "home-button-text": "Mont da bajenn degemer \"{{BOOK_TITLE}}\"",
26 | "random-page-button-text": "Mont d’ur bajenn dre zegouezh",
27 | "searchbox-tooltip": "Klask '{{BOOK_TITLE}}'",
28 | "powered-by-kiwix-html": "Lusket gant Kiwix",
29 | "search": "Klask",
30 | "book-filtering-all-categories": "An holl rummadoù",
31 | "book-filtering-all-languages": "An holl yezhoù",
32 | "count-of-matching-books": "{{COUNT}} levr",
33 | "download": "Pellgargañ",
34 | "direct-download-link-text": "Eeun",
35 | "filter-by-tag": "Silañ gant an dikedenn \"{{TAG}}\"",
36 | "stop-filtering-by-tag": "Paouez da silañ gant an dikedenn \"{{TAG}}\"",
37 | "welcome-to-kiwix-server": "Degemer mat er servijer Kiwix",
38 | "download-links-heading": "Liammoù pellgargañ evit {{BOOK_TITLE}}",
39 | "download-links-title": "Pellgargañ al levr",
40 | "preview-book": "Rakwelet",
41 | "unknown-error": "Fazi dianav"
42 | }
43 |
--------------------------------------------------------------------------------
/src/opds_catalog.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Veloman Yunkan
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #include "opds_catalog.h"
21 | #include "tools/stringTools.h"
22 |
23 | #include
24 |
25 | namespace kiwix
26 | {
27 |
28 | namespace
29 | {
30 | const char opdsSearchEndpoint[] = "/catalog/v2/entries";
31 |
32 | enum Separator { AMP };
33 |
34 | std::ostringstream& operator<<(std::ostringstream& oss, Separator sep)
35 | {
36 | if ( oss.tellp() > 0 )
37 | oss << "&";
38 | return oss;
39 | }
40 |
41 | std::string buildSearchString(const Filter& f)
42 | {
43 | std::ostringstream oss;
44 | if ( f.hasQuery() )
45 | oss << AMP << "q=" << urlEncode(f.getQuery());
46 |
47 | if ( f.hasCategory() )
48 | oss << AMP << "category=" << urlEncode(f.getCategory());
49 |
50 | if ( f.hasLang() )
51 | oss << AMP << "lang=" << urlEncode(f.getLang());
52 |
53 | if ( f.hasName() )
54 | oss << AMP << "name=" << urlEncode(f.getName());
55 |
56 | if ( !f.getAcceptTags().empty() )
57 | oss << AMP << "tag=" << urlEncode(join(f.getAcceptTags(), ";"));
58 |
59 | return oss.str();
60 | }
61 |
62 | } // unnamed namespace
63 |
64 | std::string getSearchUrl(const Filter& f)
65 | {
66 | const std::string searchString = buildSearchString(f);
67 |
68 | if ( searchString.empty() )
69 | return opdsSearchEndpoint;
70 | else
71 | return opdsSearchEndpoint + ("?" + searchString);
72 | }
73 |
74 | } // namespace kiwix
75 |
--------------------------------------------------------------------------------
/static/meson.build:
--------------------------------------------------------------------------------
1 | if meson.version().version_compare('>=0.47.0')
2 | resource_files = run_command(
3 | res_manager,
4 | '--list-all',
5 | files('resources_list.txt'),
6 | check: true
7 | ).stdout().strip().split('\n')
8 | else
9 | resource_files = run_command(
10 | res_manager,
11 | '--list-all',
12 | files('resources_list.txt')
13 | ).stdout().strip().split('\n')
14 | endif
15 |
16 |
17 | preprocessed_resources = custom_target('preprocessed_resource_files',
18 | input: 'resources_list.txt',
19 | output: ['resources_list.txt'],
20 | command:[res_manager,
21 | '--preprocess',
22 | '--outdir', '@OUTDIR@',
23 | '@INPUT@'],
24 | depend_files: resource_files
25 | )
26 |
27 | lib_resources = custom_target('resources',
28 | input: [preprocessed_resources, 'i18n_resources_list.txt'],
29 | output: ['libkiwix-resources.cpp', 'libkiwix-resources.h'],
30 | command:[res_compiler,
31 | '--cxxfile', '@OUTPUT0@',
32 | '--hfile', '@OUTPUT1@',
33 | '--source_dir', '@OUTDIR@',
34 | '@INPUT@'],
35 | depends: preprocessed_resources
36 | )
37 |
38 | # This could be replaced with
39 | # ```
40 | # fs = import('fs')
41 | # i18n_resource_files = fs.read('i18n_resources_list.txt').strip().split('\n')
42 | # ```
43 | # once we move to meson >= 0.57.0
44 |
45 | if meson.version().version_compare('>=0.47.0')
46 | i18n_resource_files = run_command(
47 | find_program('python3'),
48 | '-c',
49 | 'import sys; f=open(sys.argv[1]); print(f.read())',
50 | files('i18n_resources_list.txt'),
51 | check: true
52 | ).stdout().strip().split('\n')
53 | else
54 | i18n_resource_files = run_command(
55 | find_program('python3'),
56 | '-c',
57 | 'import sys; f=open(sys.argv[1]); print(f.read())',
58 | files('i18n_resources_list.txt'),
59 | ).stdout().strip().split('\n')
60 | endif
61 |
62 |
63 | i18n_resources = custom_target('i18n_resources',
64 | input: i18n_resource_files,
65 | output: ['libkiwix-i18n-resources.cpp'],
66 | command:[i18n_compiler,
67 | '--cxxfile', '@OUTPUT0@',
68 | '@INPUT@'],
69 | )
70 |
--------------------------------------------------------------------------------
/static/templates/catalog_v2_root.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 | {{feed_id}}
5 |
8 |
11 |
14 | OPDS Catalog Root
15 | {{date}}
16 |
17 |
18 | All entries
19 |
22 | {{date}}
23 | {{all_entries_feed_id}}
24 | All entries from this catalog.
25 |
26 |
27 | All entries (partial)
28 |
31 | {{date}}
32 | {{partial_entries_feed_id}}
33 | All entries from this catalog in partial format.
34 |
35 |
36 | List of categories
37 |
40 | {{date}}
41 | {{category_list_feed_id}}
42 | List of all categories in this catalog.
43 |
44 |
45 | List of languages
46 |
49 | {{date}}
50 | {{language_list_feed_id}}
51 | List of all languages in this catalog.
52 |
53 |
54 |
--------------------------------------------------------------------------------
/test/i18n.cpp:
--------------------------------------------------------------------------------
1 | #include "../src/server/i18n_utils.h"
2 | #include "gtest/gtest.h"
3 |
4 | using namespace kiwix;
5 |
6 | TEST(ParameterizedMessage, parameterlessMessages)
7 | {
8 | {
9 | const ParameterizedMessage msg("404-page-title", {});
10 |
11 | EXPECT_EQ(msg.getText("en"), "Content not found");
12 | EXPECT_EQ(msg.getText("test"), "[I18N TESTING] Not Found - Try Again");
13 | }
14 |
15 | {
16 | // Make sure that msgId influences the result of getText()
17 | const ParameterizedMessage msg("random-page-button-text", {});
18 |
19 | EXPECT_EQ(msg.getText("en"), "Go to a randomly selected page");
20 | EXPECT_EQ(msg.getText("test"), "[I18N TESTING] I am tired of determinism");
21 | }
22 |
23 | {
24 | // Demonstrate that unwanted parameters are silently ignored
25 | const ParameterizedMessage msg("404-page-title", {{"abc", "xyz"}});
26 |
27 | EXPECT_EQ(msg.getText("en"), "Content not found");
28 | EXPECT_EQ(msg.getText("test"), "[I18N TESTING] Not Found - Try Again");
29 | }
30 | }
31 |
32 | TEST(ParameterizedMessage, messagesWithParameters)
33 | {
34 | {
35 | const ParameterizedMessage msg("filter-by-tag",
36 | {{"TAG", "scifi"}}
37 | );
38 |
39 | EXPECT_EQ(msg.getText("en"), "Filter by tag \"scifi\"");
40 | EXPECT_EQ(msg.getText("test"), "Filter [I18N] by [TESTING] tag \"scifi\"");
41 | }
42 |
43 | {
44 | // Omitting expected parameters amounts to using empty values for them
45 | const ParameterizedMessage msg("filter-by-tag", {});
46 |
47 | EXPECT_EQ(msg.getText("en"), "Filter by tag \"\"");
48 | EXPECT_EQ(msg.getText("test"), "Filter [I18N] by [TESTING] tag \"\"");
49 | }
50 | }
51 |
52 | TEST(I18n, translateBookCategory)
53 | {
54 |
55 | EXPECT_EQ(translateBookCategory("en", "ted"), "Ted");
56 | EXPECT_EQ(translateBookCategory("test", "ted"), "[I18N] Ted [TESTING]");
57 |
58 | EXPECT_EQ(translateBookCategory("en", "stack_exchange"), "Stack Exchange");
59 | EXPECT_EQ(translateBookCategory("test", "stack_exchange"), "[I18N] Stack Exchange [TESTING]");
60 |
61 | // unknown categories are simply not translated
62 | EXPECT_EQ(translateBookCategory("en", "Qwerty"), "Qwerty");
63 | EXPECT_EQ(translateBookCategory("test", "Qwerty"), "Qwerty");
64 | }
65 |
--------------------------------------------------------------------------------
/src/libxml_dumper.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2018 Matthieu Gautier
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #ifndef KIWIX_LIBXML_DUMPER_H
21 | #define KIWIX_LIBXML_DUMPER_H
22 |
23 | #include
24 | #include
25 |
26 | #include
27 |
28 | #include "library.h"
29 |
30 | namespace kiwix
31 | {
32 |
33 | /**
34 | * A tool to dump a `Library` into a basic library.xml
35 | *
36 | */
37 | class LibXMLDumper
38 | {
39 | public:
40 | LibXMLDumper() = default;
41 | LibXMLDumper(const Library* library);
42 | ~LibXMLDumper();
43 |
44 | /**
45 | * Dump the library.xml
46 | *
47 | * @param id The id of the library.
48 | * @return The library.xml content.
49 | */
50 | std::string dumpLibXMLContent(const std::vector& bookIds);
51 |
52 |
53 | /**
54 | * Dump the bookmark of the library.
55 | *
56 | * @return The bookmark.xml content.
57 | */
58 | std::string dumpLibXMLBookmark();
59 |
60 | /**
61 | * Set the base directory used.
62 | *
63 | * @param baseDir the base directory to use.
64 | */
65 | void setBaseDir(const std::string& baseDir) { this->baseDir = baseDir; }
66 |
67 | /**
68 | * Set the library to dump.
69 | *
70 | * @param library The library to dump.
71 | */
72 | void setLibrary(const Library* library) { this->library = library; }
73 |
74 | protected:
75 | const kiwix::Library* library;
76 | std::string baseDir;
77 | private:
78 | void handleBook(Book book, pugi::xml_node root_node);
79 | void handleBookmark(Bookmark bookmark, pugi::xml_node root_node);
80 | };
81 | }
82 |
83 | #endif // KIWIX_OPDS_DUMPER_H
84 |
--------------------------------------------------------------------------------
/src/tools/archiveTools.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Maneesh P M
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #ifndef KIWIX_ARCHIVETOOLS_H
21 | #define KIWIX_ARCHIVETOOLS_H
22 |
23 | #include
24 | #include
25 |
26 | /**
27 | * This file contains all the functions that would make handling data related to
28 | * an archive easier.
29 | **/
30 |
31 | namespace kiwix
32 | {
33 | std::string getMetadata(const zim::Archive& archive, const std::string& name);
34 | std::string getArchiveTitle(const zim::Archive& archive);
35 | std::string getMetaDescription(const zim::Archive& archive);
36 | std::string getMetaTags(const zim::Archive& archive, bool original = false);
37 | std::string getMetaLanguage(const zim::Archive& archive);
38 | std::string getMetaName(const zim::Archive& archive);
39 | std::string getMetaDate(const zim::Archive& archive);
40 | std::string getMetaCreator(const zim::Archive& archive);
41 | std::string getMetaPublisher(const zim::Archive& archive);
42 | std::string getMetaFlavour(const zim::Archive& archive);
43 |
44 | bool getArchiveFavicon(const zim::Archive& archive, unsigned size,
45 | std::string& content, std::string& mimeType);
46 |
47 | unsigned int getArchiveMediaCount(const zim::Archive& archive);
48 | unsigned int getArchiveArticleCount(const zim::Archive& archive);
49 | unsigned int getArchiveFileSize(const zim::Archive& archive);
50 |
51 | zim::Item getFinalItem(const zim::Archive& archive, const zim::Entry& entry);
52 |
53 | zim::Entry getEntryFromPath(const zim::Archive& archive, const std::string& path);
54 | }
55 |
56 | #endif
57 |
--------------------------------------------------------------------------------
/docs/conf.py:
--------------------------------------------------------------------------------
1 | # Configuration file for the Sphinx documentation builder.
2 | #
3 | # This file only contains a selection of the most common options. For a full
4 | # list see the documentation:
5 | # https://www.sphinx-doc.org/en/master/usage/configuration.html
6 |
7 | # -- Path setup --------------------------------------------------------------
8 |
9 | # If extensions (or modules to document with autodoc) are in another directory,
10 | # add these directories to sys.path here. If the directory is relative to the
11 | # documentation root, use os.path.abspath to make it absolute, like shown here.
12 | #
13 | import os
14 | # import sys
15 | # sys.path.insert(0, os.path.abspath('.'))
16 |
17 |
18 | # -- Project information -----------------------------------------------------
19 |
20 | project = 'libkiwix'
21 | copyright = '2022, libkiwix-team'
22 | author = 'libkiwix-team'
23 |
24 |
25 | # -- General configuration ---------------------------------------------------
26 |
27 | # Add any Sphinx extension module names here, as strings. They can be
28 | # extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
29 | # ones.
30 | extensions = [
31 | 'breathe',
32 | 'exhale'
33 | ]
34 |
35 | # Add any paths that contain templates here, relative to this directory.
36 | templates_path = ['_templates']
37 |
38 | # List of patterns, relative to source directory, that match files and
39 | # directories to ignore when looking for source files.
40 | # This pattern also affects html_static_path and html_extra_path.
41 | exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
42 |
43 | html_theme = 'sphinx_rtd_theme'
44 |
45 | # Add any paths that contain custom static files (such as style sheets) here,
46 | # relative to this directory. They are copied after the builtin static files,
47 | # so a file named "default.css" will overwrite the builtin "default.css".
48 | html_static_path = ['_static']
49 |
50 | breathe_projects = {
51 | "libkiwix": "./xml"
52 | }
53 | breathe_default_project = 'libkiwix'
54 |
55 | exhale_args = {
56 | "containmentFolder": "./api",
57 | "rootFileName": "ref_api.rst",
58 | "rootFileTitle": "Reference API",
59 | "doxygenStripFromPath":"..",
60 | "treeViewIsBootstrap": True,
61 | "createTreeView" : True,
62 | "exhaleExecutesDoxygen": True,
63 | "exhaleDoxygenStdin": "INPUT = ../include"
64 | }
65 |
66 | primary_domain = 'cpp'
67 |
68 | highlight_language = 'cpp'
69 |
--------------------------------------------------------------------------------
/src/server/i18n_utils.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Veloman Yunkan
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #ifndef KIWIX_SERVER_I18N_UTILS
21 | #define KIWIX_SERVER_I18N_UTILS
22 |
23 | #include "i18n.h"
24 | #include
25 |
26 | namespace kiwix
27 | {
28 |
29 | struct I18nString {
30 | const char* const key;
31 | const char* const value;
32 | };
33 |
34 | struct I18nStringTable {
35 | const char* const lang;
36 | const size_t entryCount;
37 | const I18nString* const entries;
38 |
39 | const char* get(const std::string& key) const;
40 | };
41 |
42 | namespace i18n
43 | {
44 |
45 | class GetTranslatedStringWithMsgId
46 | {
47 | typedef kainjow::mustache::basic_data MustacheString;
48 | typedef std::pair MsgIdAndTranslation;
49 |
50 | public:
51 | explicit GetTranslatedStringWithMsgId(const std::string& lang) : m_lang(lang) {}
52 |
53 | MsgIdAndTranslation operator()(const std::string& key) const
54 | {
55 | return {key, getTranslatedString(m_lang, key)};
56 | }
57 |
58 | MsgIdAndTranslation operator()(const std::string& key, const Parameters& params) const
59 | {
60 | return {key, expandParameterizedString(m_lang, key, params)};
61 | }
62 |
63 | private:
64 | const std::string m_lang;
65 | };
66 |
67 | } // namespace i18n
68 |
69 | struct LangPreference
70 | {
71 | const std::string lang;
72 | const float preference;
73 | };
74 |
75 | typedef std::vector UserLangPreferences;
76 |
77 | UserLangPreferences parseUserLanguagePreferences(const std::string& s);
78 |
79 | std::string selectMostSuitableLanguage(const UserLangPreferences& prefs);
80 |
81 | } // namespace kiwix
82 |
83 | #endif // KIWIX_SERVER_I18N_UTILS
84 |
--------------------------------------------------------------------------------
/test/data/library.xml:
--------------------------------------------------------------------------------
1 |
2 |
20 |
37 |
54 |
55 |
--------------------------------------------------------------------------------
/static/skin/i18n/fi.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "MITO",
5 | "Nike",
6 | "Pyscowicz",
7 | "Samoasambia"
8 | ]
9 | },
10 | "name": "suomi",
11 | "suggest-full-text-search": "sisältää '{{{SEARCH_TERMS}}}'...",
12 | "no-such-book": "Kirjaa {{BOOK_NAME}} ei ole olemassa",
13 | "url-not-found": "Pyydettyä URL-osoitetta \"{{url}}\" ei löytynyt tältä palvelimelta.",
14 | "400-page-title": "Virheellinen pyyntö",
15 | "400-page-heading": "Virheellinen pyyntö",
16 | "404-page-title": "Sisältöä ei löytynyt",
17 | "404-page-heading": "Ei löytynyt",
18 | "new-404-page-title": "Sivua ei löytynyt",
19 | "new-404-page-heading": "Hupsista. Artikkelia ei löytynyt.",
20 | "404-img-text": "Ei löytynyt!",
21 | "path-was-not-found": "Pyydettyä polkua ei löytynyt:",
22 | "500-page-title": "Sisäinen palvelinvirhe",
23 | "500-page-heading": "Hupsista. Sivu ei toimi.",
24 | "500-img-text": "Sivu ei toimi",
25 | "external-link-detected": "Ulkoinen linkki havaittu",
26 | "caution-warning": "Huomio!",
27 | "external-link-intro": "Olet poistumassa Kiwixin ZIM-lukijasta siirtyäksesi verkkoon",
28 | "search-results-page-title": "Haku: {{SEARCH_PATTERN}}",
29 | "word-count": "{{COUNT}} sanaa",
30 | "library-button-text": "Siirry tervetulosivulle",
31 | "home-button-text": "Siirry kirjan '{{{BOOK_TITLE}}}' etusivulle",
32 | "random-page-button-text": "Siirry satunnaiselle sivulle",
33 | "searchbox-tooltip": "Hae kirjasta '{{{BOOK_TITLE}}}'",
34 | "search": "Hae",
35 | "book-filtering-all-categories": "Kaikki luokat",
36 | "book-filtering-all-languages": "Kaikki kielet",
37 | "count-of-matching-books": "{{COUNT}} kirja(a)",
38 | "download": "Lataa",
39 | "magnet-link-text": "Magnet-linkki",
40 | "magnet-alt-text": "lataa magnet",
41 | "torrent-download-link-text": "BitTorrent",
42 | "torrent-download-alt-text": "lataa torrent-tiedosto",
43 | "filter-by-tag": "Suodata tunnisteen ”{{TAG}}” mukaan",
44 | "download-links-title": "Lataa kirja",
45 | "preview-book": "Esikatsele",
46 | "unknown-error": "Tuntematon virhe",
47 | "book-category.wikibooks": "Wikikirjasto",
48 | "book-category.wikinews": "Wikiuutiset",
49 | "book-category.wikipedia": "Wikipedia",
50 | "book-category.wikiquote": "Wikisitaatit",
51 | "book-category.wikisource": "Wikiaineisto",
52 | "book-category.wikispecies": "Wikispecies",
53 | "book-category.wikiversity": "Wikiopisto",
54 | "book-category.wikivoyage": "Wikimatkat",
55 | "book-category.wiktionary": "Wikisanakirja",
56 | "book-category.other": "Muu",
57 | "text-loading-content": "Ladataan sisältöä"
58 | }
59 |
--------------------------------------------------------------------------------
/src/tools/languageTools.cpp:
--------------------------------------------------------------------------------
1 | #include "tools.h"
2 | #include "stringTools.h"
3 | #include
4 |
5 | namespace kiwix
6 | {
7 |
8 | namespace
9 | {
10 |
11 | // These mappings are not provided by the ICU library, any such mappings can be manually added here
12 | std::map iso639_3 = {
13 | {"ami", "Amis"},
14 | {"atj", "atikamekw"},
15 | {"azb", "آذربایجان دیلی"},
16 | {"bcl", "central bikol"},
17 | {"bgs", "tagabawa"},
18 | {"blk", "ပအိုဝ်ႏ"},
19 | {"bxr", "буряад хэлэн"},
20 | {"cbk", "chavacano"},
21 | {"cdo", "閩東語"},
22 | {"dag", "Dagbani"},
23 | {"diq", "dimli"},
24 | {"dty", "डोटेली"},
25 | {"eml", "emiliân-rumagnōl"},
26 | {"fbs", "српскохрватски"},
27 | {"fon", "fɔ̀ngbè"},
28 | {"gcr", "Kriyòl gwiyannen"},
29 | {"guw", "Gungbe"},
30 | {"hbs", "srpskohrvatski"},
31 | {"hyw", "հայերէն/հայերեն"},
32 | {"ido", "ido"},
33 | {"kbp", "kabɩyɛ"},
34 | {"kld", "Gamilaraay"},
35 | {"lbe", "лакку маз"},
36 | {"lbj", "ལ་དྭགས་སྐད་"},
37 | {"lld", "ladin"},
38 | {"map", "Austronesian"},
39 | {"mhr", "марий йылме"},
40 | {"mnw", "ဘာသာမန်"},
41 | {"myn", "mayan"},
42 | {"nah", "nahuatl"},
43 | {"nai", "north American Indian"},
44 | {"nds", "plattdütsch"},
45 | {"nrm", "bhasa narom"},
46 | {"olo", "livvi"},
47 | {"pih", "Pitcairn-Norfolk"},
48 | {"pnb", "Western Panjabi"},
49 | {"pwn", "Pinayuanan"},
50 | {"rmr", "Caló"},
51 | {"rmy", "romani shib"},
52 | {"roa", "romance languages"},
53 | {"skr", "سرائیکی"},
54 | {"szy", "Sakizaya"},
55 | {"tay", "Tayal"},
56 | {"tgl", "Wikang Tagalog"},
57 | {"twi", "Akwapem Twi"},
58 | // ICU for Ubuntu versions <= focal (20.04) returns "" for the language code ""
59 | // unlike the later versions - which returns "und". We map this value to "Undetermined" for a common ground.
60 | {"", "Undetermined"},
61 | };
62 |
63 | std::once_flag fillLanguagesFlag;
64 |
65 | void fillLanguagesMap()
66 | {
67 | for (auto icuLangPtr = icu::Locale::getISOLanguages(); *icuLangPtr != NULL; ++icuLangPtr) {
68 | const kiwix::ICULanguageInfo lang(*icuLangPtr);
69 | iso639_3.insert({lang.iso3Code(), lang.selfName()});
70 | }
71 | iso639_3.erase("mul");
72 | }
73 |
74 | } // unnamed namespace
75 |
76 | std::string getLanguageSelfName(const std::string& lang)
77 | {
78 | std::call_once(fillLanguagesFlag, fillLanguagesMap);
79 | const auto itr = iso639_3.find(lang);
80 | if (itr != iso639_3.end()) {
81 | return itr->second;
82 | }
83 | return lang;
84 | };
85 |
86 | } // namespace kiwix
87 |
--------------------------------------------------------------------------------
/static/generate_i18n_resources_list.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env python3
2 | # Copyright (c) 2020 Matthieu Gautier
3 | #
4 | # This file is part of libkiwix.
5 | #
6 | # This program is free software: you can redistribute it and/or modify
7 | # it under the terms of the GNU General Public License as published by
8 | # the Free Software Foundation, either version 3 of the License, or
9 | # (at your option) any later version.
10 |
11 | # This program is distributed in the hope that it will be useful,
12 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 | # GNU General Public License for more details.
15 |
16 | # You should have received a copy of the GNU General Public License
17 | # along with this program. If not, see .
18 |
19 | from pathlib import Path
20 | import json
21 |
22 | script_path = Path(__file__)
23 |
24 | resource_file = script_path.parent / "i18n_resources_list.txt"
25 | translation_dir = script_path.parent / "skin/i18n"
26 | language_list_relpath = "skin/languages.js"
27 |
28 | def get_translation_info(filepath):
29 | lang_code = Path(filepath).stem
30 | with open(filepath, 'r', encoding="utf-8") as f:
31 | content = json.load(f)
32 | lang_name = content.get("name")
33 | translation_count = len(content)
34 | return dict(iso_code=lang_code,
35 | self_name=lang_name,
36 | translation_count=translation_count)
37 |
38 | language_list = []
39 | json_files = translation_dir.glob("*.json")
40 | with open(resource_file, 'w', encoding="utf-8") as f:
41 | for i18n_file in sorted(translation_dir.glob("*.json")):
42 | if i18n_file.name == "qqq.json":
43 | continue
44 | print("Processing", i18n_file.name)
45 | if i18n_file.name != "test.json":
46 | translation_info = get_translation_info(i18n_file)
47 | lang_name = translation_info["self_name"]
48 | if lang_name:
49 | language_list.append(translation_info)
50 | else:
51 | print(f"Warning: missing 'name' in {i18n_file.name}")
52 | f.write(str(i18n_file.relative_to(script_path.parent)) + '\n')
53 |
54 | language_list_jsobj_str = json.dumps(language_list,
55 | indent=2,
56 | ensure_ascii=False)
57 | print("Saving", language_list_relpath)
58 | fullpath = script_path.parent / language_list_relpath
59 | with open(fullpath, 'w', encoding="utf-8") as f:
60 | f.write("const uiLanguages = " + language_list_jsobj_str)
61 |
--------------------------------------------------------------------------------
/static/skin/autoComplete/css/autoComplete.css:
--------------------------------------------------------------------------------
1 | /* Modified from https://github.com/TarekRaafat/autoComplete.js (version 10.2.6)*/
2 | .autoComplete_wrapper {
3 | display: inline-block;
4 | position: relative;
5 | }
6 |
7 | .autoComplete_wrapper > input {
8 | width: 370px;
9 | height: 40px;
10 | padding-left: 20px;
11 | font-size: 1rem;
12 | color: rgba(123, 123, 123, 1);
13 | border-radius: 8px;
14 | border: 0;
15 | outline: none;
16 | background-color: #f1f3f4;
17 | }
18 |
19 | .autoComplete_wrapper > input::placeholder {
20 | color: rgba(123, 123, 123, 0.5);
21 | transition: all 0.3s ease;
22 | }
23 |
24 | .autoComplete_wrapper > ul {
25 | position: absolute;
26 | min-width: 100%;
27 | width: fit-content;
28 | max-width: 600px;
29 | max-height: 226px;
30 | overflow-y: scroll;
31 | top: 100%;
32 | left: 0;
33 | right: 0;
34 | padding: 0;
35 | margin: 0.5rem 0 0;
36 | border-radius: 0.6rem;
37 | background-color: #fff;
38 | box-shadow: 0 3px 6px rgba(149, 157, 165, 0.15);
39 | border: 1px solid rgba(33, 33, 33, 0.07);
40 | z-index: 1000;
41 | outline: none;
42 | }
43 |
44 | .autoComplete_wrapper > ul[hidden],
45 | .autoComplete_wrapper > ul:empty {
46 | display: block;
47 | opacity: 0;
48 | transform: scale(0);
49 | }
50 |
51 | .autoComplete_wrapper > ul > li {
52 | margin: 0.3rem;
53 | padding: 0.3rem 0.5rem;
54 | list-style: none;
55 | text-align: left;
56 | font-size: 1rem;
57 | color: #212121;
58 | border-radius: 0.35rem;
59 | background-color: rgba(255, 255, 255, 1);
60 | white-space: nowrap;
61 | overflow: hidden;
62 | text-overflow: ellipsis;
63 | transition: all 0.2s ease;
64 | }
65 |
66 | .autoComplete_wrapper > ul > li > a {
67 | overflow: hidden;
68 | text-overflow: ellipsis;
69 | }
70 |
71 | .autoComplete_wrapper > ul > li::selection {
72 | color: rgba(#ffffff, 0);
73 | background-color: rgba(#ffffff, 0);
74 | }
75 |
76 | .autoComplete_wrapper > ul > li:hover {
77 | cursor: pointer;
78 | background-color: rgba(123, 123, 123, 0.1);
79 | }
80 |
81 | .autoComplete_wrapper > ul > li mark {
82 | background-color: transparent;
83 | color: rgba(255, 122, 122, 1);
84 | font-weight: bold;
85 | }
86 |
87 | .autoComplete_wrapper > ul > li mark::selection {
88 | color: rgba(#ffffff, 0);
89 | background-color: rgba(#ffffff, 0);
90 | }
91 |
92 | .autoComplete_wrapper > ul > li[aria-selected="true"] {
93 | background-color: rgba(123, 123, 123, 0.1);
94 | }
95 |
96 | @media only screen and (max-width: 600px) {
97 | .autoComplete_wrapper > input {
98 | width: 18rem;
99 | }
100 | }
101 |
--------------------------------------------------------------------------------
/static/skin/i18n/ar.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "Asma",
5 | "Hamoudak",
6 | "Meno25",
7 | "Mohammed Qays",
8 | "Ravan",
9 | "محمد أحمد عبد الفتاح"
10 | ]
11 | },
12 | "name": "الإنجليزية",
13 | "no-such-book": "لا يوجد مثل هذا الكتاب: {{BOOK_NAME}}",
14 | "too-many-books": "طلب العديد من الكتب {{NB_BOOKS}} حيث الحد {{LIMIT}}",
15 | "no-book-found": "لا يوجد كتاب يطابق معايير الاختيار",
16 | "url-not-found": "لم يتم العثور على عنوان URL المطلوب \"{{url}}\" على هذا الخادم.",
17 | "suggest-search": "قم بإجراء بحث عن النص الكامل لـ {{PATTERN}}",
18 | "random-article-failure": "للأسف ! فشل في اختيار مقال عشوائي :(",
19 | "invalid-raw-data-type": "{{DATATYPE}} ليس طلبًا صالحًا للمحتوى الأولي.",
20 | "no-value-for-arg": "لم يتم تقديم قيمة للوسيطة {{ARGUMENT}}",
21 | "no-query": "لم يتم تقديم ملخص.",
22 | "raw-entry-not-found": "لا يمكن العثور على إدخال {{DATATYPE}} {{ENTRY}}",
23 | "400-page-title": "طلب غير صالح",
24 | "400-page-heading": "طلب غير صالح",
25 | "404-page-title": "المحتوى غير موجود",
26 | "404-page-heading": "لم يتم العثور عليه",
27 | "500-page-title": "خطأ داخلي بالخادم",
28 | "500-page-heading": "عفواً، الصفحة لا تعمل.",
29 | "500-page-text": "لا يمكن إرسال المسار المطلوب بشكل صحيح:",
30 | "fulltext-search-unavailable": "البحث في كامل النص غير متاح",
31 | "no-search-results": "محرك البحث في كامل النص غير متوفر لهذا المحتوي.",
32 | "library-button-text": "توجه إلي صفحة الترحيب",
33 | "home-button-text": "انتقل إلى الصفحة الرئيسة لـ '{{{BOOK_TITLE}}}'",
34 | "random-page-button-text": "اذهب إلى صفحة عشوائية",
35 | "searchbox-tooltip": "ابحث عن '{{{BOOK_TITLE}}}'",
36 | "confusion-of-tongues": "قد يشارك في البحث كتابان أو أكثر بلغات مختلفة، مما قد يؤدي إلى نتائج محيرة.",
37 | "direct-download-alt-text": "التنزيل مباشرة عبر بروتوكول HTTP(S)",
38 | "hash-download-link-text": "المجموع الإختباري لخوارزمية SHA-256",
39 | "hash-download-alt-text": "عرض المجموع الإختباري لخوارزمية SHA-256 للملف",
40 | "magnet-link-text": "رابط جاذب",
41 | "magnet-alt-text": "التنزيل بواسطة الرابط الجاذب",
42 | "torrent-download-link-text": "بت تورنت",
43 | "torrent-download-alt-text": "التنزيل بواسطة بت تورنت",
44 | "unknown-error": "خطأ غير معروف",
45 | "book-category.wikibooks": "ويكي الكتب",
46 | "book-category.wikinews": "ويكي الأخبار",
47 | "book-category.wikipedia": "ويكيبيديا",
48 | "book-category.wikiquote": "ويكي الإقتباس",
49 | "book-category.wikisource": "ويكي مصدر",
50 | "book-category.wikispecies": "ويكي أنواع",
51 | "book-category.wikiversity": "ويكي الجامعة",
52 | "book-category.wikivoyage": "ويكي الرحلات",
53 | "book-category.wiktionary": "ويكي القاموس",
54 | "book-category.other": "أخرى {كتب أخري}"
55 | }
56 |
--------------------------------------------------------------------------------
/test/opds_catalog.cpp:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2021 Veloman Yunkan
3 | *
4 | * This program is free software; you can redistribute it and/or
5 | * modify it under the terms of the GNU General Public License as
6 | * published by the Free Software Foundation; either version 2 of the
7 | * License, or (at your option) any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful, but
10 | * is provided AS IS, WITHOUT ANY WARRANTY; without even the implied
11 | * warranty of MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, and
12 | * NON-INFRINGEMENT. See the GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 | *
18 | */
19 |
20 | #include "../include/opds_catalog.h"
21 |
22 | #include "gtest/gtest.h"
23 |
24 | using namespace kiwix;
25 |
26 | TEST(OpdsCatalog, getSearchUrl)
27 | {
28 | #define EXPECT_SEARCH_URL(url) EXPECT_EQ(url, getSearchUrl(f))
29 | {
30 | Filter f;
31 | EXPECT_SEARCH_URL("/catalog/v2/entries");
32 | }
33 | {
34 | Filter f;
35 | f.query("abc");
36 | EXPECT_SEARCH_URL("/catalog/v2/entries?q=abc");
37 | }
38 | {
39 | Filter f;
40 | f.query("abc def#xyz");
41 | EXPECT_SEARCH_URL("/catalog/v2/entries?q=abc%20def%23xyz");
42 | }
43 | {
44 | Filter f;
45 | f.category("ted&bob");
46 | EXPECT_SEARCH_URL("/catalog/v2/entries?category=ted%26bob");
47 | }
48 | {
49 | Filter f;
50 | f.lang("eng,fra");
51 | EXPECT_SEARCH_URL("/catalog/v2/entries?lang=eng%2Cfra");
52 | }
53 | {
54 | Filter f;
55 | f.name("second?");
56 | EXPECT_SEARCH_URL("/catalog/v2/entries?name=second%3F");
57 | }
58 | {
59 | Filter f;
60 | f.acceptTags({"#paper", "#plastic"});
61 | EXPECT_SEARCH_URL("/catalog/v2/entries?tag=%23paper%3B%23plastic");
62 | }
63 | {
64 | Filter f;
65 | f.query("abc=123");
66 | f.category("@ted");
67 | EXPECT_SEARCH_URL("/catalog/v2/entries?q=abc%3D123&category=%40ted");
68 | }
69 | {
70 | Filter f;
71 | f.category("ted");
72 | f.query("abc");
73 | EXPECT_SEARCH_URL("/catalog/v2/entries?q=abc&category=ted");
74 | }
75 | {
76 | Filter f;
77 | f.query("peru");
78 | f.category("scifi");
79 | f.lang("html");
80 | f.name("edsonarantesdonascimento");
81 | f.acceptTags({"body", "script"});
82 | EXPECT_SEARCH_URL("/catalog/v2/entries?q=peru&category=scifi&lang=html&name=edsonarantesdonascimento&tag=body%3Bscript");
83 | }
84 | #undef EXPECT_SEARCH_URL
85 | }
86 |
--------------------------------------------------------------------------------
/static/skin/i18n/nqo.json:
--------------------------------------------------------------------------------
1 | {
2 | "@metadata": {
3 | "authors": [
4 | "Lancine.kounfantoh.fofana"
5 | ]
6 | },
7 | "name": "ߒߞߏ",
8 | "suggest-full-text-search": "ߞߣߐߞߍߣߍ߲߫ ߦߋ߫ '{{{SEARCH_TERMS}}}'...",
9 | "no-such-book": "ߞߊ߬ߝߊ߫ ߛߎ߮ ߏ߬ ߕߴߦߋ߲߬: {{BOOK_NAME}}",
10 | "too-many-books": "ߞߝߊ߬ ߛߌߦߊߡߊ߲߫ ߡߊߢߌ߬ߣߌ߲߬ߞߊ߬ߣߍ߲߫ ߞߏߖߎ߰ {{NB_BOOKS}} ߡߍ߲ ߞߐߘߊ߲ ߦߋ߫ {{LIMIT}} ߘߌ߫",
11 | "no-book-found": "ߞߝߊ߬ ߛߌ߫ ߓߍ߬ߣߍ߲߬ ߕߍ߫ ߛߎߥߊ߲ߘߟߌ ߛߙߊߕߌ ߏ߬ ߡߊ߬",
12 | "url-not-found": "ߍ߲߬ߤߍ߲߫ ''URL ''{{url}} ߡߊߢߌ߬ߣߌ߲߬ߞߊ߬ߣߍ߲ ߡߊ߫ ߛߐ߬ߘߐ߲߫ ߡߊ߬ߟߐ߬ߟߊ߲ ߣߌ߲߬ ߠߊ߫.",
13 | "suggest-search": "ߛߓߍߟߌ߫ ߘߝߊߣߍ߲ ߢߌߣߌ߲ߠߌ߲ ߞߍ߫ {{PATTERN}}",
14 | "random-article-failure": "ߏ߯߹ ߞߢߊ߬ ߓߘߊ߫ ߞߍ߫ ߓߍ߲߬ߛߋ߲߬ߡߊ߬ ߞߎߡߘߊ ߛߐ߬ߘߐ߲߬ ߠߊ߫:(",
15 | "invalid-raw-data-type": "{{DATATYPE}} ߕߍ߫ ߡߞߊ߬ߣߌ߲߬ߣߍ߲߫ ߓߍ߲߬ߣߍ߲߫ ߘߌ߫ ߞߣߐߘߐ߫ ߘߝߊߣߍ߲ ߞߊ߲ߡߊ߬.",
16 | "no-value-for-arg": "ߡߐ߬ߟߐ߲߬ ߡߊ߫ ߡߊߛߐ߫ ߘߊߘߐߡߌߣߊߞߎ߲ߧߊ {{ARGUMENT}} ߞߊ߲ߡߊ߬",
17 | "no-query": "ߡߞߊ߬ߣߌ߲߬ߠߌ߲߫ ߛߌ߫ ߡߊ߫ ߡߊߛߐ߫.",
18 | "raw-entry-not-found": "ߟߊ߬ߘߏ߲߬ߣߍ߲ {{ENTRY}} {{DATATYPE}} ߕߍ߫ ߣߊ߬ ߡߊߛߐ߬ߘߐ߲߫ ߠߊ߫",
19 | "400-page-title": "ߡߞߊ߬ߣߌ߲߬ߠߌ߲߫ ߓߍ߲߬ߓߊߟߌ",
20 | "400-page-heading": "ߡߞߊ߬ߣߌ߲߬ߠߌ߲߫ ߓߍ߲߬ߓߊߟߌ",
21 | "404-page-title": "ߞߣߐߘߐ ߡߊ߫ ߛߐ߬ߘߐ߲߫",
22 | "404-page-heading": "ߡߊ߫ ߛߐ߬ߘߐ߲߫",
23 | "500-page-title": "ߞߣߐߟߊ ߡߊ߬ߛߐ߬ߟߊ߲ ߝߎ߬ߕߎ߲߬ߕߌ",
24 | "500-page-heading": "ߞߣߐߟߊ ߡߊ߬ߛߐ߬ߟߊ߲ ߝߎ߬ߕߎ߲߬ߕߌ",
25 | "fulltext-search-unavailable": "ߛߓߍߟߌ߫ ߘߝߊߣߍ߲ ߢߌߣߌ߲ߠߌ߲ ߕߍ߫ ߦߋ߲߬",
26 | "no-search-results": "ߛߓߍߟߌ߫ ߘߝߊߣߍ߲ ߢߌߣߌ߲ߠߌ߲߫ ߣߌߘߐ ߕߍ߫ ߦߋ߲߬ ߞߣߐߘߐ ߣߌ߲߬ ߢߍ߫.",
27 | "library-button-text": "ߕߊ߯ ߟߊ߬ߛߣߍ߬ߟߌ߫ ߞߐߜߍ ߞߊ߲߬",
28 | "home-button-text": "ߕߊ߯ {{BOOK_TITLE}} ߓߏ߬ߟߏ߲߬ߘߊ ߞߐߜߍ ߞߊ߲߬",
29 | "random-page-button-text": "ߕߊ߯ ߓߍ߲߬ߛߋ߲߬ߡߊ߬ ߞߐߜߍ߫ ߛߎߥߊ߲ߘߌߣߍ߲ ߠߎ߬ ߞߊ߲߬",
30 | "searchbox-tooltip": "ߕߌߙߌ߲ߠߌ߲ {{BOOK_TITLE}}",
31 | "confusion-of-tongues": "ߞߊ߬ߝߊ߫ ߝߌ߬ߟߊ߬ ߥߟߊ߫ ߦߙߌߞߊ ߞߊ߲߫ ߜߘߍ ߟߎ߬ ߘߐ߫߸ ߏ߬ ߟߎ߫ ߘߌߣߊ߬ ߕߘߍ߬ ߢߌߣߌ߲ߠߌ߲ ߘߐ߫߸ ߡߍ߲ ߠߎ߬ ߛߌ߫ ߞߣߐ߬ߝߟߌ ߟߊߘߏ߲߬ ߠߊ߫ ߞߐߝߟߌ ߘߐ߫.",
32 | "welcome-page-overzealous-filter": "ߞߐߝߟߌ߫ ߕߴߦߋ߲߬. ߊ߬ ߝߐ߫ ߌ ߦߴߊ߬ ߝߍ߬ ߞߊ߬ ߛߍ߲ߛߍ߲ߟߊ߲ ߘߐߛߌ߰ ߕߎ߲߯؟",
33 | "search": "ߢߌߣߌ߲ߠߌ߲",
34 | "book-filtering-all-categories": "ߦߌߟߡߊ ߟߎ߬ ߓߍ߯",
35 | "book-filtering-all-languages": "ߞߊ߲ ߠߎ߬ ߓߍ߯",
36 | "count-of-matching-books": "ߞߊ߬ߝߊ {{COUNT}}(ߟߎ߫)",
37 | "download": "ߟߊ߬ߖߌ߰ߒ߬ߞߎ߲߬ߠߌ߲",
38 | "direct-download-link-text": "ߒߕߋߟߋ߲ߡߊ߬",
39 | "direct-download-alt-text": "ߟߊ߬ߖߌ߰ߒ߬ߞߎ߲߬ߠߌ߲߫ ߝߊ߲ߞߢߊ",
40 | "hash-download-alt-text": "ߤߊߛ߭ ߟߊߖߌ߰ ߌ ߞߎ߲߬",
41 | "magnet-link-text": "ߡߊߢߍߕ ߛߘߌ߬ߜߋ߲",
42 | "magnet-alt-text": "ߡߊߢߍߕ ߟߊߖߌ߰ ߌ ߞߎ߲߬",
43 | "torrent-download-link-text": "ߕߏߙߍ߲ߕ ߞߐߕߐ߮",
44 | "torrent-download-alt-text": "ߕߏߙߍ߲ߕ ߟߊߖߌ߰ ߌ ߞߎ߲߬",
45 | "welcome-to-kiwix-server": "ߌ ߣߌ߫ ߛߣߍ߫ ߞߥߌߞߛ ߡߊߛߐߟߊ߲ ߞߣߐ߫",
46 | "download-links-heading": "{{BOOK_TITLE}} ߛߘߌ߬ߜߋ߲ ߠߊߖߌ߰ ߌ ߞߎ߲߬",
47 | "download-links-title": "ߞߊ߬ߝߊ ߟߊߖߌ߰ ߌ ߞߎ߲߬",
48 | "preview-book": "ߊ߬ ߘߐߜߍ߫ ߡߎߣߎ߲߬"
49 | }
50 |
--------------------------------------------------------------------------------
/src/opds_dumper.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2017 Matthieu Gautier
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #ifndef KIWIX_OPDS_DUMPER_H
21 | #define KIWIX_OPDS_DUMPER_H
22 |
23 | #include
24 | #include
25 | #include
26 |
27 | #include
28 |
29 | #include "library.h"
30 | #include "name_mapper.h"
31 | #include "library_dumper.h"
32 |
33 | using namespace std;
34 |
35 | namespace kiwix
36 | {
37 |
38 | /**
39 | * A tool to dump a `Library` into a opds stream.
40 | *
41 | */
42 | class OPDSDumper : public LibraryDumper
43 | {
44 | public:
45 | OPDSDumper(const Library* library, const NameMapper* NameMapper);
46 | ~OPDSDumper();
47 |
48 | /**
49 | * Dump the OPDS feed.
50 | *
51 | * @param bookIds the ids of the books to include in the feed
52 | * @param query the query used to obtain the list of book ids
53 | * @return The OPDS feed.
54 | */
55 | std::string dumpOPDSFeed(const std::vector& bookIds, const std::string& query) const;
56 |
57 | /**
58 | * Dump the OPDS feed.
59 | *
60 | * @param bookIds the ids of the books to include in the feed
61 | * @param query the query used to obtain the list of book ids
62 | * @param partial whether the feed should include partial or complete entries
63 | * @return The OPDS feed.
64 | */
65 | std::string dumpOPDSFeedV2(const std::vector& bookIds, const std::string& query, bool partial) const;
66 |
67 | /**
68 | * Dump the OPDS complete entry document.
69 | *
70 | * @param bookId the id of the book
71 | * @return The OPDS complete entry document.
72 | */
73 | std::string dumpOPDSCompleteEntry(const std::string& bookId) const;
74 |
75 | /**
76 | * Dump the categories OPDS feed.
77 | *
78 | * @return The OPDS feed.
79 | */
80 | std::string categoriesOPDSFeed() const;
81 |
82 | /**
83 | * Dump the languages OPDS feed.
84 | *
85 | * @return The OPDS feed.
86 | */
87 | std::string languagesOPDSFeed() const;
88 | };
89 | }
90 |
91 | #endif // KIWIX_OPDS_DUMPER_H
92 |
--------------------------------------------------------------------------------
/include/name_mapper.h:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2019 Matthieu Gautier
3 | *
4 | * This program is free software; you can redistribute it and/or modify
5 | * it under the terms of the GNU General Public License as published by
6 | * the Free Software Foundation; either version 3 of the License, or
7 | * any later version.
8 | *
9 | * This program is distributed in the hope that it will be useful,
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 | * GNU General Public License for more details.
13 | *
14 | * You should have received a copy of the GNU General Public License
15 | * along with this program; if not, write to the Free Software
16 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17 | * MA 02110-1301, USA.
18 | */
19 |
20 | #ifndef KIWIX_NAMEMAPPER_H
21 | #define KIWIX_NAMEMAPPER_H
22 |
23 | #include
24 | #include