Compare commits

..

1 Commits

Author SHA1 Message Date
Matthieu Gautier
00c8f55cc4 Update name of the project in meson.build.
The right name is `kiwix-lib`, not `kiwixlib`.
Also update the version to be able to do a small fix release.
2018-02-01 16:10:54 +01:00
436 changed files with 6162 additions and 59547 deletions

View File

@@ -1,12 +0,0 @@
codecov:
notify:
require_ci_to_pass: yes
coverage:
status:
project:
default:
threshold: 1%
ignore:
- "test"

12
.github/FUNDING.yml vendored
View File

@@ -1,12 +0,0 @@
# These are supported funding model platforms
github: kiwix
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: # https://kiwix.org/support-us/

27
.github/move.yml vendored
View File

@@ -1,27 +0,0 @@
# Configuration for Move Issues - https://github.com/dessant/move-issues
# Delete the command comment when it contains no other content
deleteCommand: true
# Close the source issue after moving
closeSourceIssue: true
# Lock the source issue after moving
lockSourceIssue: false
# Mention issue and comment authors
mentionAuthors: true
# Preserve mentions in the issue content
keepContentMentions: true
# Move labels that also exist on the target repository
moveLabels: true
# Set custom aliases for targets
# aliases:
# r: repo
# or: owner/repo
# Repository to extend settings from
# _extends: repo

15
.github/stale.yml vendored
View File

@@ -1,15 +0,0 @@
daysUntilClose: false
staleLabel: stale
issues:
daysUntilStale: 60
markComment: >
This issue has been automatically marked as stale because it has not had
recent activity. It will be now be reviewed manually. Thank you
for your contributions.
pulls:
daysUntilStale: 7
markComment: >
This pull request has been automatically marked as stale because it has not had
recent activity. It will be now be reviewed manually. Thank you
for your contributions.

View File

@@ -1,162 +0,0 @@
name: CI
on: [push]
jobs:
Macos:
runs-on: macos-latest
steps:
- name: Checkout code
uses: actions/checkout@v1
- name: Setup python 3.5
uses: actions/setup-python@v1
with:
python-version: '3.5'
- name: Install packages
run:
brew install gcovr pkg-config ninja
- name: Install python modules
run: pip3 install meson==0.49.2 pytest
- name: Install deps
shell: bash
run: |
ARCHIVE_NAME=deps2_osx_native_dyn_kiwix-lib.tar.xz
wget -O- http://tmp.kiwix.org/ci/${ARCHIVE_NAME} | tar -xJ -C $HOME
- name: Compile
shell: bash
run: |
export PKG_CONFIG_PATH=$HOME/BUILD_native_dyn/INSTALL/lib/pkgconfig
export CPPFLAGS="-I$HOME/BUILD_native_dyn/INSTALL/include"
meson . build --default-library=shared -Db_coverage=true
cd build
ninja
- name: Test
shell: bash
run: |
export LD_LIBRARY_PATH=$HOME/BUILD_native_dyn/INSTALL/lib:$HOME/BUILD_native_dyn/INSTALL/lib64
cd build
meson test --verbose
ninja coverage
env:
SKIP_BIG_MEMORY_TEST: 1
- name: Publish coverage
shell: bash
run: |
curl https://codecov.io/bash -o codecov.sh
bash codecov.sh -n osx_native_dyn -Z
rm codecov.sh
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
Linux:
strategy:
fail-fast: false
matrix:
name:
- native_static
- native_dyn
- native_dyn_bionic
- android_arm
- android_arm64
- win32_static
- win32_dyn
include:
- name: native_static
target: native_static
image_variant: xenial
lib_postfix: '/x86_64-linux-gnu'
- name: native_dyn
target: native_dyn
image_variant: xenial
lib_postfix: '/x86_64-linux-gnu'
- name: native_dyn_bionic
target: native_dyn
image_variant: bionic
lib_postfix: '/x86_64-linux-gnu'
- name: android_arm
target: android_arm
image_variant: xenial
lib_postfix: '/x86_64-linux-gnu'
- name: android_arm64
target: android_arm64
image_variant: xenial
lib_postfix: '/x86_64-linux-gnu'
- name: win32_static
target: win32_static
image_variant: f31
lib_postfix: '64'
- name: win32_dyn
target: win32_dyn
image_variant: f31
lib_postfix: '64'
env:
HOME: /home/runner
runs-on: ubuntu-latest
container:
image: "kiwix/kiwix-build_ci:${{matrix.image_variant}}-26"
steps:
- name: Extract branch name
shell: bash
run: echo "##[set-output name=branch;]$(echo ${GITHUB_REF#refs/heads/})"
id: extract_branch
- name: Checkout code
shell: python
run: |
from subprocess import check_call
from os import environ
command = [
'git', 'clone',
'https://github.com/${{github.repository}}',
'--depth=1',
'--branch', '${{steps.extract_branch.outputs.branch}}'
]
check_call(command, cwd=environ['HOME'])
- name: Install deps
shell: bash
run: |
ARCHIVE_NAME=deps2_${OS_NAME}_${{matrix.target}}_kiwix-lib.tar.xz
wget -O- http://tmp.kiwix.org/ci/${ARCHIVE_NAME} | tar -xJ -C /home/runner
- name: Compile
shell: bash
run: |
meson --version
if [[ "${{matrix.target}}" =~ .*_dyn ]]; then
MESON_OPTION="--default-library=shared"
else
MESON_OPTION="--default-library=static"
fi
if [[ "${{matrix.target}}" =~ native_.* ]]; then
MESON_OPTION="$MESON_OPTION -Db_coverage=true"
else
MESON_OPTION="$MESON_OPTION --cross-file $HOME/BUILD_${{matrix.target}}/meson_cross_file.txt"
fi
if [[ "${{matrix.target}}" =~ android_.* ]]; then
MESON_OPTION="$MESON_OPTION -Dandroid=true"
fi
cd $HOME/kiwix-lib
meson . build ${MESON_OPTION}
cd build
ninja
env:
PKG_CONFIG_PATH: "/home/runner/BUILD_${{matrix.target}}/INSTALL/lib/pkgconfig:/home/runner/BUILD_${{matrix.target}}/INSTALL/lib${{matrix.lib_postfix}}/pkgconfig"
CPPFLAGS: "-I/home/runner/BUILD_${{matrix.target}}/INSTALL/include"
- name: Test
if: startsWith(matrix.target, 'native_')
shell: bash
run: |
cd $HOME/kiwix-lib/build
meson test --verbose
ninja coverage
env:
LD_LIBRARY_PATH: "/home/runner/BUILD_${{matrix.target}}/INSTALL/lib:/home/runner/BUILD_${{matrix.target}}/INSTALL/lib${{matrix.lib_postfix}}"
SKIP_BIG_MEMORY_TEST: 1
- name: Publish coverage
shell: bash
run: |
cd $HOME/kiwix-lib
curl https://codecov.io/bash -o codecov.sh
bash codecov.sh -n "${OS_NAME}_${{matrix.target}}" -Z
rm codecov.sh
if: startsWith(matrix.target, 'native_') && matrix.image_variant == 'xenial'
env:
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}

View File

@@ -1,87 +0,0 @@
name: Packages
on: [push, pull_request]
jobs:
build-deb:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
distro: [ubuntu-hirsute, ubuntu-groovy, ubuntu-focal, ubuntu-bionic]
steps:
- uses: actions/checkout@v2
# Determine which PPA we should upload to
- name: PPA
id: ppa
run: |
if [[ $REF == refs/tags* ]]
then
echo "::set-output name=ppa::kiwixteam/release"
else
echo "::set-output name=ppa::kiwixteam/dev"
fi
env:
REF: ${{ github.ref }}
- uses: legoktm/gh-action-auto-dch@master
with:
fullname: Kiwix builder
email: release+launchpad@kiwix.org
distro: ${{ matrix.distro }}
- uses: legoktm/gh-action-build-deb@ubuntu-hirsute
if: matrix.distro == 'ubuntu-hirsute'
name: Build package for ubuntu-hirsute
id: build-ubuntu-hirsute
with:
args: --no-sign
ppa: ${{ steps.ppa.outputs.ppa }}
- uses: legoktm/gh-action-build-deb@ubuntu-groovy
if: matrix.distro == 'ubuntu-groovy'
name: Build package for ubuntu-groovy
id: build-ubuntu-groovy
with:
args: --no-sign
ppa: ${{ steps.ppa.outputs.ppa }}
- uses: legoktm/gh-action-build-deb@ubuntu-focal
if: matrix.distro == 'ubuntu-focal'
name: Build package for ubuntu-focal
id: build-ubuntu-focal
with:
args: --no-sign
ppa: ${{ steps.ppa.outputs.ppa }}
- uses: legoktm/gh-action-build-deb@ubuntu-bionic
if: matrix.distro == 'ubuntu-bionic'
name: Build package for ubuntu-bionic
id: build-ubuntu-bionic
with:
args: --no-sign
ppa: ${{ steps.ppa.outputs.ppa }}
- uses: actions/upload-artifact@v2
with:
name: Packages for ${{ matrix.distro }}
path: output
- uses: legoktm/gh-action-dput@master
name: Upload dev package
# Only upload on pushes to master
if: github.event_name == 'push' && github.event.ref == 'refs/heads/master' && startswith(matrix.distro, 'ubuntu-')
with:
gpg_key: ${{ secrets.LAUNCHPAD_GPG }}
repository: ppa:kiwixteam/dev
packages: output/*_source.changes
- uses: legoktm/gh-action-dput@master
name: Upload release package
# Only upload on pushes to master or tag
if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') && startswith(matrix.distro, 'ubuntu-')
with:
gpg_key: ${{ secrets.LAUNCHPAD_GPG }}
repository: ppa:kiwixteam/release
packages: output/*_source.changes

6
.gitignore vendored
View File

@@ -1,6 +0,0 @@
.idea/
*.swp
subprojects/googletest-release*
*.class
build/
.vscode/

13
.travis.yml Normal file
View File

@@ -0,0 +1,13 @@
language: cpp
dist: trusty
sudo: required
cache: ccache
install: travis/install_deps.sh
script: travis/compile.sh
env:
- PLATFORM="native_static"
- PLATFORM="native_dyn"
- PLATFORM="win32_static"
- PLATFORM="win32_dyn"
- PLATFORM="android_arm"
- PLATFORM="android_arm64"

View File

@@ -77,7 +77,7 @@ modification follow.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
@@ -510,7 +510,7 @@ actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties

393
ChangeLog
View File

@@ -1,396 +1,3 @@
kiwix-lib 9.4.1
===============
* Fix `M/Counter` parsing.
* [SERVER] Adjust body padding-top for taskbar
* Fix potential crash when stoping a server not started.
* Various fix in build system and the CI.
kiwix-lib 9.4.0
===============
* [SERVER] Make the headers handling case insensitive.
* [SERVER] Make server answer 204 http status code for empty search
* [PACKAGING] Made CI build deb packages.
* [SERVER] Add a way to prevent taskbar and external link bloquer at article
level.
* Fix meson file to be compatible with meson 0.45
* [SERVER] Update search requests to use pageStart/pageLength instead of
pageStart/pageEnd arguments.
* [SERVER] Set a fixed favicon size in the main page.
* [SERVER] Refactor the response system code to better handling future new
libzim api.
* Fix segmentation fault around exchange with aria2 process making
kiwix-desktop crash at exit.
kiwix-lib 9.3.1
===============
* Fix handling of samba path on windows.
* Do not include `kiwix_config.h` in public header.
* Fix compilation with libmicrohttpd v0.97.1
* Increase default test timeout to 160seconds/test.
* Add automatic debian packaging.
* Use non-minified version of jquery-ui.js
* Pass `-latomic` compile option for sh4 architecture.
* Make mesion install `kiwix-compile-resources` man page.
kiwix-lib 9.3.0
===============
* Add a thread safe method to search suggestions.
Old methods are now deprecated.
kiwix-lib 9.2.3
===============
* Add test on byte-range
* Fix compilation on bionic and windows.
* Allow building using debian packaged kainjow-mustache
* Pass `-latomic` compile option for architectures that need it
kiwix-lib 9.2.2
===============
* Fix handling on empty content in byte range management (wrong assert)
kiwix-lib 9.2.1
===============
* Fix support of byte range request.
kiwix-lib 9.2
=============
* Add tests
* Refactoring server code.
* [SERVER] Add HEAD, Etag and If-None-Match support.
* [SERVER] Compress opds catalog answers.
kiwix-lib 9.1.2
===============
* Do not use the pathToSave if it is empty.
kiwix-lib 9.1.1
===============
* Fix the detection of the dataDirectory on windows.
kiwix-lib 9.1.0
===============
* [JAVA] Add a method to get the size of an article.
* Add a new method to the libray to get the book by path.
* Add a option to make the server blocks external link.
Links are intercepted by js an redirected to a "portail" page.
* [ODPS] Correctly handle book's articleCount and mediaCount.
kiwix-lib 9.0.1
===============
* [JAVA] Use a long to store the offset of an article in the zim file instead
of an int.
kiwix-lib 9.0.0
===============
* [OPDS] Correctly set the id of the OPDS stream.
* [OPDS] Do not try to filter the catalog if no filter field is given in the
request.
* [WINDOWS] Correctly convert path to wide chars when opening the library.xml
* [LIBRARY] Remove the function the read file using a native path.
All path must be utf8, no need to pass a native path along the utf8 path.
* [TEST] Fix tests using the main function of gtest instead of custom one.
* [CI] Move to github CI instead of Travis.
* The `Book::update` method always update the book's fields. Even if they are
not empty.
* [JAVA] Add wrapping around the library manager (opds parsing)
* [ARIA2] Add api option to start download with option (destination folder)
* [OPDS] Fixes about opds parsing, generation (missing attributes)
and requesting (server)
* Add methods on `Book` to get specific tag values (was on `Reader` only)
* Add flavour attribute to `Book`
* Fix opensearch description.
* Trust the given library.xml (by default) instead of reading the value from
the zim files.
* [OPDS] Be able to filter the content by name or size.
* [WINDOWS] Fix launching subcommand when there is spaces in the path.
kiwix-lib 8.2.2
===============
* Improve a few compilation scripts
kiwix-lib 8.2.1
===============
* Reintroduce kiwix-serve taskbar
kiwix-lib 8.2.0
===============
* More debug information if aria2c command fails
* Allow to set kiwix-serve port
* Better (dead) bookmarks mgmt
kiwix-lib 8.1.0
===============
* Fix pathTools manipulation.
* Add missing implementation of getArticleCount and getMediaCount on android.
* Correctly convert windows path to utf8.
* Add code coverage in the CI
kiwix-lib 8.0.1
===============
* Fix join function
kiwix-lib 8.0.0
===============
* Add new methods to get all (and new) metadata from the zim file.
* Add methods to get the value of a specific tag.
* [API Change] Convert tags value to the new convention.
* [API Change] Rename `getMatatag` method to `getMetadata`
* [ABI Change] Correctly detect executable path in appimage.
kiwix-lib 7.0.0
===============
* [API break] Add a argument to kiwix-serve to specify the library to use.
kiwix-lib 6.0.4
===============
* Fix HTML rendering of the search result if there is no result.
* Do not crash at html rendering if request ask for 0 results (start == end)
* Correctly find the executable path if we are using AppImage
kiwix-lib 6.0.3
===============
* force one column suggestion in kiwix-serve suggestions
* fix fulltext search link in suggestions
* UI fixes in kiwix-serve rendering
kiwix-lib 6.0.2
===============
* Correctly set the groupId in the pom file.
kiwix-lib 6.0.1
===============
* Generate the pom file for android/maven
kiwix-lib 6.0.0
===============
* Move the server code in kiwix-lib (from kiwix-serve).
* Add unit test on regex functions.
* Fix computerAbsolutePath (thread safe, memory leak).
* Correctly set the book's path as valid if we construct the book from a
reader.
* [JNI] Add a method to know if a article is a redirection.
* Do not embed the gtest dependency.
* [JNI] Add a constructor to JNIKiwixString.
* Change order of search of the favicon urls.
* Clean a lot of unecessary includes in headers. (potential "API break")
kiwix-lib 5.2.0
===============
* kiwix-serve integration (as a seperated process).
* Fix crash in the suggestion search.
* Better API to filter the library books.
* New kiwix-lib application for android. (.aar)
* Use ReLinker to link with libkiwix.so in android.
* Correctly set the verbosity of zim search.
kiwix-lib 5.1.0
===============
* Add function to pause, resume and stop downloads.
* Add zim's tags in the opds stream.
* Addapt to new libzim 5.0.0 API.
kiwix-lib 5.0.0
===============
* Remove error message when trying to open an wrong zim file.
* Rewrite `makeTmpDirectory` to not use uuid functions on windows.
* [API break] Remove `getNetworkInterfaces` and `getBestPublicIp`.
* Remove rpath
* Detect infinite (and too long) redirect loops.
kiwix-lib 4.1.0
===============
* Allow the library to be filtered by tags.
* Fix language mapping.
* Update README about mustache dependency.
kiwix-lib 4.0.1
===============
* Fix "maybe uninitialize variable" issue.
* Ensure path are stored correctly (absolute path) in the library.
* [CI] Use the new deps archive xz
kiwix-lib 4.0.0
===============
* [API break] Remove support for external index.
* Move to the mustache templating system instead of ctpp2.
* Make meson.build works for meson>=0.43.0
* [API break] Move the basic tools from the `common` directory to `tools`.
kiwix-lib 3.1.1
===============
* The OPDS feed book's date must be the date of the book, not the date of the
feed generation.
* Convert the standard opds date to our format (YYYY-MM-DD)
* Remove duplicate language attribute in the libxml dumper.
* Create the datadirectory to not fail to write a file in a non-existent
directory
kiwix-lib 3.1.0
===============
* Add a method to get the favicon url of book (if available).
* Move dump code of library.xml in a specific class.
* Add a first support to bookmarks
kiwix-lib 3.0.3
===============
* Add the 'en' language to the mapping alpha2-code ('en') to alpha3-code
('eng').
* Correctly write the 'ArticleCount' and 'MediaCount' in the library.xml.
* Correctly fill the book size for the zim file size.
* Fix launch of aria2c.
kiwix-lib 3.0.2
===============
* Use the correct path separator when computing relativePath on Windows.
kiwix-lib 3.0.1
===============
* Small fix about parsing the opdsStream.
kiwix-lib 3.0.0
===============
* Change the downloader to use aria2 using a separated process (with rpc)
instead of using the libaria2. This simplify a lot the link process to
libaria2 on Windows.
- kiwix-lib doesn't depend on libaria2 anymore.
- kiwix-lib now depends on libcurl.
* [API break] Library class API has been updated :
- Books are referenced by id, not index. A lot of methods have been
updated this way.
- Books "list" is now private.
- There is no more "current" book.
- listBooksIds's filters have been updated.
* [API break] Book class API has been updated :
- Move the definition of Book in `book.h`.
- Use getter/setter methods instead public members.
- Size (getSize/setSize) is now returned in bytes, not kB.
- Dependending of how the book has been initialized (opdsfeed), the
faviconUrl may be stored in the book, the favicon being downloaded when
using `getFavicon`.
- The path (and indexPath) are always absolute path.
- Book has now a downloadId, corresponding to the aria2 download id (if
exists)
* [API break] Manager class API has been updated :
- The manager is mainly use to fill a Libray from a "library.xml" file or
opds feed. Other operations (has removeBookById, setBookPath, filter, ...)
have been removed.
- The manager use a intermediate class (LibraryManipulator) to add book to
the library. This dependency injection allow caller code to hook the add
of a book to the library.
- The manager work on a existing Library. It doesn't how a internal
Library.
* [API break] OpdsDumper class API has been updated :
- dumpOPDSFeed method now take the list of bookIds to dump instead of
dumping all books in the library.
- OpdsDumper can now dump openSearch result information (total result
count, start index, ...).
* [API break] Common tools API has been updated :
- `base64_encode` and `base64_decode` take std::string as arguments.
- New `download` function in networkTools.h using libcurl.
- New `getDataDirectory` function in pathTools.
- Better `beautifyInteger` and `beautifyFileSize` functions.
- New `nodeToString` function serializing a pugi::xml_node to a string.
- New `converta2toa3` function to convert alpha2 language code to aplha3
language code.
kiwix-lib 2.0.2
===============
* [Android] Forward c++ errors message de Java world.
* Follow redirection of favicon.
* Make aria2 dependency optional.
* Inculde unistd.h only on unix platform.
kiwix-lib 2.0.1
===============
* Fix parsing of url.
* Remove unused static resources.
* Correctly decode reserved characters in URLs.
* Explicitly use icu namespace to allow use of packaged icu lib.
kiwix-lib 2.0.0
===============
* Introduce a new API to retrive content from a reader.
* Introduce the `Entry` class.
* Reader's methods return an `Entry`.
* Content and other information can be retrieved from the `Entry`.
* Older Reader's methods are depreciated.
* Add an `OPDSDumper` class to dump a whole `Library` as an OPDS feed.
* Add a tool function to get the content of a file.
* Add a tool function to create a tempory directory.
* Add a `Downloader` class to download a file.
* Allow the manager to populate a `Library` from an OPDS feed.
* Try to locate libctpp2 in default system libdir and then fallback in 'lib'
directory.
* Build kiwix-lib setting RPATH.
* Build kiwix-lib without warning (werror=true)
* Build kiwix-lib on macos.
kiwix-lib 1.1.1
===============
* Correct the name of kiwix-lib (from `kiwixlib`) in meson.build to generate
dist archive with the correct name.
* Libzim version need to be at least 3.2.0
kiwix-lib 1.1.0
===============
* Allow for more than 70 search result per page in html results rendering
(kiwix/kiwix-tools#92)
* Add a small api to do geo queries.
* Add multi-search support in the JNI (#67)
* Add an API to get only one part of an article.
* Add an API to get direct location of an article content in the zim file.
* Improve urlencoding
* Fix pagination in html results rendering.
* Compile using gcc-5 on Travis.
* Allow JNI to access search snippets.
* JNI throw an exception instead of returning an invalid object if something
goes wrong.
* Add doctext documentation. (#116)
* Various bug fixes.
kiwix-lib 1.0.0
===============

167
README.md
View File

@@ -1,32 +1,23 @@
Kiwix library
=============
The Kiwix library provides the [Kiwix](https://kiwix.org) software
suite core. It contains the code shared by all Kiwix ports (Windows,
GNU/Linux, macOS, Android, iOS, ...).
[![Download](https://api.bintray.com/packages/kiwix/kiwix/kiwixlib/images/download.svg)](https://bintray.com/kiwix/kiwix/kiwixlib/_latestVersion)
[![Build Status](https://github.com/kiwix/kiwix-lib/workflows/CI/badge.svg?query=branch%3Amaster)](https://github.com/kiwix/kiwix-lib/actions?query=branch%3Amaster)
[![CodeFactor](https://www.codefactor.io/repository/github/kiwix/kiwix-lib/badge)](https://www.codefactor.io/repository/github/kiwix/kiwix-lib)
[![Codecov](https://codecov.io/gh/kiwix/kiwix-lib/branch/master/graph/badge.svg)](https://codecov.io/gh/kiwix/kiwix-lib)
[![License: GPL v3](https://img.shields.io/badge/License-GPLv3-blue.svg)](https://www.gnu.org/licenses/gpl-3.0)
[![Packaging status](https://repology.org/badge/vertical-allrepos/kiwix-lib.svg)](https://repology.org/project/kiwix-lib/versions)
The Kiwix library provides the Kiwix software core. It contains the
code shared by all Kiwix ports (Windows, Linux, OSX, Android, ...).
Disclaimer
----------
This document assumes you have a little knowledge about software
compilation. If you experience difficulties with the dependencies or
with the Kiwix library compilation itself, we recommend to have a look
with the Kiwix libary compilation itself, we recommend to have a look
to [kiwix-build](https://github.com/kiwix/kiwix-build).
Preamble
--------
Although the Kiwix library can be (cross-)compiled on/for many
systems, the following documentation explains how to do it on POSIX
ones. It is primarily thought for GNU/Linux systems and has been tested
Although the Kiwix library can be compiled/cross-compiled on/for many
sytems, the following documentation explains how to do it on POSIX
ones. It is primarly though for GNU/Linux systems and has been tested
on recent releases of Ubuntu and Fedora.
Dependencies
@@ -36,18 +27,16 @@ The Kiwix library relies on many third parts software libraries. They
are prerequisites to the Kiwix library compilation. Following
libraries need to be available:
* [ICU](https://site.icu-project.org/) (package `libicu-dev` on Ubuntu)
* [ZIM](https://openzim.org/) (package `libzim-dev` on Ubuntu)
* [Pugixml](https://pugixml.org/) (package `libpugixml-dev` on Ubuntu)
* [Mustache](https://github.com/kainjow/Mustache) (Just copy the
header `mustache.hpp` somewhere it can be found by the compiler and/or
set CPPFLAGS with correct `-I` option). Use Mustache version 3 only.
* [libcurl](https://curl.se/libcurl) (`libcurl4-gnutls-dev`, `libcurl4-nss-dev` or `libcurl4-openssl-dev` on Ubuntu)
* [microhttpd](https://www.gnu.org/software/libmicrohttpd) (package `libmicrohttpd-dev` on Ubuntu)
* [zlib](https://zlib.net/) (package `zlib1g-dev` on Ubuntu)
The following dependency needs to be available at runtime:
* [Aria2](https://aria2.github.io/) (package `aria2` on Ubuntu)
* ICU ................................... http://site.icu-project.org/
(package libicu-dev on Ubuntu)
* ZIM ........................................ http://www.openzim.org/
(package libzim-dev on Ubuntu)
* Pugixml ........................................ http://pugixml.org/
(package libpugixml-dev on Ubuntu)
* ctpp2 ........................................ http://ctpp.havoc.ru/
(package libctpp2-dev on Ubuntu)
* Xapian ......................................... https://xapian.org/
(package libxapian-dev on Ubuntu)
These dependencies may or may not be packaged by your operating
system. They may also be packaged but only in an older version. The
@@ -56,104 +45,76 @@ In the worse case, you will have to download and compile bleeding edge
version by hand.
If you want to install these dependencies locally, then use the
`kiwix-lib` directory as install prefix.
kiwix-lib directory as install prefix.
Environment
If you compile ctpp2 from source and want to compile the Kiwix library
statically then you will probably need to rename ctpp2 static library
from ctpp2-st.a to ctpp2.a.
Environnement
-------------
The Kiwix library builds using [Meson](https://mesonbuild.com/) version
0.45 or higher. Meson relies itself on Ninja, pkg-config and few other
The Kiwix library builds using [Meson](http://mesonbuild.com/) version
0.34 or higher. Meson relies itself on Ninja, pkg-config and few other
compilation tools.
Install first the few common compilation tools:
* [Meson](https://mesonbuild.com/)
* [Ninja](https://ninja-build.org/)
* [pkg-config](https://www.freedesktop.org/wiki/Software/pkg-config/)
* Automake
* Libtool
* Virtualenv
* Pkg-config
These tools should be packaged if you use a cutting edge operating
system. If not, have a look to the [Troubleshooting](#Troubleshooting)
section.
Compilation
-----------
Once all dependencies are installed, you can compile the Kiwix library
with:
```bash
meson . build
ninja -C build
Then install Meson itself:
```
By default, it will compile dynamic linked libraries. All binary files
will be created in the "build" directory created automatically by
Meson. If you want statically linked libraries, you can add
`--default-library=static` option to the Meson command.
Depending of you system, `ninja` may be called `ninja-build`.
Testing
-------
To run the automated tests:
```bash
cd build
meson test
```
Installation
------------
If you want to install the Kiwix library and the headers you just have
compiled on your system, here we go:
```bash
ninja -C build install
```
You might need to run the command as root (or using `sudo`), depending
where you want to install the libraries. After the installation
succeeded, you may need to run `ldconfig` (as `root`).
Uninstallation
------------
If you want to uninstall the Kiwix library:
```bash
ninja -C build uninstall
```
Like for the installation, you might need to run the command as `root`
(or using `sudo`).
Troubleshooting
---------------
If you need to install Meson "manually":
```bash
virtualenv -p python3 ./ # Create virtualenv
source bin/activate # Activate the virtualenv
pip3 install meson # Install Meson
pip install meson # Install Meson
hash -r # Refresh bash paths
```
If you need to install Ninja "manually":
```bash
Finally download and build Ninja locally:
```
git clone git://github.com/ninja-build/ninja.git
cd ninja
git checkout release
./configure.py --bootstrap
mkdir ../bin
mkdir ../bin
cp ninja ../bin
cd ..
```
If the compilation still fails, you might need to get a more recent
version of a dependency than the one packaged by your Linux
distribution. Try then with a source tarball distributed by the
problematic upstream project or even directly from the source code
repository.
Compilation
-----------
Once all dependencies are installed, you can compile kiwix-lib with:
```
mkdir build
meson . build
cd build
ninja
```
By default, it will compile dynamic linked libraries. If you want
statically linked libraries, you can add `--default-library=static`
option to the Meson command.
Depending of you system, `ninja` may be called `ninja-build`.
Installation
------------
If you want to install the libraries you just have compiled on your
system, here we go:
```
ninja install
cd ..
```
You might need to run the command as root, depending where you want to
install the libraries.
License
-------
[GPLv3](https://www.gnu.org/licenses/gpl-3.0) or later, see
[COPYING](COPYING) for more details.
GPLv3 or later, see COPYING for more details.

View File

@@ -1,13 +0,0 @@
*.iml
.gradle
/local.properties
/.idea/caches
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
/.idea/navEditor.xml
/.idea/assetWizardSettings.xml
.DS_Store
/build
/captures
.externalNativeBuild

View File

@@ -1,25 +0,0 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.4.1'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@@ -1,15 +0,0 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official

View File

Binary file not shown.

View File

@@ -1,6 +0,0 @@
#Wed Jun 19 15:28:39 BST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip

View File

@@ -1,172 +0,0 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

View File

@@ -1,84 +0,0 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@@ -1 +0,0 @@
/build

View File

@@ -1,64 +0,0 @@
apply plugin: 'com.android.library'
apply plugin: 'maven'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 15
targetSdkVersion 28
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation 'com.getkeepsafe.relinker:relinker:1.3.1'
}
task writePom {
pom {
project {
groupId 'org.kiwix.kiwixlib'
artifactId 'kiwixlib'
version '10.0.0' + (System.env.KIWIXLIB_BUILDVERSION == null ? '' : '-'+System.env.KIWIXLIB_BUILDVERSION)
packaging 'aar'
name 'kiwixlib'
url 'https://github.com/kiwix/kiwix-lib'
licenses {
license {
name 'GPLv3'
url 'https://www.gnu.org/licenses/gpl-3.0.en.html'
}
}
developers {
developer {
id 'kiwix'
name 'kiwix'
email 'contact@kiwix.org'
}
}
scm {
connection 'https://github.com/kiwix/kiwix-lib.git'
developerConnection 'https://github.com/kiwix/kiwix-lib.git'
url 'https://github.com/kiwix/kiwix-lib'
}
}
}.withXml {
def dependenciesNode = asNode().appendNode('dependencies')
//Iterate over the implementation dependencies, adding a <dependency> node for each
configurations.implementation.allDependencies.each {
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', it.group)
dependencyNode.appendNode('artifactId', it.name)
dependencyNode.appendNode('version', it.version)
}
}.writeTo("$buildDir/pom.xml")
}

View File

@@ -1,21 +0,0 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@@ -1,10 +0,0 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.kiwix.kiwixlib">
<application
android:allowBackup="true"
android:supportsRtl="true">
</application>
</manifest>

View File

@@ -1 +0,0 @@
include ':kiwixLibAndroid'

5
debian/changelog vendored
View File

@@ -1,5 +0,0 @@
libkiwix (0.0.0) unstable; urgency=medium
* Initial release
-- Kunal Mehta <legoktm@debian.org> Wed, 08 Jul 2020 18:12:32 -0700

46
debian/control vendored
View File

@@ -1,46 +0,0 @@
Source: libkiwix
Priority: optional
Maintainer: Kiwix team <kiwix@kiwix.org>
Build-Depends: debhelper-compat (= 13),
meson,
pkg-config,
libzim-dev (>= 6.1.8),
libcurl4-gnutls-dev,
libicu-dev,
libgtest-dev,
libkainjow-mustache-dev,
liblzma-dev,
libmicrohttpd-dev,
libpugixml-dev,
zlib1g-dev
Standards-Version: 4.5.0
Section: libs
Homepage: https://github.com/kiwix/kiwix-lib
Rules-Requires-Root: no
Package: libkiwix-dev
Section: libdevel
Architecture: any
Multi-Arch: same
Depends: libkiwix10 (= ${binary:Version}), ${misc:Depends}, python3,
libzim-dev (>= 6.0.0),
libicu-dev,
libpugixml-dev,
libcurl4-gnutls-dev,
libmicrohttpd-dev
Description: library of common code for Kiwix (development)
Kiwix is an offline Wikipedia reader. libkiwix provides the
software core for Kiwix, and contains the code shared by all
Kiwix ports (Windows, Linux, OSX, Android, etc.).
.
This package contains development files.
Package: libkiwix10
Architecture: any
Multi-Arch: same
Depends: ${shlibs:Depends}, ${misc:Depends}, aria2
Conflicts: libkiwix0, libkiwix3, libkiwix9
Description: library of common code for Kiwix
Kiwix is an offline Wikipedia reader. libkiwix provides the
software core for Kiwix, and contains the code shared by all
Kiwix ports (Windows, Linux, OSX, Android, etc.).

1
debian/copyright vendored
View File

@@ -1 +0,0 @@
See COPYING in the repository root.

View File

@@ -1,4 +0,0 @@
usr/include
usr/lib/*/libkiwix.so
usr/lib/*/pkgconfig
usr/bin

View File

@@ -1 +0,0 @@
usr/share/man/man1/kiwix-compile-resources.1*

View File

@@ -1 +0,0 @@
usr/lib/*/libkiwix.so.*

8
debian/rules vendored
View File

@@ -1,8 +0,0 @@
#!/usr/bin/make -f
export DEB_BUILD_MAINT_OPTIONS = hardening=+all
%:
dh $@ --buildsystem=meson
override_dh_auto_test:
dh_auto_test -- -t 3

View File

@@ -1 +0,0 @@
3.0 (native)

View File

@@ -1,124 +0,0 @@
/*
* Copyright 2011 Emmanuel Engelhart <kelson@kiwix.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef KIWIX_BOOK_H
#define KIWIX_BOOK_H
#include <string>
namespace pugi {
class xml_node;
}
namespace kiwix
{
class OPDSDumper;
class Reader;
/**
* A class to store information about a book (a zim file)
*/
class Book
{
public:
Book();
~Book();
bool update(const Book& other);
void update(const Reader& reader);
void updateFromXml(const pugi::xml_node& node, const std::string& baseDir);
void updateFromOpds(const pugi::xml_node& node, const std::string& urlHost);
std::string getHumanReadableIdFromPath() const;
bool readOnly() const { return m_readOnly; }
const std::string& getId() const { return m_id; }
const std::string& getPath() const { return m_path; }
bool isPathValid() const { return m_pathValid; }
const std::string& getTitle() const { return m_title; }
const std::string& getDescription() const { return m_description; }
const std::string& getLanguage() const { return m_language; }
const std::string& getCreator() const { return m_creator; }
const std::string& getPublisher() const { return m_publisher; }
const std::string& getDate() const { return m_date; }
const std::string& getUrl() const { return m_url; }
const std::string& getName() const { return m_name; }
const std::string& getTags() const { return m_tags; }
std::string getTagStr(const std::string& tagName) const;
bool getTagBool(const std::string& tagName) const;
const std::string& getFlavour() const { return m_flavour; }
const std::string& getOrigId() const { return m_origId; }
const uint64_t& getArticleCount() const { return m_articleCount; }
const uint64_t& getMediaCount() const { return m_mediaCount; }
const uint64_t& getSize() const { return m_size; }
const std::string& getFavicon() const;
const std::string& getFaviconUrl() const { return m_faviconUrl; }
const std::string& getFaviconMimeType() const { return m_faviconMimeType; }
const std::string& getDownloadId() const { return m_downloadId; }
void setReadOnly(bool readOnly) { m_readOnly = readOnly; }
void setId(const std::string& id) { m_id = id; }
void setPath(const std::string& path);
void setPathValid(bool valid) { m_pathValid = valid; }
void setTitle(const std::string& title) { m_title = title; }
void setDescription(const std::string& description) { m_description = description; }
void setLanguage(const std::string& language) { m_language = language; }
void setCreator(const std::string& creator) { m_creator = creator; }
void setPublisher(const std::string& publisher) { m_publisher = publisher; }
void setDate(const std::string& date) { m_date = date; }
void setUrl(const std::string& url) { m_url = url; }
void setName(const std::string& name) { m_name = name; }
void setFlavour(const std::string& flavour) { m_flavour = flavour; }
void setTags(const std::string& tags) { m_tags = tags; }
void setOrigId(const std::string& origId) { m_origId = origId; }
void setArticleCount(uint64_t articleCount) { m_articleCount = articleCount; }
void setMediaCount(uint64_t mediaCount) { m_mediaCount = mediaCount; }
void setSize(uint64_t size) { m_size = size; }
void setFavicon(const std::string& favicon) { m_favicon = favicon; }
void setFaviconMimeType(const std::string& faviconMimeType) { m_faviconMimeType = faviconMimeType; }
void setDownloadId(const std::string& downloadId) { m_downloadId = downloadId; }
protected:
std::string m_id;
std::string m_downloadId;
std::string m_path;
bool m_pathValid = false;
std::string m_title;
std::string m_description;
std::string m_language;
std::string m_creator;
std::string m_publisher;
std::string m_date;
std::string m_url;
std::string m_name;
std::string m_flavour;
std::string m_tags;
std::string m_origId;
uint64_t m_articleCount = 0;
uint64_t m_mediaCount = 0;
bool m_readOnly = false;
uint64_t m_size = 0;
mutable std::string m_favicon;
std::string m_faviconUrl;
std::string m_faviconMimeType;
};
}
#endif

View File

@@ -1,68 +0,0 @@
/*
* Copyright 2018 Matthieu Gautier <mgautier@kymeria.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef KIWIX_BOOKMARK_H
#define KIWIX_BOOKMARK_H
#include <string>
namespace pugi {
class xml_node;
}
namespace kiwix
{
/**
* A class to store information about a bookmark (an article in a book)
*/
class Bookmark
{
public:
Bookmark();
~Bookmark();
void updateFromXml(const pugi::xml_node& node);
const std::string& getBookId() const { return m_bookId; }
const std::string& getBookTitle() const { return m_bookTitle; }
const std::string& getUrl() const { return m_url; }
const std::string& getTitle() const { return m_title; }
const std::string& getLanguage() const { return m_language; }
const std::string& getDate() const { return m_date; }
void setBookId(const std::string& bookId) { m_bookId = bookId; }
void setBookTitle(const std::string& bookTitle) { m_bookTitle = bookTitle; }
void setUrl(const std::string& url) { m_url = url; }
void setTitle(const std::string& title) { m_title = title; }
void setLanguage(const std::string& language) { m_language = language; }
void setDate(const std::string& date) { m_date = date; }
protected:
std::string m_bookId;
std::string m_bookTitle;
std::string m_url;
std::string m_title;
std::string m_language;
std::string m_date;
};
}
#endif

View File

@@ -1,24 +0,0 @@
#ifndef _KIWIX_COMMON_H_
#define _KIWIX_COMMON_H_
#include <zim/zim.h>
#ifdef __GNUC__
#define DEPRECATED __attribute__((deprecated))
#elif defined(_MSC_VER)
#define DEPRECATED __declspec(deprecated)
#else
#praga message("WARNING: You need to implement DEPRECATED for this compiler")
#define DEPRECATED
#endif
namespace kiwix {
typedef zim::size_type size_type;
typedef zim::offset_type offset_type;
}
#endif //_KIWIX_COMMON_H_

4
include/common/base64.h Normal file
View File

@@ -0,0 +1,4 @@
#include <string>
std::string base64_encode(unsigned char const* , unsigned int len);
std::string base64_decode(std::string const& s);

View File

@@ -1,6 +1,5 @@
/*
* Copyright (C) 2013 Emmanuel Engelhart <kelson@kiwix.org>
* Copyright (C) 2017 Matthieu Gautier <mgautier@kymeria.fr>
* Copyright 2012 Emmanuel Engelhart <kelson@kiwix.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -18,27 +17,33 @@
* MA 02110-1301, USA.
*/
#include <jni.h>
#include "org_kiwix_kiwixlib_JNIICU.h"
#ifndef KIWIX_NETWORKTOOLS_H
#define KIWIX_NETWORKTOOLS_H
#ifdef _WIN32
#include <winsock2.h>
#include <ws2tcpip.h>
#else
#include <net/if.h>
#include <netdb.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#endif
#include <iostream>
#include <map>
#include <string>
#include <vector>
#include "unicode/putil.h"
#include "utils.h"
std::mutex globalLock;
JNIEXPORT void JNICALL Java_org_kiwix_kiwixlib_JNIICU_setDataDirectory(
JNIEnv* env, jclass kclass, jstring dirStr)
namespace kiwix
{
std::string cPath = jni2c(dirStr, env);
Lock l;
try {
u_setDataDirectory(cPath.c_str());
} catch (...) {
std::cerr << "Unable to set data directory " << cPath << std::endl;
}
std::map<std::string, std::string> getNetworkInterfaces();
std::string getBestPublicIp();
}
#endif

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2020 Emmanuel Engelhart <kelson@kiwix.org>
* Copyright 2014 Emmanuel Engelhart <kelson@kiwix.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -17,8 +17,18 @@
* MA 02110-1301, USA.
*/
#include <microhttpd.h>
#ifndef KIWIX_OTHERTOOLS_H
#define KIWIX_OTHERTOOLS_H
#ifdef _WIN32
#include <windows.h>
#else
#include <unistd.h>
#endif
namespace kiwix
{
void sleep(unsigned int milliseconds);
}
#if MHD_VERSION < 0x00097002
typedef int MHD_Result;
#endif

View File

@@ -0,0 +1,61 @@
/*
* Copyright 2011 Emmanuel Engelhart <kelson@kiwix.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef KIWIX_PATHTOOLS_H
#define KIWIX_PATHTOOLS_H
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fstream>
#include <ios>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#ifdef _WIN32
#include <direct.h>
#endif
#include "stringTools.h"
using namespace std;
bool isRelativePath(const string& path);
string computeAbsolutePath(const string path, const string relativePath);
string computeRelativePath(const string path, const string absolutePath);
string removeLastPathElement(const string path,
const bool removePreSeparator = false,
const bool removePostSeparator = false);
string appendToDirectory(const string& directoryPath, const string& filename);
unsigned int getFileSize(const string& path);
string getFileSizeAsString(const string& path);
bool fileExists(const string& path);
bool makeDirectory(const string& path);
bool copyFile(const string& sourcePath, const string& destPath);
string getLastPathElement(const string& path);
string getExecutablePath();
string getCurrentDirectory();
bool writeTextFile(const string& path, const string& content);
#endif

View File

@@ -20,6 +20,9 @@
#ifndef KIWIX_REGEXTOOLS_H
#define KIWIX_REGEXTOOLS_H
#include <unicode/regex.h>
#include <unicode/ucnv.h>
#include <map>
#include <string>
bool matchRegex(const std::string& content, const std::string& regex);
@@ -27,10 +30,7 @@ std::string replaceRegex(const std::string& content,
const std::string& replacement,
const std::string& regex);
std::string appendToFirstOccurence(const std::string& content,
const std::string& regex,
const std::string regex,
const std::string& replacement);
std::string prependToFirstOccurence(const std::string& content,
const std::string& regex,
const std::string& replacement);
#endif

View File

@@ -22,29 +22,38 @@
#include <unicode/unistr.h>
#include <fstream>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <sstream>
#include "pathTools.h"
namespace kiwix
{
std::string beautifyInteger(uint64_t number);
std::string beautifyFileSize(uint64_t number);
#ifndef __ANDROID__
std::string beautifyInteger(const unsigned int number);
std::string beautifyFileSize(const unsigned int number);
std::string urlEncode(const std::string& c);
void printStringInHexadecimal(const char* s);
void printStringInHexadecimal(icu::UnicodeString s);
void printStringInHexadecimal(UnicodeString s);
void stringReplacement(std::string& str,
const std::string& oldStr,
const std::string& newStr);
std::string encodeDiples(const std::string& str);
#endif
std::string removeAccents(const std::string& text);
void loadICUExternalTables();
std::string urlDecode(const std::string& c);
std::string urlEncode(const std::string& value, bool encodeReserved = false);
std::string urlDecode(const std::string& value, bool component = false);
std::vector<std::string> split(const std::string& str, const std::string& delims, bool trimEmpty = true, bool keepDelim = false);
std::string join(const std::vector<std::string>& list, const std::string& sep);
std::vector<std::string> split(const std::string&, const std::string&);
std::vector<std::string> split(const char*, const char*);
std::vector<std::string> split(const std::string&, const char*);
std::vector<std::string> split(const char*, const std::string&);
std::string ucAll(const std::string& word);
std::string lcAll(const std::string& word);
@@ -53,22 +62,6 @@ std::string lcFirst(const std::string& word);
std::string toTitle(const std::string& word);
std::string normalize(const std::string& word);
template<typename T>
std::string to_string(T value)
{
std::ostringstream oss;
oss << value;
return oss.str();
}
template<typename T>
T extractFromString(const std::string& str) {
std::istringstream iss(str);
T ret;
iss >> ret;
return ret;
}
bool startsWith(const std::string& base, const std::string& start);
} //namespace kiwix
#endif

View File

@@ -0,0 +1,79 @@
/*
* Copyright 2013 Renaud Gaudin <reg@kiwix.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef _CTPP2_VM_STRING_LOADER_HPP__
#define _CTPP2_VM_STRING_LOADER_HPP__ 1
#include <ctpp2/CTPP2VMLoader.hpp>
#include <ctpp2/CTPP2Util.hpp>
#include <ctpp2/CTPP2Exception.hpp>
#include <ctpp2/CTPP2VMExecutable.hpp>
#include <ctpp2/CTPP2VMInstruction.hpp>
#include <ctpp2/CTPP2VMMemoryCore.hpp>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <iostream>
#include <string>
/**
@file VMStringLoader.hpp
@brief Load program core from file
*/
namespace CTPP // C++ Template Engine
{
// FWD
struct VMExecutable;
/**
@class VMStringLoader CTPP2VMStringLoader.hpp <CTPP2VMStringLoader.hpp>
@brief Load program core from file
*/
class CTPP2DECL VMStringLoader:
public VMLoader
{
public:
/**
*/
VMStringLoader(CCHAR_P rawContent, size_t rawContentSize);
/**
@brief Get ready-to-run program
*/
const VMMemoryCore * GetCore() const;
/**
@brief A destructor
*/
~VMStringLoader() throw();
private:
/** Program core */
VMExecutable * oCore;
/** Ready-to-run program */
VMMemoryCore * pVMMemoryCore;
};
} // namespace CTPP
#endif // _CTPP2_VM_STRING_LOADER_HPP__
// End.

View File

@@ -1,107 +0,0 @@
/*
* Copyright 2018 Matthieu Gautier <mgautier@kymeria.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef KIWIX_DOWNLOADER_H
#define KIWIX_DOWNLOADER_H
#include <string>
#include <vector>
#include <map>
#include <memory>
#include <stdexcept>
namespace kiwix
{
class Aria2;
struct DownloadedFile {
DownloadedFile()
: success(false) {}
bool success;
std::string path;
};
class AriaError : public std::runtime_error {
public:
AriaError(const std::string& message) : std::runtime_error(message) {}
};
class Download {
public:
typedef enum { K_ACTIVE, K_WAITING, K_PAUSED, K_ERROR, K_COMPLETE, K_REMOVED, K_UNKNOWN } StatusResult;
Download() :
m_status(K_UNKNOWN) {}
Download(std::shared_ptr<Aria2> p_aria, std::string did)
: mp_aria(p_aria),
m_status(K_UNKNOWN),
m_did(did) {};
void updateStatus(bool follow=false);
void pauseDownload();
void resumeDownload();
void cancelDownload();
StatusResult getStatus() { return m_status; }
std::string getDid() { return m_did; }
std::string getFollowedBy() { return m_followedBy; }
uint64_t getTotalLength() { return m_totalLength; }
uint64_t getCompletedLength() { return m_completedLength; }
uint64_t getDownloadSpeed() { return m_downloadSpeed; }
uint64_t getVerifiedLength() { return m_verifiedLength; }
std::string getPath() { return m_path; }
std::vector<std::string>& getUris() { return m_uris; }
protected:
std::shared_ptr<Aria2> mp_aria;
StatusResult m_status;
std::string m_did = "";
std::string m_followedBy = "";
uint64_t m_totalLength;
uint64_t m_completedLength;
uint64_t m_downloadSpeed;
uint64_t m_verifiedLength;
std::vector<std::string> m_uris;
std::string m_path;
};
/**
* A tool to download things.
*
*/
class Downloader
{
public:
Downloader();
virtual ~Downloader();
void close();
Download* startDownload(const std::string& uri, const std::vector<std::pair<std::string, std::string>>& options = {});
Download* getDownload(const std::string& did);
size_t getNbDownload() { return m_knownDownloads.size(); }
std::vector<std::string> getDownloadIds();
private:
std::map<std::string, std::unique_ptr<Download>> m_knownDownloads;
std::shared_ptr<Aria2> mp_aria;
};
}
#endif

View File

@@ -1,183 +0,0 @@
/*
* Copyright 2018-2020 Matthieu Gautier <mgautier@kymeria.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef KIWIX_ENTRY_H
#define KIWIX_ENTRY_H
#include <stdio.h>
#include <zim/entry.h>
#include <zim/item.h>
#include <exception>
#include <string>
#include "common.h"
using namespace std;
namespace kiwix
{
class NoEntry : public std::exception {};
/**
* A entry represent an.. entry in a zim file.
*/
class Entry
{
public:
/**
* Construct an entry making reference to an zim article.
*
* @param article a zim::Article object
*/
Entry(zim::Entry entry);
virtual ~Entry() = default;
/**
* Get the path of the entry.
*
* The path is the "key" of an entry.
*
* @return the path of the entry.
*/
std::string getPath() const { return entry.getPath(); }
/**
* Get the title of the entry.
*
* @return the title of the entry.
*/
std::string getTitle() const { return entry.getTitle(); }
/**
* Get the content of the entry.
*
* The string is a copy of the content.
* If you don't want to do a copy, use get_blob.
*
* @return the content of the entry.
*/
std::string getContent() const { return entry.getItem().getData(); }
/**
* Get the blob of the entry.
*
* A blob make reference to the content without copying it.
*
* @param offset The starting offset of the blob.
* @return the blob of the entry.
*/
zim::Blob getBlob(offset_type offset = 0) const { return entry.getItem().getData(offset); }
/**
* Get the blob of the entry.
*
* A blob make reference to the content without copying it.
*
* @param offset The starting offset of the blob.
* @param size The size of the blob.
* @return the blob of the entry.
*/
zim::Blob getBlob(offset_type offset, size_type size) const { return entry.getItem().getData(offset, size); }
/**
* Get the info for direct access to the content of the entry.
*
* Some entry (ie binary ones) have their content plain stored
* in the zim file. Knowing the offset where the content is stored
* an user can directly read the content in the zim file bypassing the
* kiwix-lib/libzim.
*
* @return A pair specifying where to read the content.
* The string is the real file to read (may be different that .zim
* file if zim is cut).
* The offset is the offset to read in the file.
* Return <"",0> if is not possible to read directly.
*/
std::pair<std::string, offset_type> getDirectAccessInfo() const { return entry.getItem().getDirectAccessInformation(); }
/**
* Get the size of the entry.
*
* @return the size of the entry.
*/
size_type getSize() const;
/**
* Get the mime_type of the entry.
*
* @return the mime_type of the entry.
*/
std::string getMimetype() const;
/**
* Get if the entry is a redirect entry.
*
* @return True if the entry is a redirect.
*/
bool isRedirect() const;
/**
* Get if the entry is a link target entry.
*
* @return True if the entry is a link target.
*/
bool isLinkTarget() const;
/**
* Get if the entry is a deleted entry.
*
* @return True if the entry is a deleted entry.
*/
bool isDeleted() const;
/**
* Get the entry pointed by this entry.
*
* @return the entry pointed.
* @throw NoEntry if the entry is not a redirected entry.
*/
Entry getRedirectEntry() const;
/**
* Get the final entry pointed by this entry.
*
* Follow the redirection until a "not redirecting" entry is found.
* If the entry is not a redirected entry, return the entry itself.
*
* @return the final entry.
*/
Entry getFinalEntry() const;
/**
* Get the zim entry wrapped by this (kiwix) entry
*
* @return the zim entry
*/
const zim::Entry& getZimEntry() const { return entry; }
private:
zim::Entry entry;
};
}
#endif // KIWIX_ENTRY_H

View File

@@ -1,30 +0,0 @@
#ifndef KIWIXLIB_KIWIX_SERVE_H_
#define KIWIXLIB_KIWIX_SERVE_H_
#include <memory>
#include <string>
class Subprocess;
namespace kiwix {
class KiwixServe
{
public:
KiwixServe(const std::string& libraryPath, int port = 8181);
~KiwixServe();
void run();
void shutDown();
bool isRunning();
int getPort() { return m_port; }
int setPort(int port);
private:
std::unique_ptr<Subprocess> mp_kiwixServe;
int m_port;
std::string m_libraryPath;
};
}; //end namespace kiwix
#endif // KIWIXLIB_KIWIX_SERVE_H_

View File

@@ -20,269 +20,86 @@
#ifndef KIWIX_LIBRARY_H
#define KIWIX_LIBRARY_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stack>
#include <string>
#include <vector>
#include <map>
#include <memory>
#include "book.h"
#include "bookmark.h"
#include "common.h"
#include "common/regexTools.h"
#include "common/stringTools.h"
#define KIWIX_LIBRARY_VERSION "20110515"
using namespace std;
namespace kiwix
{
enum supportedIndexType { UNKNOWN, XAPIAN };
class OPDSDumper;
class Book
{
public:
Book();
~Book();
enum supportedListSortBy { UNSORTED, TITLE, SIZE, DATE, CREATOR, PUBLISHER };
enum supportedListMode {
ALL = 0,
LOCAL = 1,
REMOTE = 1 << 1,
NOLOCAL = 1 << 2,
NOREMOTE = 1 << 3,
VALID = 1 << 4,
NOVALID = 1 << 5
static bool sortByLastOpen(const Book& a, const Book& b);
static bool sortByTitle(const Book& a, const Book& b);
static bool sortBySize(const Book& a, const Book& b);
static bool sortByDate(const Book& a, const Book& b);
static bool sortByCreator(const Book& a, const Book& b);
static bool sortByPublisher(const Book& a, const Book& b);
static bool sortByLanguage(const Book& a, const Book& b);
string getHumanReadableIdFromPath();
string id;
string path;
string pathAbsolute;
string last;
string indexPath;
string indexPathAbsolute;
supportedIndexType indexType;
string title;
string description;
string language;
string creator;
string publisher;
string date;
string url;
string name;
string tags;
string origId;
string articleCount;
string mediaCount;
bool readOnly;
string size;
string favicon;
string faviconMimeType;
};
class Filter {
private:
uint64_t activeFilters;
std::vector<std::string> _acceptTags;
std::vector<std::string> _rejectTags;
std::string _lang;
std::string _publisher;
std::string _creator;
size_t _maxSize;
std::string _query;
std::string _name;
public:
Filter();
~Filter() = default;
/**
* Set the filter to check local.
*
* A local book is a book with a path.
* If accept is true, only local book are accepted.
* If accept is false, only non local book are accepted.
*/
Filter& local(bool accept);
/**
* Set the filter to check remote.
*
* A remote book is a book with a url.
* If accept is true, only remote book are accepted.
* If accept is false, only non remote book are accepted.
*/
Filter& remote(bool accept);
/**
* Set the filter to check validity.
*
* A valid book is a book with a path pointing to a existing zim file.
* If accept is true, only valid book are accepted.
* If accept is false, only non valid book are accepted.
*/
Filter& valid(bool accept);
/**
* Set the filter to only accept book with corresponding tag.
*/
Filter& acceptTags(std::vector<std::string> tags);
Filter& rejectTags(std::vector<std::string> tags);
Filter& lang(std::string lang);
Filter& publisher(std::string publisher);
Filter& creator(std::string creator);
Filter& maxSize(size_t size);
Filter& query(std::string query);
Filter& name(std::string name);
bool accept(const Book& book) const;
};
/**
* A Library store several books.
*/
class Library
{
std::map<std::string, kiwix::Book> m_books;
std::map<std::string, std::shared_ptr<Reader>> m_readers;
std::vector<kiwix::Bookmark> m_bookmarks;
public:
Library();
~Library();
/**
* Add a book to the library.
*
* If a book already exist in the library with the same id, update
* the existing book instead of adding a new one.
*
* @param book The book to add.
* @return True if the book has been added.
* False if a book has been updated.
*/
string version;
bool addBook(const Book& book);
bool removeBookByIndex(const unsigned int bookIndex);
vector<kiwix::Book> books;
/**
* Add a bookmark to the library.
*
* @param bookmark the book to add.
/*
* 'current' is the variable storing the current content/book id
* in the library. This is used to be able to load per default a
* content. As Kiwix may work with many library XML files, you may
* have "current" defined many time with different values. The
* last XML file read has the priority, Although we do not have an
* library object for each file, we want to be able to fallback to
* an 'old' current book if the one which should be load
* failed. That is the reason why we need a stack here
*/
void addBookmark(const Bookmark& bookmark);
/**
* Remove a bookmarkk
*
* @param zimId The zimId of the bookmark.
* @param url The url of the bookmark.
* @return True if the bookmark has been removed.
*/
bool removeBookmark(const std::string& zimId, const std::string& url);
Book& getBookById(const std::string& id);
Book& getBookByPath(const std::string& path);
std::shared_ptr<Reader> getReaderById(const std::string& id);
/**
* Remove a book from the library.
*
* @param id the id of the book to remove.
* @return True if the book were in the lirbrary and has been removed.
*/
bool removeBookById(const std::string& id);
/**
* Write the library to a file.
*
* @param path the path of the file to write to.
* @return True if the library has been correctly saved.
*/
bool writeToFile(const std::string& path);
/**
* Write the library bookmarks to a file.
*
* @param path the path of the file to write to.
* @return True if the library has been correctly saved.
*/
bool writeBookmarksToFile(const std::string& path);
/**
* Get the number of book in the library.
*
* @param localBooks If we must count local books (books with a path).
* @param remoteBooks If we must count remote books (books with an url)
* @return The number of books.
*/
unsigned int getBookCount(const bool localBooks, const bool remoteBooks);
/**
* Get all langagues of the books in the library.
*
* @return A list of languages.
*/
std::vector<std::string> getBooksLanguages();
/**
* Get all book creators of the books in the library.
*
* @return A list of book creators.
*/
std::vector<std::string> getBooksCreators();
/**
* Get all book publishers of the books in the library.
*
* @return A list of book publishers.
*/
std::vector<std::string> getBooksPublishers();
/**
* Get all bookmarks.
*
* @return A list of bookmarks
*/
const std::vector<kiwix::Bookmark> getBookmarks(bool onlyValidBookmarks = true);
/**
* Get all book ids of the books in the library.
*
* @return A list of book ids.
*/
std::vector<std::string> getBooksIds();
/**
* Filter the library and generate a new one with the keep elements.
*
* This is equivalent to `listBookIds(ALL, UNSORTED, search)`.
*
* @param search List only books with search in the title or description.
* @return The list of bookIds corresponding to the query.
*/
DEPRECATED std::vector<std::string> filter(const std::string& search);
/**
* Filter the library and return the id of the keep elements.
*
* @param filter The filter to use.
* @return The list of bookIds corresponding to the filter.
*/
std::vector<std::string> filter(const Filter& filter);
/**
* Sort (in place) bookIds using the given comparator.
*
* @param bookIds the list of book Ids to sort
* @param comparator how to sort the books
* @return The sorted list of books
*/
void sort(std::vector<std::string>& bookIds, supportedListSortBy sortBy, bool ascending);
/**
* List books in the library.
*
* @param mode The mode of listing :
* - LOCAL  : list only local books (with a path).
* - REMOTE : list only remote books (with an url).
* - VALID  : list only valid books (without a path or with a
* path pointing to a valid zim file).
* - NOLOCAL : list only books without valid path.
* - NOREMOTE : list only books without url.
* - NOVALID : list only books not valid.
* - ALL : Do not do any filter (LOCAL or REMOTE)
* - Flags can be combined.
* @param sortBy Attribute to sort by the book list.
* @param search List only books with search in the title, description.
* @param language List only books in this language.
* @param creator List only books of this creator.
* @param publisher List only books of this publisher.
* @param maxSize Do not list book bigger than maxSize.
* Set to 0 to cancel this filter.
* @return The list of bookIds corresponding to the query.
*/
DEPRECATED std::vector<std::string> listBooksIds(
int supportedListMode = ALL,
supportedListSortBy sortBy = UNSORTED,
const std::string& search = "",
const std::string& language = "",
const std::string& creator = "",
const std::string& publisher = "",
const std::vector<std::string>& tags = {},
size_t maxSize = 0);
friend class OPDSDumper;
friend class libXMLDumper;
stack<string> current;
};
}

View File

@@ -1,83 +0,0 @@
/*
* Copyright 2018 Matthieu Gautier <mgautier@kymeria.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef KIWIX_LIBXML_DUMPER_H
#define KIWIX_LIBXML_DUMPER_H
#include <string>
#include <vector>
#include <pugixml.hpp>
#include "library.h"
namespace kiwix
{
/**
* A tool to dump a `Library` into a basic library.xml
*
*/
class LibXMLDumper
{
public:
LibXMLDumper() = default;
LibXMLDumper(Library* library);
~LibXMLDumper();
/**
* Dump the library.xml
*
* @param id The id of the library.
* @return The library.xml content.
*/
std::string dumpLibXMLContent(const std::vector<std::string>& bookIds);
/**
* Dump the bookmark of the library.
*
* @return The bookmark.xml content.
*/
std::string dumpLibXMLBookmark();
/**
* Set the base directory used.
*
* @param baseDir the base directory to use.
*/
void setBaseDir(const std::string& baseDir) { this->baseDir = baseDir; }
/**
* Set the library to dump.
*
* @param library The library to dump.
*/
void setLibrary(Library* library) { this->library = library; }
protected:
kiwix::Library* library;
std::string baseDir;
private:
void handleBook(Book book, pugi::xml_node root_node);
void handleBookmark(Bookmark bookmark, pugi::xml_node root_node);
};
}
#endif // KIWIX_OPDS_DUMPER_H

View File

@@ -20,147 +20,88 @@
#ifndef KIWIX_MANAGER_H
#define KIWIX_MANAGER_H
#include "book.h"
#include <time.h>
#include <sstream>
#include <string>
#include <pugixml.hpp>
#include "common/base64.h"
#include "common/pathTools.h"
#include "common/regexTools.h"
#include "library.h"
#include "reader.h"
#include <string>
#include <vector>
namespace pugi {
class xml_document;
}
using namespace std;
namespace kiwix
{
enum supportedListMode { LASTOPEN, REMOTE, LOCAL };
enum supportedListSortBy { TITLE, SIZE, DATE, CREATOR, PUBLISHER };
class LibraryManipulator {
public:
virtual ~LibraryManipulator() {}
virtual bool addBookToLibrary(Book book) = 0;
virtual void addBookmarkToLibrary(Bookmark bookmark) = 0;
};
class DefaultLibraryManipulator : public LibraryManipulator {
public:
DefaultLibraryManipulator(Library* library) :
library(library) {}
virtual ~DefaultLibraryManipulator() {}
bool addBookToLibrary(Book book) {
return library->addBook(book);
}
void addBookmarkToLibrary(Bookmark bookmark) {
library->addBookmark(bookmark);
}
private:
kiwix::Library* library;
};
/**
* A tool to manage a `Library`.
*/
class Manager
{
public:
Manager(LibraryManipulator* manipulator);
Manager(Library* library);
Manager();
~Manager();
/**
* Read a `library.xml` and add book in the file to the library.
*
* @param path The (utf8) path to the `library.xml`.
* @param readOnly Set if the libray path could be overwritten latter with
* updated content.
* @return True if file has been properly parsed.
*/
bool readFile(const std::string& path, bool readOnly = true, bool trustLibrary = true);
/**
* Load a library content store in the string.
*
* @param xml The content corresponding of the library xml
* @param readOnly Set if the libray path could be overwritten latter with
* updated content.
* @param libraryPath The library path (used to resolve relative path)
* @return True if the content has been properly parsed.
*/
bool readXml(const std::string& xml,
bool readFile(const string path, const bool readOnly = true);
bool readFile(const string nativePath,
const string UTF8Path,
const bool readOnly = true);
bool readXml(const string xml,
const bool readOnly = true,
const std::string& libraryPath = "",
bool trustLibrary = true);
/**
* Load a library content stored in a OPDS stream.
*
* @param content The content of the OPDS stream.
* @param readOnly Set if the library path could be overwritten later with
* updated content.
* @param libraryPath The library path (used to resolve relative path)
* @return True if the content has been properly parsed.
*/
bool readOpds(const std::string& content, const std::string& urlHost);
/**
* Load a bookmark file.
*
* @param path The path of the file to read.
* @return True if the content has been properly parsed.
*/
bool readBookmarkFile(const std::string& path);
/**
* Add a book to the library.
*
* @param pathToOpen The path to the zim file to add.
* @param pathToSave The path to store in the library in place of pathToOpen.
* @param url The url of the book to store in the library.
* @param checMetaData Tell if we check metadata before adding book to the
* library.
* @return The id of the book if the book has been added to the library.
* Else, an empty string.
*/
std::string addBookFromPathAndGetId(const std::string& pathToOpen,
const std::string& pathToSave = "",
const std::string& url = "",
const string libraryPath = "");
bool writeFile(const string path);
bool removeBookByIndex(const unsigned int bookIndex);
bool removeBookById(const string id);
bool setCurrentBookId(const string id);
string getCurrentBookId();
bool setBookIndex(const string id,
const string path,
const supportedIndexType type);
bool setBookIndex(const string id, const string path);
bool setBookPath(const string id, const string path);
string addBookFromPathAndGetId(const string pathToOpen,
const string pathToSave = "",
const string url = "",
const bool checkMetaData = false);
/**
* Add a book to the library.
*
* @param pathToOpen The path to the zim file to add.
* @param pathToSave The path to store in the library in place of pathToOpen.
* @param url The url of the book to store in the library.
* @param checMetaData Tell if we check metadata before adding book to the
* library.
* @return True if the book has been added to the library.
*/
bool addBookFromPath(const std::string& pathToOpen,
const std::string& pathToSave = "",
const std::string& url = "",
bool addBookFromPath(const string pathToOpen,
const string pathToSave = "",
const string url = "",
const bool checkMetaData = false);
Library cloneLibrary();
bool getBookById(const string id, Book& book);
bool getCurrentBook(Book& book);
unsigned int getBookCount(const bool localBooks, const bool remoteBooks);
bool updateBookLastOpenDateById(const string id);
void removeBookPaths();
bool listBooks(const supportedListMode mode,
const supportedListSortBy sortBy,
const unsigned int maxSize,
const string language,
const string creator,
const string publisher,
const string search);
vector<string> getBooksLanguages();
vector<string> getBooksCreators();
vector<string> getBooksPublishers();
vector<string> getBooksIds();
std::string writableLibraryPath;
string writableLibraryPath;
bool m_hasSearchResult = false;
uint64_t m_totalBooks = 0;
uint64_t m_startIndex = 0;
uint64_t m_itemsPerPage = 0;
vector<std::string> bookIdList;
protected:
kiwix::LibraryManipulator* manipulator;
bool mustDeleteManipulator;
kiwix::Library library;
bool readBookFromPath(const std::string& path, Book* book);
bool readBookFromPath(const string path, Book* book = NULL);
bool parseXmlDom(const pugi::xml_document& doc,
bool readOnly,
const std::string& libraryPath,
bool trustLibrary);
bool parseOpdsDom(const pugi::xml_document& doc,
const std::string& urlHost);
const bool readOnly,
const string libraryPath);
private:
void checkAndCleanBookPaths(Book& book, const string& libraryPath);
};
}

View File

@@ -1,30 +1,30 @@
headers = [
'book.h',
'bookmark.h',
'common.h',
'library.h',
'manager.h',
'libxml_dumper.h',
'opds_dumper.h',
'downloader.h',
'reader.h',
'entry.h',
'searcher.h',
'search_renderer.h',
'server.h',
'kiwixserve.h',
'name_mapper.h'
'searcher.h'
]
if xapian_dep.found()
headers += ['xapianSearcher.h']
endif
install_headers(headers, subdir:'kiwix')
install_headers(
'tools/base64.h',
'tools/networkTools.h',
'tools/otherTools.h',
'tools/pathTools.h',
'tools/regexTools.h',
'tools/stringTools.h',
subdir:'kiwix/tools'
'common/base64.h',
'common/networkTools.h',
'common/otherTools.h',
'common/pathTools.h',
'common/regexTools.h',
'common/stringTools.h',
subdir:'kiwix/common'
)
if has_ctpp2_dep
install_headers(
'ctpp2/CTPP2VMStringLoader.hpp',
subdir:'kiwix/ctpp2'
)
endif

View File

@@ -1,61 +0,0 @@
/*
* Copyright 2019 Matthieu Gautier <mgautier@kymeria.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef KIWIX_NAMEMAPPER_H
#define KIWIX_NAMEMAPPER_H
#include <string>
#include <map>
namespace kiwix
{
class Library;
class NameMapper {
public:
virtual ~NameMapper() = default;
virtual std::string getNameForId(const std::string& id) = 0;
virtual std::string getIdForName(const std::string& name) = 0;
};
class IdNameMapper : public NameMapper {
public:
virtual std::string getNameForId(const std::string& id) { return id; };
virtual std::string getIdForName(const std::string& name) { return name; };
};
class HumanReadableNameMapper : public NameMapper {
private:
std::map<std::string, std::string> m_idToName;
std::map<std::string, std::string> m_nameToId;
public:
HumanReadableNameMapper(kiwix::Library& library, bool withAlias);
virtual ~HumanReadableNameMapper() = default;
virtual std::string getNameForId(const std::string& id);
virtual std::string getIdForName(const std::string& name);
};
}
#endif

View File

@@ -1,120 +0,0 @@
/*
* Copyright 2017 Matthieu Gautier <mgautier@kymeria.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef KIWIX_OPDS_DUMPER_H
#define KIWIX_OPDS_DUMPER_H
#include <time.h>
#include <sstream>
#include <string>
#include <pugixml.hpp>
#include "tools/base64.h"
#include "tools/pathTools.h"
#include "tools/regexTools.h"
#include "library.h"
#include "reader.h"
using namespace std;
namespace kiwix
{
/**
* A tool to dump a `Library` into a opds stream.
*
*/
class OPDSDumper
{
public:
OPDSDumper() = default;
OPDSDumper(Library* library);
~OPDSDumper();
/**
* Dump the OPDS feed.
*
* @param id The id of the library.
* @return The OPDS feed.
*/
std::string dumpOPDSFeed(const std::vector<std::string>& bookIds);
/**
* Set the id of the opds stream.
*
* @param id the id to use.
*/
void setId(const std::string& id) { this->id = id;}
/**
* Set the title oft the opds stream.
*
* @param title the title to use.
*/
void setTitle(const std::string& title) { this->title = title; }
/**
* Set the root location used when generating url.
*
* @param rootLocation the root location to use.
*/
void setRootLocation(const std::string& rootLocation) { this->rootLocation = rootLocation; }
/**
* Set the search url.
*
* @param searchUrl the search url to use.
*/
void setSearchDescriptionUrl(const std::string& searchDescriptionUrl) { this->searchDescriptionUrl = searchDescriptionUrl; }
/**
* Set some informations about the search results.
*
* @param totalResult the total number of results of the search.
* @param startIndex the start index of the result.
* @param count the number of result of the current set (or page).
*/
void setOpenSearchInfo(int totalResult, int startIndex, int count);
/**
* Set the library to dump.
*
* @param library The library to dump.
*/
void setLibrary(Library* library) { this->library = library; }
protected:
kiwix::Library* library;
std::string id;
std::string title;
std::string date;
std::string rootLocation;
std::string searchDescriptionUrl;
int m_totalResults;
int m_startIndex;
int m_count;
bool m_isSearchResult = false;
private:
pugi::xml_node handleBook(Book book, pugi::xml_node root_node);
};
}
#endif // KIWIX_OPDS_DUMPER_H

View File

@@ -21,439 +21,105 @@
#define KIWIX_READER_H
#include <stdio.h>
#include <zim/article.h>
#include <zim/file.h>
#include <zim/fileiterator.h>
#include <zim/zim.h>
#include <zim/archive.h>
#include <exception>
#include <map>
#include <sstream>
#include <string>
#include "common.h"
#include "entry.h"
#include "tools/pathTools.h"
#include "tools/stringTools.h"
#include "common/pathTools.h"
#include "common/stringTools.h"
using namespace std;
namespace kiwix
{
/**
* The Reader class is the class who allow to get an entry content from a zim
* file.
*/
using SuggestionsList_t = std::vector<std::vector<std::string>>;
class Reader
{
public:
/**
* Create a Reader to read a zim file specified by zimFilePath.
*
* @param zimFilePath The path to the zim file to read.
* The zim file can be splitted (.zimaa, .zimab, ...).
* In this case, the file path must still point to the
* unsplitted path as if the file were not splitted
* (.zim extesion).
*/
Reader(const string zimFilePath);
~Reader() = default;
~Reader();
/**
* Get the number of "displayable" entries in the zim file.
*
* @return If the zim file has a /M/Counter metadata, return the number of
* entries with the 'text/html' MIMEtype specified in the metadata.
* Else return the number of entries in the 'A' namespace.
*/
void reset();
unsigned int getArticleCount() const;
/**
* Get the number of media in the zim file.
*
* @return If the zim file has a /M/Counter metadata, return the number of
* entries with the 'image/jpeg', 'image/gif' and 'image/png' in
* the metadata.
* Else return the number of entries in the 'I' namespace.
*/
unsigned int getMediaCount() const;
/**
* Get the number of all entries in the zim file.
*
* @return Return the number of all the entries, whatever their MIMEtype or
* their namespace.
*/
unsigned int getGlobalCount() const;
/**
* Get the path of the zim file.
*
* @return the path of the zim file as given in the constructor.
*/
string getZimFilePath() const;
/**
* Get the Id of the zim file.
*
* @return The uuid stored in the zim file.
*/
string getId() const;
/**
* Get a random page.
*
* @return A random Entry. The entry is picked from all entries in
* the 'A' namespace.
* The main entry is excluded from the potential results.
*/
Entry getRandomPage() const;
/**
* Get the entry of the main page.
*
* @return Entry of the main page as specified in the zim file.
*/
Entry getMainPage() const;
/**
* Get the content of a metadata.
*
* @param[in] name The name of the metadata.
* @param[out] value The value will be set to the content of the metadata.
* @return True if it was possible to get the content of the metadata.
*/
bool getMetadata(const string& name, string& value) const;
/**
* Get the name of the zim file.
*
* @return The name of the zim file as specified in the zim metadata.
*/
string getName() const;
/**
* Get the title of the zim file.
*
* @return The title of zim file as specified in the zim metadata.
* If no title has been set, return a title computed from the
* file path.
*/
string getRandomPageUrl() const;
string getFirstPageUrl() const;
string getMainPageUrl() const;
bool getMetatag(const string& url, string& content) const;
string getTitle() const;
/**
* Get the creator of the zim file.
*
* @return The creator of the zim file as specified in the zim metadata.
*/
string getCreator() const;
/**
* Get the publisher of the zim file.
*
* @return The publisher of the zim file as specified in the zim metadata.
*/
string getPublisher() const;
/**
* Get the date of the zim file.
*
* @return The date of the zim file as specified in the zim metadata.
*/
string getDate() const;
/**
* Get the description of the zim file.
*
* @return The description of the zim file as specified in the zim metadata.
* If no description has been set, return the subtitle.
*/
string getDescription() const;
/**
* Get the long description of the zim file.
*
* @return The long description of the zim file as specifed in the zim metadata.
*/
string getLongDescription() const;
/**
* Get the language of the zim file.
*
* @return The language of the zim file as specified in the zim metadata.
*/
string getLanguage() const;
/**
* Get the license of the zim file.
*
* @return The license of the zim file as specified in the zim metadata.
*/
string getLicense() const;
/**
* Get the tags of the zim file.
*
* @param original If true, return the original tags as specified in the zim metadata.
* Else, try to convert it to the new 'normalized' format.
* @return The tags of the zim file.
*/
string getTags(bool original=false) const;
/**
* Get the value (as a string) of a specific tag.
*
* According to https://wiki.openzim.org/wiki/Tags
*
* @return The value of the specified tag.
* @throw std::out_of_range if the specified tag is not found.
*/
string getTagStr(const std::string& tagName) const;
/**
* Get the boolean value of a specific tag.
*
* According to https://wiki.openzim.org/wiki/Tags
*
* @return The boolean value of the specified tag.
* @throw std::out_of_range if the specified tag is not found.
* std::domain_error if the value of the tag cannot be convert to bool.
*/
bool getTagBool(const std::string& tagName) const;
/**
* Get the relations of the zim file.
*
* @return The relation of the zim file as specified in the zim metadata.
*/
string getRelation() const;
/**
* Get the flavour of the zim file.
*
* @return The flavour of the zim file as specified in the zim metadata.
*/
string getFlavour() const;
/**
* Get the source of the zim file.
*
* @return The source of the zim file as specified in the zim metadata.
*/
string getSource() const;
/**
* Get the scraper of the zim file.
*
* @return The scraper of the zim file as specified in the zim metadata.
*/
string getScraper() const;
/**
* Get the origId of the zim file.
*
* The origId is only used in the case of patch zim file and is the Id
* of the original zim file.
*
* @return The origId of the zim file as specified in the zim metadata.
*/
string getName() const;
string getTags() const;
string getDate() const;
string getCreator() const;
string getPublisher() const;
string getOrigId() const;
/**
* Get the favicon of the zim file.
*
* @param[out] content The content of the favicon.
* @param[out] mimeType The mimeType of the favicon.
* @return True if a favicon has been found.
*/
bool getFavicon(string& content, string& mimeType) const;
/**
* Get an entry associated to an path.
*
* @param path The path of the entry.
* @return The entry.
* @throw NoEntry If no entry correspond to the path.
*/
Entry getEntryFromPath(const std::string& path) const;
/**
* Get an entry associated to an url encoded path.
*
* Equivalent to `getEntryFromPath(urlDecode(path));`
*
* @param path The url encoded path.
* @return The entry.
* @throw NoEntry If no entry correspond to the path.
*/
Entry getEntryFromEncodedPath(const std::string& path) const;
/**
* Get un entry associated to a title.
*
* @param title The title.
* @return The entry
* throw NoEntry If no entry correspond to the url.
*/
Entry getEntryFromTitle(const std::string& title) const;
/**
* Search for entries with title starting with prefix (case sensitive).
*
* Suggestions are stored in an internal vector and can be retrieved using
* `getNextSuggestion` method.
* This method is not thread safe and is deprecated. Use :
* bool searchSuggestions(const string& prefix,
* unsigned int suggestionsCount,
* SuggestionsList_t& results);
*
* @param prefix The prefix to search.
* @param suggestionsCount How many suggestions to search for.
* @param reset If true, remove previous suggestions in the internal vector.
* If false, add suggestions to the internal vector
* (until internal vector size is suggestionCount (or no more
* suggestion))
* @return True if some suggestions have been added to the internal vector.
*/
DEPRECATED bool searchSuggestions(const string& prefix,
unsigned int suggestionsCount,
const bool reset = true);
/**
* Search for entries with title starting with prefix (case sensitive).
*
* Suggestions are added to the `result` vector.
*
* @param prefix The prefix to search.
* @param suggestionsCount How many suggestions to search for.
* @param result The vector where to store the suggestions.
* @return True if some suggestions have been added to the vector.
*/
bool getPageUrlFromTitle(const string& title, string& url) const;
bool getMimeTypeByUrl(const string& url, string& mimeType) const;
bool getContentByUrl(const string& url,
string& content,
string& title,
unsigned int& contentLength,
string& contentType) const;
bool getContentByEncodedUrl(const string& url,
string& content,
string& title,
unsigned int& contentLength,
string& contentType,
string& baseUrl) const;
bool getContentByEncodedUrl(const string& url,
string& content,
string& title,
unsigned int& contentLength,
string& contentType) const;
bool getContentByDecodedUrl(const string& url,
string& content,
string& title,
unsigned int& contentLength,
string& contentType,
string& baseUrl) const;
bool getContentByDecodedUrl(const string& url,
string& content,
string& title,
unsigned int& contentLength,
string& contentType) const;
bool searchSuggestions(const string& prefix,
unsigned int suggestionsCount,
SuggestionsList_t& resuls);
/**
* Search for entries for the given prefix.
*
* If the zim file has a internal fulltext index, the suggestions will be
* searched using it.
* Else the suggestions will be search using `searchSuggestions` while trying
* to be smart about case sensitivity (using `getTitleVariants`).
*
* In any case, suggestions are stored in an internal vector and can be
* retrieved using `getNextSuggestion` method.
* The internal vector will be reset.
* This method is not thread safe and is deprecated. Use :
* bool searchSuggestionsSmart(const string& prefix,
* unsigned int suggestionsCount,
* SuggestionsList_t& results);
*
* @param prefix The prefix to search for.
* @param suggestionsCount How many suggestions to search for.
*/
DEPRECATED bool searchSuggestionsSmart(const string& prefix,
const bool reset = true);
bool searchSuggestionsSmart(const string& prefix,
unsigned int suggestionsCount);
/**
* Search for entries for the given prefix.
*
* If the zim file has a internal fulltext index, the suggestions will be
* searched using it.
* Else the suggestions will be search using `searchSuggestions` while trying
* to be smart about case sensitivity (using `getTitleVariants`).
*
* In any case, suggestions are stored in an internal vector and can be
* retrieved using `getNextSuggestion` method.
* The internal vector will be reset.
*
* @param prefix The prefix to search for.
* @param suggestionsCount How many suggestions to search for.
* @param results The vector where to store the suggestions
* @return True if some suggestions have been added to the results.
*/
bool searchSuggestionsSmart(const string& prefix,
unsigned int suggestionsCount,
SuggestionsList_t& results);
/**
* Check if the path exists in the zim file.
*
* @param path the path to check.
* @return True if the path exists in the zim file.
*/
bool pathExists(const string& path) const;
/**
* Check if the zim file has a embedded fulltext index.
*
* @return True if the zim file has a embedded fulltext index
* and is not split (else the fulltext is not accessible).
*/
bool urlExists(const string& url) const;
bool hasFulltextIndex() const;
/**
* Get potential case title variations for a title.
*
* @param title a title.
* @return the list of variantions.
*/
std::vector<std::string> getTitleVariants(const std::string& title) const;
/**
* Get the next suggestion title.
*
* @param[out] title the title of the suggestion.
* @return True if title has been set.
*/
DEPRECATED bool getNextSuggestion(string& title);
/**
* Get the next suggestion title and url.
*
* @param[out] title the title of the suggestion.
* @param[out] url the url of the suggestion.
* @return True if title and url have been set.
*/
DEPRECATED bool getNextSuggestion(string& title, string& url);
/**
* Get if we can check zim file integrity (has a checksum).
*
* @return True if zim file have a checksum.
*/
bool getNextSuggestion(string& title);
bool getNextSuggestion(string& title, string& url);
bool canCheckIntegrity() const;
/**
* Check is zim file is corrupted.
*
* @return True if zim file is corrupted.
*/
bool isCorrupted() const;
/**
* Return the total size of the zim file.
*
* If zim file is split, return the sum of all parts' size.
*
* @return Size of the size file is KiB.
*/
bool parseUrl(const string& url, char* ns, string& title) const;
unsigned int getFileSize() const;
/**
* Get the zim file handler.
*
* @return The libzim file handler.
*/
zim::Archive* getZimArchive() const;
zim::File* getZimFileHandler() const;
bool getArticleObjectByDecodedUrl(const string& url,
zim::Article& article) const;
protected:
std::unique_ptr<zim::Archive> zimArchive;
zim::File* zimFileHandler;
zim::size_type firstArticleOffset;
zim::size_type lastArticleOffset;
zim::size_type currentArticleOffset;
zim::size_type nsACount;
zim::size_type nsICount;
std::string zimFilePath;
SuggestionsList_t suggestions;
SuggestionsList_t::iterator suggestionsOffset;
std::vector<std::vector<std::string>> suggestions;
std::vector<std::vector<std::string>>::iterator suggestionsOffset;
private:
std::map<const std::string, unsigned int> parseCounterMetadata() const;

View File

@@ -1,91 +0,0 @@
/*
* Copyright 2011 Emmanuel Engelhart <kelson@kiwix.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef KIWIX_SEARCH_RENDERER_H
#define KIWIX_SEARCH_RENDERER_H
#include <string>
namespace kiwix
{
class Searcher;
class NameMapper;
/**
* The SearcherRenderer class is used to render a search result to a html page.
*/
class SearchRenderer
{
public:
/**
* The default constructor.
*
* @param humanReadableName The global zim's humanReadableName.
* Used to generate pagination links.
*/
SearchRenderer(Searcher* searcher, NameMapper* mapper);
~SearchRenderer();
void setSearchPattern(const std::string& pattern);
/**
* Set the search content id.
*/
void setSearchContent(const std::string& name);
/**
* Set protocol prefix.
*/
void setProtocolPrefix(const std::string& prefix);
/**
* Set search protocol prefix.
*/
void setSearchProtocolPrefix(const std::string& prefix);
/**
* set result count per page
*/
void setPageLength(unsigned int pageLength){
this->pageLength = pageLength;
}
/**
* Generate the html page with the resutls of the search.
*/
std::string getHtml();
protected:
std::string beautifyInteger(const unsigned int number);
Searcher* mp_searcher;
NameMapper* mp_nameMapper;
std::string searchContent;
std::string searchPattern;
std::string protocolPrefix;
std::string searchProtocolPrefix;
unsigned int pageLength;
unsigned int estimatedResultCount;
unsigned int resultStart;
};
}
#endif

View File

@@ -29,8 +29,9 @@
#include <string>
#include <vector>
#include <vector>
#include "tools/pathTools.h"
#include "tools/stringTools.h"
#include "common/pathTools.h"
#include "common/stringTools.h"
#include "kiwix_config.h"
using namespace std;
@@ -52,98 +53,31 @@ class Result
};
struct SearcherInternal;
/**
* The Searcher class is reponsible to do different kind of search using the
* fulltext index.
*/
class Searcher
{
public:
/**
* The default constructor.
*/
Searcher();
Searcher(const string& xapianDirectoryPath,
Reader* reader,
const string& humanReadableName);
~Searcher();
/**
* Add a reader (containing embedded fulltext index) to the search.
*
* @param reader The Reader for the zim containing the fulltext index.
* @return true if the reader has been added.
* false if the reader cannot be added (no embedded fulltext index present)
*/
bool add_reader(Reader* reader);
Reader* get_reader(int index);
/**
* Start a search on the zim associated to the Searcher.
*
* Search results should be retrived using the getNextResult method.
*
* @param search The search query.
* @param resultStart the start offset of the search results (used for pagination).
* @param resultEnd the end offset of the search results (used for pagination).
* @param verbose print some info on stdout if true.
*/
void search(const std::string& search,
void add_reader(Reader* reader, const std::string& humanReaderName);
void search(std::string& search,
unsigned int resultStart,
unsigned int resultEnd,
const bool verbose = false);
/**
* Start a geographique search.
* The search return result for entry in a disc of center latitude/longitude
* and radius distance.
*
* Search results should be retrived using the getNextResult method.
*
* @param latitude The latitude of the center point.
* @param longitude The longitude of the center point.
* @param distance The radius of the disc.
* @param resultStart the start offset of the search results (used for pagination).
* @param resultEnd the end offset of the search results (used for pagination).
* @param verbose print some info on stdout if true.
*/
void geo_search(float latitude, float longitude, float distance,
unsigned int resultStart,
unsigned int resultEnd,
const bool verbose = false);
/**
* Start a suggestion search.
* The search made depend of the "version" of the embedded index.
* - If the index is newer enough and have a title namespace, the search is
* made in the titles only.
* - Else the search is made on the whole article content.
* In any case, the search is made "partial" (as adding '*' at the end of the query)
*
* @param search The search query.
* @param verbose print some info on stdout if true.
*/
void suggestions(std::string& search, const bool verbose = false);
/**
* Get the next result of a started search.
* This is the method to use to loop hover the search results.
*/
Result* getNextResult();
/**
* Restart the previous search.
* Next call to getNextResult will return the first result.
*/
void restart_search();
/**
* Get a estimation of the result count.
*/
unsigned int getEstimatedResultCount();
bool setProtocolPrefix(const std::string prefix);
bool setSearchProtocolPrefix(const std::string prefix);
void reset();
unsigned int getResultStart() { return resultStart; }
unsigned int getResultEnd() { return resultEnd; }
#ifdef ENABLE_CTPP2
string getHtml();
#endif
protected:
std::string beautifyInteger(const unsigned int number);
@@ -154,18 +88,17 @@ class Searcher
const bool verbose = false);
std::vector<Reader*> readers;
std::vector<std::string> humanReaderNames;
SearcherInternal* internal;
std::string searchPattern;
std::string protocolPrefix;
std::string searchProtocolPrefix;
unsigned int resultCountPerPage;
unsigned int estimatedResultCount;
unsigned int resultStart;
unsigned int resultEnd;
private:
void reset();
std::string contentHumanReadableId;
};
}
#endif

View File

@@ -1,78 +0,0 @@
/*
* Copyright 2019 Matthieu Gautier <mgautier@kymeria.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef KIWIX_SERVER_H
#define KIWIX_SERVER_H
#include <string>
#include <memory>
namespace kiwix
{
class Library;
class NameMapper;
class InternalServer;
class Server {
public:
/**
* The default constructor.
*
* @param library The library to serve.
*/
Server(Library* library, NameMapper* nameMapper=nullptr);
virtual ~Server();
/**
* Serve the content.
*/
bool start();
/**
* Stop the daemon.
*/
void stop();
void setRoot(const std::string& root);
void setAddress(const std::string& addr) { m_addr = addr; }
void setPort(int port) { m_port = port; }
void setNbThreads(int threads) { m_nbThreads = threads; }
void setVerbose(bool verbose) { m_verbose = verbose; }
void setTaskbar(bool withTaskbar, bool withLibraryButton)
{ m_withTaskbar = withTaskbar; m_withLibraryButton = withLibraryButton; }
void setBlockExternalLinks(bool blockExternalLinks)
{ m_blockExternalLinks = blockExternalLinks; }
protected:
Library* mp_library;
NameMapper* mp_nameMapper;
std::string m_root = "";
std::string m_addr = "";
int m_port = 80;
int m_nbThreads = 1;
bool m_verbose = false;
bool m_withTaskbar = true;
bool m_withLibraryButton = true;
bool m_blockExternalLinks = false;
std::unique_ptr<InternalServer> mp_server;
};
}
#endif

View File

@@ -1,4 +0,0 @@
#include <string>
std::string base64_encode(const std::string& inString);
std::string base64_decode(const std::string& s);

View File

@@ -1,50 +0,0 @@
/*
* Copyright 2014 Emmanuel Engelhart <kelson@kiwix.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef KIWIX_OTHERTOOLS_H
#define KIWIX_OTHERTOOLS_H
#include <string>
#include <vector>
#include <map>
#include <zim/zim.h>
namespace pugi {
class xml_node;
}
namespace kiwix
{
void sleep(unsigned int milliseconds);
std::string nodeToString(const pugi::xml_node& node);
std::string converta2toa3(const std::string& a2code);
/*
* Convert all format tag string to new format
*/
std::vector<std::string> convertTags(const std::string& tags_str);
std::string getTagValueFromTagList(const std::vector<std::string>& tagList,
const std::string& tagName);
bool convertStrToBool(const std::string& value);
using MimeCounterType = std::map<const std::string, zim::entry_index_type>;
MimeCounterType parseMimetypeCounter(const std::string& counterData);
}
#endif

View File

@@ -1,48 +0,0 @@
/*
* Copyright 2011 Emmanuel Engelhart <kelson@kiwix.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef KIWIX_PATHTOOLS_H
#define KIWIX_PATHTOOLS_H
#include <string>
#ifdef _WIN32
std::string WideToUtf8(const std::wstring& wstr);
std::wstring Utf8ToWide(const std::string& str);
#endif
bool isRelativePath(const std::string& path);
std::string computeAbsolutePath(const std::string& path, const std::string& relativePath);
std::string computeRelativePath(const std::string& path, const std::string& absolutePath);
std::string removeLastPathElement(const std::string& path);
std::string appendToDirectory(const std::string& directoryPath, const std::string& filename);
unsigned int getFileSize(const std::string& path);
std::string getFileSizeAsString(const std::string& path);
std::string getFileContent(const std::string& path);
bool fileExists(const std::string& path);
bool makeDirectory(const std::string& path);
std::string makeTmpDirectory();
bool copyFile(const std::string& sourcePath, const std::string& destPath);
std::string getLastPathElement(const std::string& path);
std::string getExecutablePath(bool realPathOnly = false);
std::string getCurrentDirectory();
std::string getDataDirectory();
bool writeTextFile(const std::string& path, const std::string& content);
std::string getMimeTypeForFile(const std::string& filename);
#endif

98
include/xapianSearcher.h Normal file
View File

@@ -0,0 +1,98 @@
/*
* Copyright 2011 Emmanuel Engelhart <kelson@kiwix.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
* MA 02110-1301, USA.
*/
#ifndef KIWIX_XAPIAN_SEARCHER_H
#define KIWIX_XAPIAN_SEARCHER_H
#include <xapian.h>
#include "reader.h"
#include "searcher.h"
#include <map>
#include <string>
using namespace std;
namespace kiwix
{
class XapianSearcher;
class XapianResult : public Result
{
public:
XapianResult(XapianSearcher* searcher, Xapian::MSetIterator& iterator);
virtual ~XapianResult(){};
virtual std::string get_url();
virtual std::string get_title();
virtual int get_score();
virtual std::string get_snippet();
virtual std::string get_content();
virtual int get_wordCount();
virtual int get_size();
virtual int get_readerIndex() { return 0; };
private:
XapianSearcher* searcher;
Xapian::MSetIterator iterator;
Xapian::Document document;
};
class NoXapianIndexInZim : public exception
{
virtual const char* what() const throw()
{
return "There is no fulltext index in the zim file";
}
};
class XapianSearcher
{
friend class XapianResult;
public:
XapianSearcher(const string& xapianDirectoryPath, Reader* reader);
virtual ~XapianSearcher(){};
void searchInIndex(string& search,
const unsigned int resultStart,
const unsigned int resultEnd,
const bool verbose = false);
virtual Result* getNextResult();
void restart_search();
Xapian::MSet results;
protected:
void closeIndex();
void openIndex(const string& xapianDirectoryPath);
void setup_queryParser();
Reader* reader;
Xapian::Database readableDatabase;
std::string language;
std::string stopwords;
Xapian::QueryParser queryParser;
Xapian::Stem stemmer;
Xapian::SimpleStopper stopper;
Xapian::MSetIterator current_result;
std::map<std::string, int> valuesmap;
};
}
#endif

View File

@@ -1,80 +1,100 @@
project('kiwix-lib', 'cpp',
version : '10.0.0', # Also change this in android-kiwix-lib-publisher/kiwixLibAndroid/build.gradle
license : 'GPLv3+',
default_options : ['c_std=c11', 'cpp_std=c++11', 'werror=true'])
version : '1.0.2',
license : 'GPL',
default_options : ['c_std=c11', 'cpp_std=c++11'])
compiler = meson.get_compiler('cpp')
find_library_in_compiler = meson.version().version_compare('>=0.31.0')
wrapper = get_option('wrapper')
static_deps = get_option('android') or get_option('default_library') == 'static'
static_deps = wrapper.contains('android') or wrapper.contains('java') or get_option('default_library') == 'static'
if wrapper.contains('android')
extra_libs = ['-llog']
else
extra_libs = []
endif
if wrapper.contains('java')
add_languages('java')
endif
# See https://github.com/kiwix/kiwix-lib/issues/371
if ['arm', 'mips', 'm68k', 'ppc', 'sh4'].contains(target_machine.cpu_family())
extra_libs += '-latomic'
endif
if (compiler.get_id() == 'gcc' and build_machine.system() == 'linux') or target_machine.system() == 'freebsd'
# C++ std::thread is implemented using pthread on linux by gcc
thread_dep = dependency('threads')
else
thread_dep = dependency('', required:false)
endif
thread_dep = dependency('threads')
libicu_dep = dependency('icu-i18n', static:static_deps)
libzim_dep = dependency('libzim', version : '>=3.0.0', static:static_deps)
pugixml_dep = dependency('pugixml', static:static_deps)
libcurl_dep = dependency('libcurl', static:static_deps)
microhttpd_dep = dependency('libmicrohttpd', static:static_deps)
zlib_dep = dependency('zlib', static:static_deps)
if compiler.has_header('mustache.hpp')
extra_include = []
elif compiler.has_header('mustache.hpp', args: '-I/usr/include/kainjow')
extra_include = ['/usr/include/kainjow']
ctpp2_include_path = ''
has_ctpp2_dep = false
ctpp2_prefix_install = get_option('ctpp2-install-prefix')
ctpp2_link_args = []
if ctpp2_prefix_install == ''
if compiler.has_header('ctpp2/CTPP2Logger.hpp')
if find_library_in_compiler
ctpp2_lib = compiler.find_library('ctpp2')
else
ctpp2_lib = find_library('ctpp2')
endif
ctpp2_link_args = ['-lctpp2']
if meson.is_cross_build() and host_machine.system() == 'windows'
if find_library_in_compiler
iconv_lib = compiler.find_library('iconv', required:false)
else
iconv_lib = find_library('iconv', required:false)
endif
if iconv_lib.found()
ctpp2_link_args += ['-liconv']
endif
endif
has_ctpp2_dep = true
ctpp2_dep = declare_dependency(link_args:ctpp2_link_args)
else
message('ctpp2/CTPP2Logger.hpp not found. Compiling without CTPP2 support')
endif
else
error('Cannot found header mustache.hpp')
if not find_library_in_compiler
error('For custom ctpp2_prefix_install you need a meson version >=0.31.0')
endif
ctpp2_include_path = ctpp2_prefix_install + '/include'
ctpp2_include_args = ['-I'+ctpp2_include_path]
if compiler.has_header('ctpp2/CTPP2Logger.hpp', args:ctpp2_include_args)
ctpp2_include_dir = include_directories(ctpp2_include_path, is_system:true)
ctpp2_lib_path = ctpp2_prefix_install+'/lib'
ctpp2_lib = compiler.find_library('ctpp2', dirs:ctpp2_lib_path)
ctpp2_link_args = ['-L'+ctpp2_lib_path, '-lctpp2']
if meson.is_cross_build() and host_machine.system() == 'windows'
iconv_lib = compiler.find_library('iconv', required:false)
if iconv_lib.found()
ctpp2_link_args += ['-liconv']
endif
endif
has_ctpp2_dep = true
ctpp2_dep = declare_dependency(include_directories:ctpp2_include_dir, link_args:ctpp2_link_args)
else
message('ctpp2/CTPP2Logger.hpp not found. Compiling without CTPP2 support')
endif
endif
libzim_dep = dependency('libzim', version : '>=7.0.0', static:static_deps)
if not compiler.has_header_symbol('zim/zim.h', 'LIBZIM_WITH_XAPIAN')
error('Libzim seems to be compiled without xapian. Xapian support is mandatory.')
xapian_dep = dependency('xapian-core', required:false, static:static_deps)
all_deps = [thread_dep, libicu_dep, libzim_dep, xapian_dep, pugixml_dep]
if has_ctpp2_dep
all_deps += [ctpp2_dep]
endif
extra_cflags = ''
if target_machine.system() == 'windows' and static_deps
add_project_arguments('-DCURL_STATICLIB', language : 'cpp')
extra_cflags += '-DCURL_STATICLIB'
endif
all_deps = [thread_dep, libicu_dep, libzim_dep, pugixml_dep, libcurl_dep, microhttpd_dep, zlib_dep]
inc = include_directories('include', extra_include)
inc = include_directories('include')
conf = configuration_data()
conf.set('VERSION', '"@0@"'.format(meson.project_version()))
if build_machine.system() == 'windows'
extra_link_args = ['-lshlwapi', '-lwinmm']
else
extra_link_args = []
endif
conf.set('ENABLE_CTPP2', has_ctpp2_dep)
subdir('include')
subdir('scripts')
subdir('static')
subdir('src')
subdir('test')
pkg_requires = ['libzim', 'icu-i18n', 'pugixml', 'libcurl', 'libmicrohttpd']
pkg_requires = ['libzim', 'icu-i18n', 'pugixml']
if xapian_dep.found()
pkg_requires += ['xapian-core']
endif
extra_libs = []
extra_cflags = ''
if has_ctpp2_dep
extra_libs += ctpp2_link_args
if ctpp2_include_path != ''
extra_cflags = '-I'+ctpp2_include_path
endif
endif
pkg_conf = configuration_data()
pkg_conf.set('prefix', get_option('prefix'))

View File

@@ -1,2 +1,4 @@
option('wrapper', type:'array', choices:['java', 'android'], value:[],
description: 'The wrapper to generate.')
option('ctpp2-install-prefix', type : 'string', value : '',
description : 'Prefix where ctpp libs has been installed')
option('android', type : 'boolean', value : false,
description : 'Do we make a kiwix-lib for android')

View File

@@ -1,10 +0,0 @@
# kiwixprototype
Revamping the landing page
## I made a simple mockup using pages
![ROUGH SKETCH landingpage](https://user-images.githubusercontent.com/41134301/105805694-969e8080-5fc8-11eb-8ce4-dc85bcfa7a55.png)
![ROUGH SKETCH footer section](https://user-images.githubusercontent.com/41134301/105805730-ab7b1400-5fc8-11eb-9d47-b3fd7abc7cd4.png)
## and here's the final version
![kiwix1](https://user-images.githubusercontent.com/41134301/105805990-23e1d500-5fc9-11eb-81be-df0ff3210071.png)
![kiwix2](https://user-images.githubusercontent.com/41134301/105806018-2fcd9700-5fc9-11eb-911f-0552fb4f0b62.png)

View File

@@ -1,132 +0,0 @@
.uls-trigger {
background: url(../images/language.svg ) no-repeat left center;
padding-left: 24px;
}
.uls-menu {
position: absolute;
z-index: 1000;
display: none;
margin-top: 1px;
background-color: #fff;
border: 1px solid #ccc;
border-color: rgba(0, 0, 0, 0.2);
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
}
.uls-wide {
min-width: 715px;
width: 45%;
}
.uls-medium {
min-width: 360px;
width: 30%;
}
/* Override the grid */
.uls-medium.grid .row {
min-width: 300px;
}
.uls-narrow {
min-width: 180px;
width: 20%;
}
/* Override the grid */
.uls-narrow.grid .row {
min-width: 150px;
}
.uls-search {
background-color: #fff;
padding: 5px 16px;
border-bottom: 1px solid #ddd;
}
.grid .uls-search {
padding-left: 0;
}
/* Make space for magnifying class on the front */
.uls-search-wrapper {
position: relative;
padding-left: 44px;
margin-right: 5px;
height: 32px;
}
.uls-search-label {
background: url(../images/search.svg ) no-repeat center center;
background-size: 20px;
height: 32px;
width: 44px;
display: block;
position: absolute;
left: 0;
opacity: 0.5;
}
.uls-search-input-wrapper {
position: relative;
}
/* There are two input boxes. This class applies to both of them */
.uls-filterinput {
font-size: 16px;
height: 32px;
width: 100%;
/* For the custom clear (X) icon */
padding: 6px 25px 6px 0;
outline: 0;
border: 0;
display: block;
position: absolute;
top: 0;
left: 0;
}
/* This is the actual input */
.uls-languagefilter {
background-color: transparent;
border: 0;
color: #222;
}
/* This is the shadow input box showing completion suggestions */
.uls-filtersuggestion {
background-color: #fff;
color: #777;
}
.uls-languagefilter-clear {
background: url(../images/close.svg ) no-repeat left center;
background-size: 15px;
cursor: pointer;
height: 15px;
width: 15px;
opacity: 0.7;
/* Vertical margins: (32 - 15) / 2 */
margin: 8.5px 5px;
position: absolute;
right: 0;
/* Make it appear above the input boxes */
z-index: 1;
}
div.navbar {
padding: 20px;
}
span.uls-trigger {
float: right;
cursor: pointer;
font-weight: bold;
}

View File

@@ -1,307 +0,0 @@
/* Generated using Foundation http://foundation.zurb.com/docs/grid.php */
/* Global Reset & Standards ---------------------- */
.grid * {
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
}
/* Misc ---------------------- */
.grid .left {
float: left;
}
.grid .right {
float: right;
}
.grid .text-left {
text-align: left;
}
.grid .text-right {
text-align: right;
}
.grid .text-center {
text-align: center;
}
.grid .hide {
display: none;
}
.grid .highlight {
background: #ff9;
}
/* The Grid ---------------------- */
.grid .row {
width: 100%;
max-width: none;
min-width: 600px;
margin: 0 auto;
}
.grid .row .row {
width: auto;
max-width: none;
min-width: 0;
margin: 0 -5px;
}
.grid .column,
.grid .columns {
float: left;
min-height: 1px;
padding: 0 5px;
position: relative;
}
.grid .row.collapse .column,
.grid .row.collapse .columns {
padding: 0;
}
.grid .row .row.collapse {
margin: 0;
}
.grid .column.centered,
.grid .columns.centered {
float: none;
margin: 0 auto;
}
.grid .row .one {
width: 8.333%;
}
.grid .row .two {
width: 16.667%;
}
.grid .row .three {
width: 25%;
}
.grid .row .four {
width: 33.333%;
}
.grid .row .five {
width: 41.667%;
}
.grid .row .six {
width: 50%;
}
.grid .row .seven {
width: 58.333%;
}
.grid .row .eight {
width: 66.667%;
}
.grid .row .nine {
width: 75%;
}
.grid .row .ten {
width: 83.333%;
}
.grid .row .eleven {
width: 91.667%;
}
.grid .row .twelve {
width: 100%;
}
.grid .row .offset-by-one {
margin-left: 8.333%;
}
.grid .row .offset-by-two {
margin-left: 16.667%;
}
.grid .row .offset-by-three {
margin-left: 25%;
}
.grid .row .offset-by-four {
margin-left: 33.333%;
}
.grid .row .offset-by-five {
margin-left: 41.667%;
}
.grid .row .offset-by-six {
margin-left: 50%;
}
.grid .row .offset-by-seven {
margin-left: 58.333%;
}
.grid .row .offset-by-eight {
margin-left: 66.667%;
}
.grid .row .offset-by-nine {
margin-left: 75%;
}
.grid .row .offset-by-ten {
margin-left: 83.333%;
}
.grid .push-two {
left: 16.667%;
}
.grid .pull-two {
right: 16.667%;
}
.grid .push-three {
left: 25%;
}
.grid .pull-three {
right: 25%;
}
.grid .push-four {
left: 33.333%;
}
.grid .pull-four {
right: 33.333%;
}
.grid .push-five {
left: 41.667%;
}
.grid .pull-five {
right: 41.667%;
}
.grid .push-six {
left: 50%;
}
.grid .pull-six {
right: 50%;
}
.grid .push-seven {
left: 58.333%;
}
.grid .pull-seven {
right: 58.333%;
}
.grid .push-eight {
left: 66.667%;
}
.grid .pull-eight {
right: 66.667%;
}
.grid .push-nine {
left: 75%;
}
.grid .pull-nine {
right: 75%;
}
.grid .push-ten {
left: 83.333%;
}
.grid .pull-ten {
right: 83.333%;
}
.grid .row:before,
.grid .row:after {
content: '';
display: table;
}
.grid .row:after {
clear: both;
}
/* Block Grids ---------------------- */
/* These are 2-up, 3-up, 4-up and 5-up ULs, suited
for repeating blocks of content. Add 'mobile' to
them to switch them just like the layout grid
(one item per line) on phones
For IE7/8 compatibility block-grid items need to be
the same height. You can optionally uncomment the
lines below to support arbitrary height, but know
that IE7/8 do not support :nth-child.
-------------------------------------------------- */
.grid .block-grid {
display: block;
overflow: hidden;
padding: 0;
}
.grid .block-grid > li {
display: block;
height: auto;
float: left;
}
.grid .block-grid.two-up {
margin: 0 -15px;
}
.grid .block-grid.two-up > li {
width: 50%;
padding: 0 15px 15px;
}
/* .block-grid.two-up>li:nth-child(2n+1) {clear: left;} */
.grid .block-grid.three-up {
margin: 0 -12px;
}
.grid .block-grid.three-up > li {
width: 33.33%;
padding: 0 12px 12px;
}
/* .block-grid.three-up>li:nth-child(3n+1) {clear: left;} */
.grid .block-grid.four-up {
margin: 0 -10px;
}
.grid .block-grid.four-up > li {
width: 25%;
padding: 0 10px 10px;
}
/* .block-grid.four-up>li:nth-child(4n+1) {clear: left;} */
.grid .block-grid.five-up {
margin: 0 -8px;
}
.grid .block-grid.five-up > li {
width: 20%;
padding: 0 8px 8px;
}

View File

@@ -1,140 +0,0 @@
/*
* Language Category Display (LCD) consists of multiple sections:
* - one to display when there are no search results (which might display suggested languages)
* - one for each region of the world, plus regions for world languages and suggested languages
* The regions consist of one or more rows (blocks) which consist of one-to-four columns. Each
* column is an ul element, and contains up to 8 li elements, each containing a link.
*/
.uls-lcd {
background-color: #fcfcfc;
height: 20em;
/* Work around Chrome bug where it places scrollbar on the left in
* in RTL mode but actually reserves the place on the right side */
overflow-x: hidden;
overflow-y: auto;
width: auto;
padding: 0 16px;
}
.uls-lcd-region-title {
color: #555;
font-size: 14px;
padding-left: 28px;
}
.uls-lcd--no-quicklist [ data-region='all' ] .uls-lcd-region-title {
display: none;
}
.uls-lcd-region-section {
margin-top: 10px;
}
/*
* We need to have this as a grid row to push rest of the content below it, but resetting
* padding and margin so that calculating them for children is easier.
*/
.grid .uls-language-block.row {
padding: 0;
margin: 0;
}
.uls-language-block > ul {
/*
* We don't want any visible bullets in this list. Not by default anyway.
* Using very unspecific selector here to allow other classes to override.
* Bug because overflow: hidden is incompatible with bullets, also render
* the bullets inside the list in case there should be any.
*/
list-style: none none;
}
/*
* Each block should have 16px padding on both sides. But because we already gave
* 16px for the whole menu, we need to remove it for first and last items the blocks.
*/
.grid .uls-language-block > ul {
margin: 0 0 20px 0;
padding: 0 16px;
}
.grid .uls-language-block > ul:first-child {
padding-left: 0;
}
.grid .uls-language-block > ul:last-child {
padding-right: 0;
}
.uls-language-block > ul > li {
cursor: pointer;
margin-left: 20px;
padding: 8px;
/*
* The directionality (ltr/rtl) for each list item is set dynamically
* as HTML attributes in JavaScript. Setting directionality also applies
* alignment, but a list with mixed alignment is hard to read.
* All items are therefore explicitly aligned to the left, including names
* of right-to-left languages in left-to-right environment and vice versa.
* As long as the directionality of the item is set correctly, the text
* is readable.
*/
text-align: left;
}
.uls-language-block > ul > li:hover {
background-color: #eaeff7;
}
.uls-language-block a {
cursor: pointer;
text-decoration: none;
color: #36c;
font-size: 14px;
display: inline-block;
width: 100%;
overflow-x: hidden;
/*
* Some languages have long names for various reasons and we still want
* them to appear on one line.
* To make it work correctly, the directionality must be set correctly
* on the item level.
*/
text-overflow: ellipsis;
white-space: nowrap;
vertical-align: middle;
}
.uls-no-results-view {
display: none;
}
.uls-lcd.uls-no-results > .uls-lcd-region-section {
display: none;
}
.uls-lcd.uls-no-results > .uls-no-results-view {
display: block;
}
.uls-no-results-found-title {
font-size: 16px;
padding: 0 16px 0 28px;
margin: 20px 0;
border-bottom: 0;
color: #54595d;
}
.uls-no-found-more {
border-top: 1px solid #eaecf0;
color: #54595d;
padding: 12px 16px 12px 44px;
font-size: 0.9em;
width: 100%;
margin-top: 1.6em;
line-height: 1.6em;
position: absolute;
bottom: 0;
left: 0;
}

View File

@@ -1,307 +0,0 @@
/* stylelint-disable declaration-no-important */
@media only screen and ( max-width: 767px ) {
.uls-mobile.uls-menu {
width: 95%;
left: 2.5%;
}
.uls-mobile .uls-language-list {
-webkit-overflow-scrolling: touch;
}
.uls-mobile .uls-language-block {
padding-left: 15px !important;
}
.uls-mobile .uls-language-block ul {
min-height: 14em;
}
.uls-mobile .uls-language-block a {
font-size: 16px;
line-height: 1.7em;
}
.uls-mobile .row {
width: auto;
min-width: 0;
margin-left: 0;
margin-right: 0;
}
.uls-mobile .column,
.uls-mobile .columns {
width: auto !important;
float: none;
}
.uls-mobile .column:last-child,
.uls-mobile .columns:last-child {
float: none;
}
.uls-mobile [ class*='column' ] + [ class*='column' ]:last-child {
float: none;
}
.uls-mobile .column:before,
.uls-mobile .uls-mobile .columns:before,
.uls-mobile .column:after,
.columns:after {
content: '';
display: table;
}
.uls-mobile .column:after,
.uls-mobile .columns:after {
clear: both;
}
.uls-mobile .offset-by-one,
.uls-mobile .offset-by-two,
.uls-mobile .offset-by-three,
.uls-mobile .offset-by-four,
.uls-mobile .offset-by-five,
.uls-mobile .offset-by-six,
.uls-mobile .offset-by-seven,
.uls-mobile .offset-by-eight,
.uls-mobile .offset-by-nine,
.uls-mobile .offset-by-ten {
margin-left: 0 !important;
}
.uls-mobile .push-two,
.uls-mobile .push-three,
.uls-mobile .push-four,
.uls-mobile .push-five,
.uls-mobile .push-six,
.uls-mobile .push-seven,
.uls-mobile .push-eight,
.uls-mobile .push-nine,
.uls-mobile .push-ten {
left: auto;
}
.uls-mobile .pull-two,
.uls-mobile .pull-three,
.uls-mobile .pull-four,
.uls-mobile .pull-five,
.uls-mobile .pull-six,
.uls-mobile .pull-seven,
.uls-mobile .pull-eight,
.uls-mobile .pull-nine,
.uls-mobile .pull-ten {
right: auto;
}
/* Mobile 4-column Grid */
.uls-mobile .row .mobile-one {
width: 25% !important;
float: left;
padding: 0 4px;
}
.uls-mobile .row .mobile-one:last-child {
float: right;
}
.uls-mobile .row.collapse .mobile-one {
padding: 0;
}
.uls-mobile .row .mobile-two {
width: 50% !important;
float: left;
padding: 0 4px;
}
.uls-mobile .row .mobile-two:last-child {
float: right;
}
.uls-mobile .row.collapse .mobile-two {
padding: 0;
}
.uls-mobile .row .mobile-three {
width: 75% !important;
float: left;
padding: 0 4px;
}
.uls-mobile .row .mobile-three:last-child {
float: right;
}
.uls-mobile .row.collapse .mobile-three {
padding: 0;
}
.uls-mobile .row .mobile-four {
width: 100% !important;
float: left;
padding: 0 4px;
}
.uls-mobile .row .mobile-four:last-child {
float: right;
}
.uls-mobile .row.collapse .mobile-four {
padding: 0;
}
.uls-mobile .push-one-mobile {
left: 25%;
}
.uls-mobile .pull-one-mobile {
right: 25%;
}
.uls-mobile .push-two-mobile {
left: 50%;
}
.uls-mobile .pull-two-mobile {
right: 50%;
}
.uls-mobile .push-three-mobile {
left: 75%;
}
.uls-mobile .pull-three-mobile {
right: 75%;
}
}
/* Visibility Classes ---------------------- */
/* Standard (large) display targeting */
.uls-mobile .show-for-small,
.uls-mobile .show-for-medium,
.uls-mobile .show-for-medium-down,
.uls-mobile .hide-for-large,
.uls-mobile .hide-for-large-up,
.uls-mobile .show-for-xlarge {
display: none !important;
}
.uls-mobile .hide-for-xlarge,
.uls-mobile .show-for-large,
.uls-mobile .show-for-large-up,
.uls-mobile .hide-for-small,
.uls-mobile .hide-for-medium,
.uls-mobile .hide-for-medium-down {
display: block !important;
}
/* Very large display targeting */
@media only screen and ( min-width: 1441px ) {
.uls-mobile .hide-for-small,
.uls-mobile .hide-for-medium,
.uls-mobile .hide-for-medium-down,
.hide-for-large,
.show-for-large-up,
.show-for-xlarge {
display: block !important;
}
.show-for-small,
.uls-mobile .show-for-medium,
.uls-mobile .show-for-medium-down,
.uls-mobile .show-for-large,
.uls-mobile .hide-for-large-up,
.uls-mobile .hide-for-xlarge {
display: none !important;
}
}
/* Medium display targeting */
@media only screen and ( max-width: 1279px ) and ( min-width: 768px ) {
.uls-mobile .hide-for-small,
.uls-mobile .show-for-medium,
.uls-mobile .show-for-medium-down,
.uls-mobile .hide-for-large,
.uls-mobile .hide-for-large-up,
.uls-mobile .hide-for-xlarge {
display: block !important;
}
.uls-mobile .show-for-small,
.uls-mobile .hide-for-medium,
.uls-mobile .hide-for-medium-down,
.uls-mobile .show-for-large,
.uls-mobile .show-for-large-up,
.uls-mobile .show-for-xlarge {
display: none !important;
}
}
/* Small display targeting */
@media only screen and ( max-width: 767px ) {
.uls-mobile .show-for-small,
.uls-mobile .hide-for-medium,
.uls-mobile .show-for-medium-down,
.uls-mobile .hide-for-large,
.uls-mobile .hide-for-large-up,
.uls-mobile .hide-for-xlarge {
display: block !important;
}
.uls-mobile .hide-for-small,
.uls-mobile .show-for-medium,
.uls-mobile .hide-for-medium-down,
.uls-mobile .show-for-large,
.uls-mobile .show-for-large-up,
.uls-mobile .show-for-xlarge {
display: none !important;
}
}
/* Orientation targeting */
.uls-mobile .show-for-landscape,
.uls-mobile .hide-for-portrait {
display: block !important;
}
.uls-mobile .hide-for-landscape,
.uls-mobile .show-for-portrait {
display: none !important;
}
@media screen and ( orientation: landscape ) {
.uls-mobile .show-for-landscape,
.uls-mobile .hide-for-portrait {
display: block !important;
}
.uls-mobile .hide-for-landscape,
.uls-mobile .show-for-portrait {
display: none !important;
}
}
@media screen and ( orientation: portrait ) {
.uls-mobile .show-for-portrait,
.uls-mobile .hide-for-landscape {
display: block !important;
}
.uls-mobile .hide-for-portrait,
.uls-mobile .show-for-landscape {
display: none !important;
}
}
/* Touch-enabled device targeting */
.uls-mobile .show-for-touch,
.uls-mobile .touch .hide-for-touch {
display: none !important;
}
/* stylelint-disable-next-line no-descending-specificity */
.uls-mobile .hide-for-touch,
.uls-mobile .touch .show-for-touch {
display: block !important;
}

View File

@@ -1,505 +0,0 @@
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
#main {
width: 100%;
height: 100%;
background: linear-gradient(180deg, #ff9933 0%, rgba(64, 38, 13, 1) 73%);
background-size: cover;
}
nav {
width: 100%;
height: 80px;
line-height: 80px;
}
nav ul {
float: left;
margin-right: 30px;
}
/* changes at kiwix logo */
nav .kiwix-logo {
float: left;
height: 60px;
width: 150px;
margin: 10px;
}
nav ul li {
list-style-type: none;
display: inline-block;
transition: 0.8s all;
}
nav ul li:hover {
background-color: #f39d1a;
}
nav ul li a {
text-decoration: none;
color: #fff;
padding: 30px;
}
/* code for search box */
#content {
position: absolute;
top: 50px;
right: 50px;
transform: translate(0%, -50%);
}
#content.on {
-webkit-animation-name: in-out;
animation-name: in-out;
-webkit-animation-duration: 0.7s;
animation-duration: 0.7s;
-webkit-animation-timing-function: linear;
animation-timing-function: linear;
-webkit-animation-iteration-count: 1;
animation-iteration-count: 1;
}
input {
box-sizing: border-box;
width: 30px;
height: 30px;
border: 2px solid #ffffff;
border-radius: 50%;
background: none;
color: #fff;
font-size: 16px;
font-weight: 400;
font-family: Roboto;
outline: 0;
-webkit-transition: width 0.4s ease-in-out, border-radius 0.8s ease-in-out,
padding 0.2s;
transition: width 0.4s ease-in-out, border-radius 0.8s ease-in-out,
padding 0.2s;
-webkit-transition-delay: 0.4s;
transition-delay: 0.4s;
-webkit-transform: translate(-100%, -50%);
-ms-transform: translate(-100%, -50%);
transform: translate(-100%, -50%);
}
.search {
background: none;
position: absolute;
top: 24px;
left: 0;
height: 50px;
width: 50px;
padding: 0;
border-radius: 100%;
outline: 0;
border: 0;
color: inherit;
cursor: pointer;
-webkit-transition: 0.2s ease-in-out;
transition: 0.2s ease-in-out;
-webkit-transform: translate(-100%, -50%);
-ms-transform: translate(-100%, -50%);
transform: translate(-100%, -50%);
}
.search:before {
content: "";
position: absolute;
width: 20px;
height: 4px;
background-color: #fff;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
margin-top: 17px;
margin-left: 17px;
-webkit-transition: 0.2s ease-in-out;
transition: 0.2s ease-in-out;
}
.close {
-webkit-transition: 0.4s ease-in-out;
transition: 0.4s ease-in-out;
-webkit-transition-delay: 0.4s;
transition-delay: 0.4s;
}
.close:before {
content: "";
position: absolute;
width: 20px;
height: 3px;
margin-top: -1px;
margin-left: -2px;
background-color: #fff;
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
transform: rotate(45deg);
-webkit-transition: 0.2s ease-in-out;
transition: 0.2s ease-in-out;
}
.close:after {
content: "";
position: absolute;
width: 20px;
height: 3px;
background-color: #fff;
margin-top: -1px;
margin-left: -2px;
cursor: pointer;
-webkit-transform: rotate(-45deg);
-ms-transform: rotate(-45deg);
transform: rotate(-45deg);
}
.square {
box-sizing: border-box;
padding: 0 40px 0 10px;
width: 300px;
height: 30px;
border: 2px solid #ffffff;
border-radius: 100vh;
background: none;
color: #fff;
font-family: Roboto;
font-size: 16px;
font-weight: 400;
outline: 0;
-webkit-transition: width 0.4s ease-in-out, border-radius 0.4s ease-in-out,
padding 0.2s;
transition: width 0.4s ease-in-out, border-radius 0.4s ease-in-out,
padding 0.2s;
-webkit-transition-delay: 0.4s, 0s, 0.4s;
transition-delay: 0.4s, 0s, 0.4s;
-webkit-transform: translate(-100%, -50%);
-ms-transform: translate(-100%, -50%);
transform: translate(-100%, -50%);
}
/* language selector */
.ui-dropdown-list {
position: relative;
}
p.ui-dropdown-list-trigger {
margin-top: 0;
}
.ui-dropdown-list-trigger strong {
position: relative;
z-index: 999;
}
.ui-dropdown-list-trigger strong:after {
display: block;
position: absolute;
content: '';
right: 5px;
top: 35px;
width: 0;
height: 0;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
border-top: 5px solid #ffffff;
}
.ui-dropdown-list-trigger strong,
.ui-dropdown-list ul a {
display: block;
width: 80px;
cursor: pointer;
padding: 30px 8px;
font-size: 13px;
line-height: 13px;
color: #ffffff;
font-weight: normal;
}
#lang-switcher strong {
float: right;
}
/* information contents */
.boxes {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-around;
padding: 60px;
}
.box {
display: flex;
flex-direction: column;
text-align: center;
width: 350px;
height: auto;
background: url('./images/bg-pattern-card.svg') no-repeat top white;
border-radius: 20px;
margin: auto;
margin-top: 10%;
box-shadow: 10px 10px 100px rgba(0, 0, 0, 0.363);
}
.photo {
background-color: transparent;
}
.photo img {
margin-top: -7%;
border-radius: 50%;
}
.gras {
font-weight: 700;
}
.grey {
color: hsl(0, 0%, 59%);
font-weight: 400;
}
.content_info {
justify-content: center;
padding-top: 10px;
padding-bottom: 10px;
border-bottom: 1px solid hsl(0, 0%, 70%);
}
.content_info .gras {
padding-right: 5px;
}
.content_stats {
display: flex;
flex-direction: row;
justify-content: space-evenly;
align-content: center;
padding-top: 30px;
padding-bottom: 30px;
padding-left: 0px;
padding-right: 15px;
padding: 10px 0 10px 0;
}
p {
padding-bottom: 5px;
text-align: center;
margin: 0;
}
@media screen and (max-width: 375px) {
html {
width: 375px;
}
.boxes {
padding: 0;
}
.box {
margin-top: 40%;
}
}
.pagination ul {
width: 100%;
display: flex;
align-items: center;
justify-content: center;
flex-wrap: wrap;
padding: 8px;
border-radius: 50px;
box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
}
.pagination ul li {
color: chocolate;
list-style: none;
line-height: 45px;
text-align: center;
font-size: 18px;
font-weight: 500;
cursor: pointer;
user-select: none;
transition: all 0.3s ease;
}
.pagination ul li.numb {
list-style: none;
height: 45px;
width: 45px;
margin: 0 3px;
line-height: 45px;
border-radius: 50%;
}
.pagination ul li.numb.first {
margin: 0px 3px 0 -5px;
}
.pagination ul li.numb.last {
margin: 0px -5px 0 3px;
}
.pagination ul li.dots {
font-size: 22px;
cursor: default;
}
.pagination ul li.btn {
padding: 0 20px;
border-radius: 50px;
}
.pagination li.active,
.pagination ul li.numb:hover,
.pagination ul li:first-child:hover,
.pagination ul li:last-child:hover {
color: #fff;
background: #ff9933;
}
ul {
list-style-type: none;
}
a {
text-decoration: none;
color: white;
transition: color 0.5s ease;
}
a:hover {
color: wheat;
}
.spacing {
height: 400px;
}
.design {
width: 100%;
height: 100px;
display: flex;
justify-content: space-between;
align-items: center;
background: white;
color: #fff;
padding: 0 4rem;
}
.footer {
width: 100%;
height: auto;
/* this is how change the color */
background: linear-gradient(180deg, #40260d 73%, #000);
}
.container {
max-width: 85%;
margin: 0 auto;
padding: 2rem 0;
}
.footer-group__container {
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}
.footer-group {
align-self: stretch;
padding: 0.4rem 1rem;
flex: 1 0 280px;
}
.footer-group__header {
color: #ff9933;
text-transform: uppercase;
font-size: 1.2rem;
letter-spacing: -1px;
word-spacing: 0.2rem;
font-weight: 500;
margin-bottom: 1.2rem;
}
.footer-group__item {
font-size: 0.85rem;
font-weight: 400;
margin-bottom: 0.6rem;
text-transform: capitalize;
}
.footer-group__lead {
/* font-weight:600; */
width: 100%;
}
.visually-hidden {
display: none;
/* TODO proper implementation */
}
.footer-footnote,
.footnote__items {
display: flex;
font-size: 0.8rem;
}
.footnote__copyright,
.footnote__items {
margin: 1rem 0;
}
.footer-footnote {
flex-wrap: wrap;
font-weight: 600;
padding: 0.25rem 1rem;
color: white;
background: #915e35;
}
.footnote__copyright {
flex: 2 0 50%;
}
@media (max-width: 998px) {
.footnote__copyright {
flex: 1 0 50%;
}
}
.footnote__items {
flex: 1 0 50%;
justify-content: flex-end;
}
.footnote__item {
margin: 0 1rem;
}
@media (max-width: 580px) {
.footer-footnote {
flex-direction: column-reverse;
}
}

View File

@@ -1,20 +0,0 @@
{
"@metadata": {
"authors": [
"Csisc"
]
},
"uls-region-WW": "Ģālemīye",
"uls-region-SP": "Spēsyāl",
"uls-region-AM": "Emerīke",
"uls-region-AF": "Ifrīqye",
"uls-region-EU": "Ūrūppe",
"uls-region-AS": "Ēsye",
"uls-region-ME": "Ic-carq il-awsaţ",
"uls-region-PA": "Il-Mūḩīţ il-hēdī",
"uls-no-results-found": "Mē fammēc ḩattā rēzülta",
"uls-common-languages": "Lūğāt muntacra",
"uls-no-results-suggestion-title": "Tnejjim tkūn muhtam b-:",
"uls-search-help": "Tnejjim tlawwij ḩasb ism il-lūğa, ism il-kod, il-kod ISO mtēģ il-lūğa w illē ḩasb ij-jīhe",
"uls-search-placeholder": "Lawwij ģlā il-lūğa"
}

View File

@@ -1,26 +0,0 @@
{
"@metadata": {
"authors": [
"Amire80",
"Biggs ZA",
"Fwolff",
"Joris Darlington Quarshie",
"Naudefj",
"Puvircho"
]
},
"uls-region-WW": "Wêreldwyd",
"uls-region-SP": "Spesiaal",
"uls-region-AM": "Amerika",
"uls-region-AF": "Afrika",
"uls-region-EU": "Europa",
"uls-region-AS": "Asië",
"uls-region-ME": "Midde-Ooste",
"uls-region-PA": "Stille Oseaan",
"uls-region-all": "Alle tale",
"uls-no-results-found": "Geen resultate gevind nie",
"uls-common-languages": "Voorgestelde tale",
"uls-no-results-suggestion-title": "U mag geïnteresseerd wees in:",
"uls-search-help": "Soek gerus volgens taalnaam, skrifnaam of ISO-kode, of blaai volgens streek.",
"uls-search-placeholder": "Soek na n taal"
}

View File

@@ -1,22 +0,0 @@
{
"@metadata": {
"authors": [
"Andemta",
"Elfalem"
]
},
"uls-region-WW": "ዓለም አቀፍ",
"uls-region-SP": "ልዩ",
"uls-region-AM": "አሜሪካ",
"uls-region-AF": "አፍሪካ",
"uls-region-EU": "አውሮጳ",
"uls-region-AS": "እስያ",
"uls-region-ME": "መካከለኛው ምሥራቅ",
"uls-region-PA": "ፓሲፊክ",
"uls-region-all": "ሁሉ ቋንቋ",
"uls-no-results-found": "ውጤት አልተገኘም",
"uls-common-languages": "ተመራጭ ቋንቋዎች",
"uls-no-results-suggestion-title": "ይህ ሊመስጦት ይችላል:",
"uls-search-help": "በቋንቋ ስም፣ የአፃፃፍ ሥርዓት ስም፣ አይ.ኤስ.ኦ. (ISO) ኮድ መፈለግ ወይም በአካባቢ መቃኘት ይቻላል::",
"uls-search-placeholder": "ቋንቋ ለመፈለግ"
}

View File

@@ -1,21 +0,0 @@
{
"@metadata": {
"authors": [
"Angpradesh"
]
},
"uls-region-WW": "वैश्विक",
"uls-region-SP": "खास",
"uls-region-AM": "अमरीका",
"uls-region-AF": "अफ़्रीका",
"uls-region-EU": "यूरोप",
"uls-region-AS": "एशिया",
"uls-region-ME": "मध्य पूर्व",
"uls-region-PA": "प्रशांत",
"uls-region-all": "सब्भे भाषा",
"uls-no-results-found": "कोय परिणाम नै मिललै",
"uls-common-languages": "आम भाषा सिनी",
"uls-no-results-suggestion-title": "आपन॑ लेली संभवतः उपयोगी:",
"uls-search-help": "आपन॑ भाषा केरऽ नाम , स्क्रिप्ट केरऽ नाम , भाषा केरऽ आईएसओ कोड सं॑ खोज॑ सकै छहो या आपन॑ क्षेत्र के नाम सं॑ ब्राउज़ कर॑ सकै छहऽ.",
"uls-search-placeholder": "भाषा लेली खोजऽ"
}

View File

@@ -1,26 +0,0 @@
{
"@metadata": {
"authors": [
"Amire80",
"DRIHEM",
"Hhaboh162002",
"Meno25",
"ترجمان05",
"ديفيد"
]
},
"uls-region-WW": "في جميع أنحاء العالم",
"uls-region-SP": "الخاصة",
"uls-region-AM": "أمريكا",
"uls-region-AF": "أفريقيا",
"uls-region-EU": "أوروبا",
"uls-region-AS": "آسيا",
"uls-region-ME": "الشرق الأوسط",
"uls-region-PA": "المحيط الهادئ",
"uls-region-all": "جميع اللغات",
"uls-no-results-found": "لم يتم العثور على نتائج",
"uls-common-languages": "اللغات المقترحة",
"uls-no-results-suggestion-title": "قد تكون مهتما بما يلي:",
"uls-search-help": "يمكنك البحث مستخدما اسم اللغة، أو اسم السكريبت، أو رمز اللغة القياسي أو يمكنك التصفح حسب المنطقة.",
"uls-search-placeholder": "بحث عن لغة"
}

View File

@@ -1,22 +0,0 @@
{
"@metadata": {
"authors": [
"Meno25",
"UpDownUp"
]
},
"uls-region-WW": "لغات عالمية",
"uls-region-SP": "لغات خاصّة",
"uls-region-AM": "أمريكا",
"uls-region-AF": "إفريقيا",
"uls-region-EU": "أوروپّا",
"uls-region-AS": "آسيا",
"uls-region-ME": "الشرق الأوسط",
"uls-region-PA": "المحيط الهادي",
"uls-region-all": "كل اللغات",
"uls-no-results-found": "مفيش أي نتايج",
"uls-common-languages": "اللغات المقترحة",
"uls-no-results-suggestion-title": "يمكن تكون مهتم بـ:",
"uls-search-help": "ممكن تدور حسب اسم اللغه، اسم نظام الكتابه\\الخط، كود الـ ISO بتاع اللغه أو ممكن تتصفح حسب المنطقه.",
"uls-search-placeholder": "دوّر على لغة"
}

View File

@@ -1,23 +0,0 @@
{
"@metadata": {
"authors": [
"Dibya Dutta",
"Mohsin Ali",
"Nilamdyuti"
]
},
"uls-region-WW": "বিশ্বব্যাপী",
"uls-region-SP": "বিশেষ",
"uls-region-AM": "আমেৰিকা",
"uls-region-AF": "আফ্ৰিকা",
"uls-region-EU": "ইউৰোপ",
"uls-region-AS": "এছিয়া",
"uls-region-ME": "মধ্যপ্রাচ্য",
"uls-region-PA": "পেচিফিক",
"uls-region-all": "সকলো ভাষা",
"uls-no-results-found": "কোনো ফলাফল পোৱা নগ'ল",
"uls-common-languages": "পৰামৰ্শমূলক ভাষাসমূহ",
"uls-no-results-suggestion-title": "আপুনি আগ্ৰহী হ'ব পাৰে:",
"uls-search-help": "আপুনি ভাষাৰ নাম, লিপিৰ নাম, ভাষাৰ ISO ক'ড সাপেক্ষে সন্ধান কৰিব পাৰে অথবা অঞ্চল সাপেক্ষে ব্ৰাউজ কৰিব পাৰে।",
"uls-search-placeholder": "ভাষা এটাৰ সন্ধান কৰক"
}

View File

@@ -1,21 +0,0 @@
{
"@metadata": {
"authors": [
"Xuacu"
]
},
"uls-region-WW": "Mundial",
"uls-region-SP": "Especiales",
"uls-region-AM": "América",
"uls-region-AF": "África",
"uls-region-EU": "Europa",
"uls-region-AS": "Asia",
"uls-region-ME": "Oriente mediu",
"uls-region-PA": "Pacíficu",
"uls-region-all": "Toles llingües",
"uls-no-results-found": "Nun s'alcontraron resultaos",
"uls-common-languages": "Llingües suxeríes",
"uls-no-results-suggestion-title": "Seique t'interese:",
"uls-search-help": "Pues buscar pol nome de la llingua, nome del alfabetu, códigu ISO de la llingua o ver un área xeográfica.",
"uls-search-placeholder": "Buscar una llingua"
}

View File

@@ -1,20 +0,0 @@
{
"@metadata": {
"authors": [
"Gazimagomedov"
]
},
"uls-region-WW": "ГӀаламиял",
"uls-region-SP": "Хассал",
"uls-region-AM": "Америка",
"uls-region-AF": "Африка",
"uls-region-EU": "Европа",
"uls-region-AS": "Азия",
"uls-region-ME": "АскӀосаб Магъриб",
"uls-region-PA": "Океания",
"uls-no-results-found": "Щибниги жо батинчӀо",
"uls-common-languages": "Жалго жедедаго рищарал мацӀал",
"uls-no-results-suggestion-title": "Дур интерес гьал мацӀазда ккезе батила:",
"uls-search-help": "МацӀалъул яги хъвай-хъваялъул цӀаразда рекъон цӀехезе бегьула, яги мацӀалъул ISO-кодалда рекъон. Гьединго бегьула регион бищун балагьизе:",
"uls-search-placeholder": "МацӀ цӀехей"
}

View File

@@ -1,23 +0,0 @@
{
"@metadata": {
"authors": [
"1AnuraagPandey",
"1PandeyAnurag",
"Ajeetsinghawadh"
]
},
"uls-region-WW": "वैश्विक",
"uls-region-SP": "विशेष",
"uls-region-AM": "अमेरिका",
"uls-region-AF": "अफ्रिका",
"uls-region-EU": "यूरोप",
"uls-region-AS": "एशिया",
"uls-region-ME": "मध्य पुरुब",
"uls-region-PA": "प्रशांत",
"uls-region-all": "कुल भाषा",
"uls-no-results-found": "कवनो नतिजा नाई मिला",
"uls-common-languages": "सुझाई गय भाषा",
"uls-no-results-suggestion-title": "आप कय लिये संभवतः उपयोगी:",
"uls-search-help": "आप भाषा कय नाँव,लिपि नाँव,भाषा कय आई.एस.ओ कोड अव क्षेत्र कय नाँव से खोज सका जात अहै ।",
"uls-search-placeholder": "भाषा खोज"
}

View File

@@ -1,24 +0,0 @@
{
"@metadata": {
"authors": [
"AZISS",
"Khan27",
"Wertuose",
"Şeyx Şamil"
]
},
"uls-region-WW": "Dünya üzrə",
"uls-region-SP": "Xüsusi",
"uls-region-AM": "Amerika",
"uls-region-AF": "Afrika",
"uls-region-EU": "Avropa",
"uls-region-AS": "Asiya",
"uls-region-ME": "Yaxın Şərq",
"uls-region-PA": "Okeaniya",
"uls-region-all": "Bütün dillər",
"uls-no-results-found": "Nəticələr tapılmadı",
"uls-common-languages": "Təklif edilən dillər",
"uls-no-results-suggestion-title": "Sizin üçün maraqlı ola bilər:",
"uls-search-help": "Siz dilin adı, yazısı və ISO-kodu üzrə və ya region üzrə axtarış edə bilərsiz.",
"uls-search-placeholder": "Dili axtar"
}

View File

@@ -1,23 +0,0 @@
{
"@metadata": {
"authors": [
"Alp Er Tunqa",
"Arjanizary",
"Mousa"
]
},
"uls-region-WW": "دونیا بویو",
"uls-region-SP": "مخصوص",
"uls-region-AM": "آمریکا",
"uls-region-AF": "آفریقا",
"uls-region-EU": "اوروپا",
"uls-region-AS": "آسیا",
"uls-region-ME": "اورتادوغو",
"uls-region-PA": "بؤیوک اوقیانوس",
"uls-region-all": "بۆتون دیللر",
"uls-no-results-found": "هئچ نتیجه تاپیلمادی",
"uls-common-languages": "یایغین دیل‌لر",
"uls-no-results-suggestion-title": "بونلارا ماراقلی اولابیلرسینیز:",
"uls-search-help": "سیز دیل آدی، یازی آدی، دیلین ISO کودو، یوخسا بؤلگه ایله آختارا بیلرسینیز.",
"uls-search-placeholder": "بیر دیلی آختار"
}

View File

@@ -1,22 +0,0 @@
{
"@metadata": {
"authors": [
"Sagan",
"Ләйсән"
]
},
"uls-region-WW": "Бөтә донъя",
"uls-region-SP": "Махсус",
"uls-region-AM": "Америка",
"uls-region-AF": "Африка",
"uls-region-EU": "Европа",
"uls-region-AS": "Азия",
"uls-region-ME": "Яҡын Көнсығыш",
"uls-region-PA": "Океания",
"uls-region-all": "Бөтә телдәр",
"uls-no-results-found": "Бер нимә лә табылманы",
"uls-common-languages": "Тәҡдим ителгән телдәр",
"uls-no-results-suggestion-title": "Бәлки, ошо телдәрҙе һайларһығыҙ:",
"uls-search-help": "Телдең исеме, яҙмаһы, ISO коды йәки регионы буйынса эҙләй алаһығыҙ.",
"uls-search-placeholder": "Тел буйынса эҙләү"
}

View File

@@ -1,22 +0,0 @@
{
"@metadata": {
"authors": [
"Chinamoonroll",
"Joseagush"
]
},
"uls-region-WW": "Gumi makejang",
"uls-region-SP": "Rahina",
"uls-region-AM": "Amérika",
"uls-region-AF": "Afrika",
"uls-region-EU": "Éropa",
"uls-region-AS": "Asia",
"uls-region-ME": "Timur Tengah",
"uls-region-PA": "Pasifik",
"uls-region-all": "Basa makejang",
"uls-no-results-found": "Tusing ade hasil",
"uls-common-languages": "Basa sane mapiteket",
"uls-no-results-suggestion-title": "Ida dane dumadak rimang:",
"uls-search-help": "Ida dane dados ngerereh anggen adan basa, adan script, kode basa ISO, utawi ida dane dados ngalih anggen wewengkon.",
"uls-search-placeholder": "Basa sane kererehin"
}

View File

@@ -1,17 +0,0 @@
{
"@metadata": {
"authors": [
"Stephensuleeman"
]
},
"uls-region-WW": "Sude luat portibi on",
"uls-region-AM": "Amerika",
"uls-region-AF": "Afrika",
"uls-region-EU": "Eropa",
"uls-region-AS": "Asia",
"uls-region-ME": "Timur Tengah",
"uls-region-PA": "Pasifik",
"uls-no-results-found": "Ndang adong jumpang",
"uls-common-languages": "Hata na somal",
"uls-search-placeholder": "Mandiori hata"
}

View File

@@ -1,21 +0,0 @@
{
"@metadata": {
"authors": [
"Baloch Afghanistan",
"Sultanselim baloch"
]
},
"uls-region-WW": "بی سراسری دونیا",
"uls-region-SP": "ویژه",
"uls-region-AM": "آمریکا",
"uls-region-AF": "آفریقا",
"uls-region-EU": "اروپا",
"uls-region-AS": "آسیا",
"uls-region-ME": "خاورمیانه",
"uls-region-PA": "اقیانوس آرام",
"uls-no-results-found": "نتیجه‌ای یافت نشد",
"uls-common-languages": "زبان‌های رایج",
"uls-no-results-suggestion-title": "ممکن است علاقه‌مند باشید:",
"uls-search-help": "شما می‌توانید بر پایه نام زبان، نام اسکریپت، کد استاندارد زبان یا بر پایه منطقه جستجو کنید:",
"uls-search-placeholder": "زبانء شۏھاز"
}

View File

@@ -1,21 +0,0 @@
{
"@metadata": {
"authors": [
"Kjeanclaude"
]
},
"uls-region-WW": "Mein oumouan nou",
"uls-region-SP": "Koungou liké",
"uls-region-AM": "Amériki",
"uls-region-AF": "Afriki",
"uls-region-EU": "Abloki",
"uls-region-AS": "Azi",
"uls-region-ME": "Wia afiliè lô mein i atôliè",
"uls-region-PA": "Pacifiki",
"uls-region-all": "Anien mou bé ngba",
"uls-no-results-found": "Ya woun man liké fi",
"uls-common-languages": "Anien nga bé fa klé mou",
"uls-no-results-suggestion-title": "Amoun kwla klo",
"uls-search-help": "Amoun kwla kounndè i anien douman sou, klèlè douman sou, anien ISO codi sou, anzè amoun kwla kounndè i akpassoua sou.",
"uls-search-placeholder": "Kounndè anien koun"
}

View File

@@ -1,22 +0,0 @@
{
"@metadata": {
"authors": [
"Brazal.dang",
"Geopoet"
]
},
"uls-region-WW": "Pankinaban",
"uls-region-SP": "Espesyal",
"uls-region-AM": "Amerika",
"uls-region-AF": "Aprika",
"uls-region-EU": "Europa",
"uls-region-AS": "Asya",
"uls-region-ME": "Katahawang Sirangan",
"uls-region-PA": "Pasipiko",
"uls-region-all": "Gabos na lengguwahe",
"uls-no-results-found": "Mayong mga resultang nanumpungan",
"uls-common-languages": "Komun na mga lengguwahe",
"uls-no-results-suggestion-title": "Ika gayod interesado sa:",
"uls-search-help": "Ika makakahanap sa pangaran nin lengguwahe, pangaran nin eskrip, ISO kodigo nin lengguwahe o kaya ika makakabuklat sa paagi nin rehiyon.",
"uls-search-placeholder": "Maghanap nin lengguwahe"
}

View File

@@ -1,23 +0,0 @@
{
"@metadata": {
"authors": [
"Amire80",
"Red Winged Duck",
"Wizardist"
]
},
"uls-region-WW": "Сусьветныя",
"uls-region-SP": "Дадатковыя",
"uls-region-AM": "Амэрыка",
"uls-region-AF": "Афрыка",
"uls-region-EU": "Эўропа",
"uls-region-AS": "Азія",
"uls-region-ME": "Блізкі Ўсход",
"uls-region-PA": "Акіянія",
"uls-region-all": "Усе мовы",
"uls-no-results-found": "Нічога ня знойдзена",
"uls-common-languages": "Прапанаваныя мовы",
"uls-no-results-suggestion-title": "Магчыма, вас зацікавяць:",
"uls-search-help": "Вы можаце шукаць паводле назвы мовы ці пісьменнасьці, а таксама паводле ISO-коду мовы, або выбраць рэгіён.",
"uls-search-placeholder": "Пошук мовы"
}

View File

@@ -1,22 +0,0 @@
{
"@metadata": {
"authors": [
"Amire80",
"Unomano"
]
},
"uls-region-WW": "Па ўсім свеце",
"uls-region-SP": "Спецыяльныя",
"uls-region-AM": "Амерыка",
"uls-region-AF": "Афрыка",
"uls-region-EU": "Еўропа",
"uls-region-AS": "Азія",
"uls-region-ME": "Блізкі Ўсход",
"uls-region-PA": "Ціхі акіян",
"uls-region-all": "Усе мовы",
"uls-no-results-found": "Нічога не знойдзена",
"uls-common-languages": "Прапанаваныя мовы",
"uls-no-results-suggestion-title": "Вы можаце быць зацікаўлены ў:",
"uls-search-help": "Вы можаце шукаць па мове, назве сцэнара, ISO-коду мовы, або вы можаце праглядаць па рэгіенах.",
"uls-search-placeholder": "Пошук мовы"
}

View File

@@ -1,25 +0,0 @@
{
"@metadata": {
"authors": [
"Amire80",
"Aquilax",
"DCLXVI",
"StanProg",
"Vodnokon4e"
]
},
"uls-region-WW": "Световни",
"uls-region-SP": "Специални",
"uls-region-AM": "Америка",
"uls-region-AF": "Африка",
"uls-region-EU": "Европа",
"uls-region-AS": "Азия",
"uls-region-ME": "Близкия изток",
"uls-region-PA": "Тихия океан",
"uls-region-all": "Всички езици",
"uls-no-results-found": "Не бяха открити резултати",
"uls-common-languages": "Предложени езици",
"uls-no-results-suggestion-title": "Може би се интересувате от:",
"uls-search-help": "Можете да търсите по име на език, име на скрипт, ISO кода на език или да разглеждате по региони.",
"uls-search-placeholder": "Търсене на език"
}

View File

@@ -1,22 +0,0 @@
{
"@metadata": {
"authors": [
"Baloch Afghanistan",
"Ibrahim khashrowdi"
]
},
"uls-region-WW": "بی موچین دونیایی تا",
"uls-region-SP": "خاص",
"uls-region-AM": "آمریکا",
"uls-region-AF": "آفریقا",
"uls-region-EU": "اروپا",
"uls-region-AS": "آسیا",
"uls-region-ME": "خاورمیانه",
"uls-region-PA": "اقیانوس آرام",
"uls-region-all": "موچین زبانان",
"uls-no-results-found": "هیچ نتیجه ودئ نبوت",
"uls-common-languages": "پیشنهاد بوته‌این زبانان",
"uls-no-results-suggestion-title": "ممکن اینت علاقه‌مند بئیت:",
"uls-search-help": "شما ئه توانیت به زبانی نامئ اساسا، نامئ اسکریپت، زبانئ استاندارتین کود یا به منطقه‌ای اساسا بگردیت.",
"uls-search-placeholder": "گَشتین په یک زبانئ خاتیرا"
}

View File

@@ -1,26 +0,0 @@
{
"@metadata": {
"authors": [
"Aftabuzzaman",
"Bellayet",
"Nasir8891",
"Sankarshan",
"Sayak Sarkar",
"আফতাবুজ্জামান"
]
},
"uls-region-WW": "বিশ্বব্যাপী",
"uls-region-SP": "বিশেষ",
"uls-region-AM": "আমেরিকা",
"uls-region-AF": "আফ্রিকা",
"uls-region-EU": "ইউরোপ",
"uls-region-AS": "এশিয়া",
"uls-region-ME": "মধ্যপ্রাচ্য",
"uls-region-PA": "প্রশান্ত মহাসাগরীয়",
"uls-region-all": "সকল ভাষা",
"uls-no-results-found": "কোনো ফলাফল পাওয়া যায়নি",
"uls-common-languages": "প্রস্তাবিত ভাষাসমূহ",
"uls-no-results-suggestion-title": "আপনি হয়তো আগ্রহী হতে পারেন:",
"uls-search-help": "আপনি ভাষার নাম, স্ক্রিপ্টের নাম, ভাষার আইএসও কোড অথবা এলাকার ভিত্তিক অনুসন্ধান করতে পারবেন।",
"uls-search-placeholder": "একটি ভাষার জন্য অনুসন্ধান করুন"
}

View File

@@ -1,22 +0,0 @@
{
"@metadata": {
"authors": [
"Fulup",
"Gwenn-Ael"
]
},
"uls-region-WW": "Bed a-bezh",
"uls-region-SP": "Dibar",
"uls-region-AM": "Amerika",
"uls-region-AF": "Afrika",
"uls-region-EU": "Europa",
"uls-region-AS": "Azia",
"uls-region-ME": "Reter-Kreiz",
"uls-region-PA": "Habask",
"uls-region-all": "An holl yezhoù",
"uls-no-results-found": "N'eus bet kavet disoc'h ebet",
"uls-common-languages": "Yezhoù aliet",
"uls-no-results-suggestion-title": "Gallout a reot bezañ dedennet gant :",
"uls-search-help": "Gallout a reot klask dre anv yezh, anv skript, kod yezh ISO pe gallout a reot klask dre rannvro.",
"uls-search-placeholder": "Klask ur yezh"
}

View File

@@ -1,24 +0,0 @@
{
"@metadata": {
"authors": [
"DzWiki",
"Edinwiki",
"Srdjan m",
"Srđan"
]
},
"uls-region-WW": "Svjetski",
"uls-region-SP": "Posebno",
"uls-region-AM": "Amerika",
"uls-region-AF": "Afrika",
"uls-region-EU": "Evropa",
"uls-region-AS": "Azija",
"uls-region-ME": "Bliski istok",
"uls-region-PA": "Pacifik",
"uls-region-all": "Svi jezici",
"uls-no-results-found": "Nema pronađenih rezultata",
"uls-common-languages": "Predloženi jezici",
"uls-no-results-suggestion-title": "Možda vas interesuje:",
"uls-search-help": "Možete da tražite po imenu jezika ili pisma, po ISO kodu jezika ili po regionu.",
"uls-search-placeholder": "Pronađi jezik"
}

View File

@@ -1,13 +0,0 @@
{
"@metadata": {
"authors": [
"Filipinayzd"
]
},
"uls-region-AM": "Amerika",
"uls-region-AF": "Aprika",
"uls-region-EU": "Europa",
"uls-region-AS": "Asya",
"uls-region-PA": "Pasipiko",
"uls-no-results-found": "Uda naturakan na resulta"
}

View File

@@ -1,24 +0,0 @@
{
"@metadata": {
"authors": [
"Amire80",
"Pginer",
"Ssola",
"Toniher"
]
},
"uls-region-WW": "Mundial",
"uls-region-SP": "Especials",
"uls-region-AM": "Amèrica",
"uls-region-AF": "Àfrica",
"uls-region-EU": "Europa",
"uls-region-AS": "Àsia",
"uls-region-ME": "Orient mitjà",
"uls-region-PA": "Pacífic",
"uls-region-all": "Totes les llengües",
"uls-no-results-found": "Cap resultat",
"uls-common-languages": "Llengües suggerides",
"uls-no-results-suggestion-title": "Pot interessar-vos:",
"uls-search-help": "Podeu cercar per nom de llengua, nom d'alfabet, codi ISO de la llengua o podeu navegar per regió:",
"uls-search-placeholder": "Cerca una llengua"
}

View File

@@ -1,21 +0,0 @@
{
"@metadata": {
"authors": [
"Умар"
]
},
"uls-region-WW": "Дерригдуьненан",
"uls-region-SP": "Леррина",
"uls-region-AM": "Америка",
"uls-region-AF": "Африка",
"uls-region-EU": "Европа",
"uls-region-AS": "Ази",
"uls-region-ME": "Гергара Малхбале",
"uls-region-PA": "Океани",
"uls-region-all": "Берриге меттанаш",
"uls-no-results-found": "Цакарийна",
"uls-common-languages": "Ша дӀанисбелла меттанаш",
"uls-no-results-suggestion-title": "Хьуна хӀара меттанаш хьашта хила мега:",
"uls-search-help": "Хьа таро ю меттан я йозанан цӀарца лаха, меттан ISO-кодаца я регионаца хьажа.",
"uls-search-placeholder": "Лаха мотт"
}

View File

@@ -1,24 +0,0 @@
{
"@metadata": {
"authors": [
"Asoxor",
"Calak",
"Lost Whispers",
"Épine"
]
},
"uls-region-WW": "لە گشت جیھاندا",
"uls-region-SP": "تایبەت",
"uls-region-AM": "ئەمریکا",
"uls-region-AF": "ئەفریقا",
"uls-region-EU": "ئەورووپا",
"uls-region-AS": "ئاسیا",
"uls-region-ME": "ڕۆژھەڵاتی ناوین",
"uls-region-PA": "ئۆقیانووسی ئارام",
"uls-region-all": "ھەموو زمانەکان",
"uls-no-results-found": "ھیچ ئاکامێک نەدۆزرایەوە",
"uls-common-languages": "زمانە پێشنیارکراوەکان",
"uls-no-results-suggestion-title": "ڕەنگە ئەمانەت پێ خۆش بێت:",
"uls-search-help": "دەتوانیت بە پێی ناوی زمان، جۆری ئەلفوبێ، کۆدی ISOی زمان یان بە پێی ناوچە بگەڕێی.",
"uls-search-placeholder": "گەڕان بەدوای زمانێکدا"
}

View File

@@ -1,20 +0,0 @@
{
"@metadata": {
"authors": [
"Bloomaround",
"ⲁϩⲙⲉⲧ"
]
},
"uls-region-WW": "ⲡⲓⲑⲟ ⲧⲏⲣϥ",
"uls-region-AM": "ⲁⲙⲉⲣⲓⲕⲏ",
"uls-region-AF": "ⲁⲫⲣⲓⲕⲏ",
"uls-region-EU": "ⲉⲩⲣⲱⲡⲏ",
"uls-region-AS": "ⲁⲥⲓⲁ",
"uls-region-ME": "ⲡⲓⲉⲃⲧ `ⲛⲑⲙⲏϯ",
"uls-region-PA": "ⲱⲕⲉⲁⲛⲓⲁ",
"uls-region-all": "ⲁⲥⲡⲓ ⲛⲓⲃⲉⲛ",
"uls-no-results-found": "ⲁⲩϫⲓⲙⲓ ⲁⲛ ⲛⲓⲁⲡⲟⲧⲉⲗⲉⲥⲙⲁ",
"uls-common-languages": "ⲛⲓⲁⲥⲡⲓ ⲁⲩϯⲙⲉⲩⲓ",
"uls-search-help": "ⲧⲉⲧⲉⲛϫⲉⲙϫⲟⲙ ⲉϫⲉⲙⲣⲁⲧ ϩⲉⲛ ⲡⲓⲣⲁⲛ ⲛⲧⲉ ⲟⲩⲁⲥⲡⲓ, ⲡⲓⲣⲁⲛ ⲛⲧⲉ ⲟⲩⲙⲉⲧⲥϦⲁⲓ, ⲟⲩϣⲓϥⲣ `ⲛISO ⲛⲧⲉ ⲁⲥⲡⲓ ⲓⲉ ⲧⲉⲧⲉⲛϫⲉⲙϫⲟⲙ ⲉⲥⲓⲛⲓ ϧⲁⲧⲉⲛⲟⲩⲭⲱⲣⲁ",
"uls-search-placeholder": "ϫⲉⲙⲣⲁⲧⲕ `ⲛⲟⲩⲁⲥⲡⲓ"
}

View File

@@ -1,23 +0,0 @@
{
"@metadata": {
"authors": [
"Amire80",
"Dvorapa",
"Mormegil"
]
},
"uls-region-WW": "Celosvětové",
"uls-region-SP": "Speciální",
"uls-region-AM": "Amerika",
"uls-region-AF": "Afrika",
"uls-region-EU": "Evropa",
"uls-region-AS": "Asie",
"uls-region-ME": "Blízký východ",
"uls-region-PA": "Tichomoří",
"uls-region-all": "Všechny jazyky",
"uls-no-results-found": "Nenalezeny žádné výsledky",
"uls-common-languages": "Doporučené jazyky",
"uls-no-results-suggestion-title": "Mohlo by vás zajímat:",
"uls-search-help": "Můžete vyhledávat podle názvu jazyka, názvu písma, ISO kódu jazyka nebo můžete procházet po regionech.",
"uls-search-placeholder": "Hledat jazyk"
}

View File

@@ -1,22 +0,0 @@
{
"@metadata": {
"authors": [
"Chavash",
"Salam"
]
},
"uls-region-WW": "Пӗтӗм тӗнчери",
"uls-region-SP": "Ятарлисем",
"uls-region-AM": "Америка",
"uls-region-AF": "Африка",
"uls-region-EU": "Европа",
"uls-region-AS": "Ази",
"uls-region-ME": "Малти хӗвел тухӑҫ",
"uls-region-PA": "Океани",
"uls-region-all": "Мӗн пур чӗлхе",
"uls-no-results-found": "Нимӗн те тупӑнмарӗ",
"uls-common-languages": "Сӗннӗ чӗлхесем",
"uls-no-results-suggestion-title": "Тен çак чĕлхесем пăхма пултаратăр:",
"uls-search-help": "Чĕлхе ячĕпе, çырулăхĕпе, ISO-кочĕпе е регионĕпе шырама пулать:",
"uls-search-placeholder": "Чĕлхе шыра"
}

View File

@@ -1,22 +0,0 @@
{
"@metadata": {
"authors": [
"Dafyddt",
"Lloffiwr",
"Robin Owain"
]
},
"uls-region-WW": "Byd-eang",
"uls-region-SP": "Neilltuol",
"uls-region-AM": "America",
"uls-region-AF": "Affrica",
"uls-region-EU": "Ewrop",
"uls-region-AS": "Asia",
"uls-region-ME": "Y Dwyrain Canol",
"uls-region-PA": "Y Pasiffig",
"uls-no-results-found": "Ni chafwyd unrhyw ganlyniadau",
"uls-common-languages": "Ieithoedd awgrymedig",
"uls-no-results-suggestion-title": "Hwyrach bod y rhai sy'n dilyn o ddiddordeb i chi:",
"uls-search-help": "Gallwch chwilio gan ddefnyddio enw iaith, enw sgript, côd ISO'r iaith neu gallwch bori fesul rhanbarth.",
"uls-search-placeholder": "Chwilio am iaith"
}

View File

@@ -1,24 +0,0 @@
{
"@metadata": {
"authors": [
"Amire80",
"Christian List",
"Jubber",
"Peter Alberti"
]
},
"uls-region-WW": "Verdensomspændende",
"uls-region-SP": "Specielle",
"uls-region-AM": "Amerika",
"uls-region-AF": "Afrika",
"uls-region-EU": "Europa",
"uls-region-AS": "Asien",
"uls-region-ME": "Mellemøsten",
"uls-region-PA": "Stillehavet",
"uls-region-all": "Alle sprog",
"uls-no-results-found": "Ingen resultater fundet",
"uls-common-languages": "Foreslåede sprog",
"uls-no-results-suggestion-title": "Du er måske interesseret i:",
"uls-search-help": "Du kan søge på sprogets navn, skriftens navn eller sprogets ISO-kode, eller du kan bladre hen til sproget efter regionen.",
"uls-search-placeholder": "Søg efter et sprog"
}

Some files were not shown because too many files have changed in this diff Show More