mirror of
https://github.com/kiwix/libkiwix.git
synced 2025-12-24 15:07:59 -05:00
Compare commits
3 Commits
dirScan
...
feature-br
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8343604394 | ||
|
|
908611102c | ||
|
|
4949a1d027 |
27
.github/move.yml
vendored
Normal file
27
.github/move.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
# 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
|
||||
258
.github/workflows/ci.yml
vendored
258
.github/workflows/ci.yml
vendored
@@ -1,200 +1,162 @@
|
||||
name: CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
pull_request:
|
||||
on: [push]
|
||||
|
||||
jobs:
|
||||
macOS:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
target:
|
||||
- macos-aarch64-dyn
|
||||
- macos-x86_64-dyn
|
||||
- ios-arm64-dyn
|
||||
- ios-x86_64-dyn
|
||||
include:
|
||||
- target: macos-aarch64-dyn
|
||||
arch_name: arm64-apple-macos
|
||||
run_test: true
|
||||
- target: macos-x86_64-dyn
|
||||
arch_name: x86_64-apple-darwin
|
||||
run_test: true
|
||||
- target: ios-arm64-dyn
|
||||
arch_name: aarch64-apple-ios
|
||||
run_test: false
|
||||
- target: ios-x86_64-dyn
|
||||
arch_name: x86-apple-ios-simulator
|
||||
run_test: false
|
||||
runs-on: macos-15
|
||||
|
||||
env:
|
||||
HOME: /Users/runner
|
||||
steps:
|
||||
- name: Retrieve source code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install packages
|
||||
run: |
|
||||
brew update
|
||||
brew install ninja meson
|
||||
|
||||
- name: Install dependencies
|
||||
uses: kiwix/kiwix-build/actions/dl_deps_archive@main
|
||||
with:
|
||||
target_platform: ${{ matrix.target }}
|
||||
|
||||
- name: Compile
|
||||
env:
|
||||
PKG_CONFIG_PATH: ${{env.HOME}}/BUILD_${{matrix.arch_name}}/INSTALL/lib/pkgconfig
|
||||
CPPFLAGS: -I${{env.HOME}}/BUILD_${{matrix.arch_name}}/INSTALL/include
|
||||
MESON_OPTION: --default-library=shared -Db_coverage=true
|
||||
MESON_CROSSFILE: ${{env.HOME}}/BUILD_${{matrix.arch_name}}/meson_cross_file.txt
|
||||
shell: bash
|
||||
run: |
|
||||
if [ -e $MESON_CROSSFILE ]; then
|
||||
MESON_OPTION="$MESON_OPTION --cross-file $MESON_CROSSFILE -Dstatic-linkage=true"
|
||||
fi
|
||||
meson . build ${MESON_OPTION}
|
||||
ninja -C build
|
||||
|
||||
- name: Test libkiwix
|
||||
if: matrix.run_test
|
||||
env:
|
||||
SKIP_BIG_MEMORY_TEST: 1
|
||||
LD_LIBRARY_PATH: ${{env.HOME}}/BUILD_${{matrix.arch_name}}/INSTALL/lib:${{env.HOME}}/BUILD_${{matrix.arch_name}}/INSTALL/lib64
|
||||
run: meson test -C build --verbose
|
||||
|
||||
Windows:
|
||||
runs-on: windows-2022
|
||||
|
||||
Macos:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup python 3.10
|
||||
uses: actions/setup-python@v5
|
||||
uses: actions/checkout@v1
|
||||
- name: Setup python 3.5
|
||||
uses: actions/setup-python@v1
|
||||
with:
|
||||
python-version: '3.10'
|
||||
|
||||
python-version: '3.5'
|
||||
- name: Install packages
|
||||
run:
|
||||
choco install pkgconfiglite ninja
|
||||
|
||||
brew install gcovr pkg-config ninja
|
||||
- name: Install python modules
|
||||
run: pip3 install meson
|
||||
|
||||
- name: Setup MSVC compiler
|
||||
uses: bus1/cabuild/action/msdevshell@v1
|
||||
with:
|
||||
architecture: x64
|
||||
|
||||
- name: Install dependencies
|
||||
uses: kiwix/kiwix-build/actions/dl_deps_archive@main
|
||||
with:
|
||||
target_platform: win-x86_64-static
|
||||
|
||||
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: cmd
|
||||
shell: bash
|
||||
run: |
|
||||
set PKG_CONFIG_PATH=%cd%\BUILD_win-amd64\INSTALL\lib\pkgconfig
|
||||
set CPPFLAGS=-I%cd%\BUILD_win-amd64\INSTALL\include
|
||||
meson.exe setup . build -Dwerror=false --default-library=static --buildtype=release
|
||||
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.exe
|
||||
|
||||
ninja
|
||||
- name: Test
|
||||
shell: cmd
|
||||
shell: bash
|
||||
run: |
|
||||
export LD_LIBRARY_PATH=$HOME/BUILD_native_dyn/INSTALL/lib:$HOME/BUILD_native_dyn/INSTALL/lib64
|
||||
cd build
|
||||
meson.exe test --verbose
|
||||
meson test --verbose
|
||||
ninja coverage
|
||||
env:
|
||||
WAIT_TIME_FACTOR_TEST: 10
|
||||
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:
|
||||
target:
|
||||
- linux-x86_64-static
|
||||
- linux-x86_64-dyn
|
||||
- android-arm
|
||||
- android-arm64
|
||||
image_variant: ['jammy']
|
||||
name:
|
||||
- native_static
|
||||
- native_dyn
|
||||
- native_dyn_bionic
|
||||
- android_arm
|
||||
- android_arm64
|
||||
- win32_static
|
||||
- win32_dyn
|
||||
include:
|
||||
- target: linux-x86_64-static
|
||||
- name: native_static
|
||||
target: native_static
|
||||
image_variant: xenial
|
||||
lib_postfix: '/x86_64-linux-gnu'
|
||||
arch_name: linux-x86_64
|
||||
run_test: true
|
||||
coverage: true
|
||||
- target: linux-x86_64-dyn
|
||||
- name: native_dyn
|
||||
target: native_dyn
|
||||
image_variant: xenial
|
||||
lib_postfix: '/x86_64-linux-gnu'
|
||||
arch_name: linux-x86_64
|
||||
run_test: true
|
||||
coverage: true
|
||||
- target: android-arm
|
||||
lib_postfix: '/arm-linux-androideabi'
|
||||
arch_name: arm-linux-androideabi
|
||||
run_test: false
|
||||
coverage: false
|
||||
- target: android-arm64
|
||||
lib_postfix: '/aarch64-linux-android'
|
||||
arch_name: aarch64-linux-android
|
||||
run_test: false
|
||||
coverage: false
|
||||
- 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-22.04
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: "ghcr.io/kiwix/kiwix-build_ci_${{matrix.image_variant}}:2025-06-07"
|
||||
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
|
||||
uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
uses: kiwix/kiwix-build/actions/dl_deps_archive@main
|
||||
with:
|
||||
target_platform: ${{ matrix.target }}
|
||||
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
|
||||
if [[ "${{matrix.target}}" =~ .*_dyn ]]; then
|
||||
MESON_OPTION="--default-library=shared"
|
||||
else
|
||||
MESON_OPTION="--default-library=static"
|
||||
fi
|
||||
if [ -e "${{env.HOME}}/BUILD_${{matrix.arch_name}}/meson_cross_file.txt" ]; then
|
||||
MESON_OPTION="$MESON_OPTION --cross-file ${{env.HOME}}/BUILD_${{matrix.arch_name}}/meson_cross_file.txt"
|
||||
else
|
||||
if [[ "${{matrix.target}}" =~ native_.* ]]; then
|
||||
MESON_OPTION="$MESON_OPTION -Db_coverage=true"
|
||||
else
|
||||
MESON_OPTION="$MESON_OPTION --cross-file $HOME/BUILD_${{matrix.target}}/meson_cross_file.txt"
|
||||
fi
|
||||
if [[ "${{matrix.target}}" =~ android-.* ]]; then
|
||||
MESON_OPTION="$MESON_OPTION -Dstatic-linkage=true"
|
||||
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.arch_name}}/INSTALL/lib/pkgconfig:/home/runner/BUILD_${{matrix.arch_name}}/INSTALL/lib${{matrix.lib_postfix}}/pkgconfig"
|
||||
CPPFLAGS: "-I/home/runner/BUILD_${{matrix.arch_name}}/INSTALL/include"
|
||||
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: matrix.run_test
|
||||
if: startsWith(matrix.target, 'native_')
|
||||
shell: bash
|
||||
run: |
|
||||
cd build
|
||||
cd $HOME/kiwix-lib/build
|
||||
meson test --verbose
|
||||
if [[ "${{matrix.coverage}}" = "true" ]]; then
|
||||
ninja coverage
|
||||
fi
|
||||
ninja coverage
|
||||
env:
|
||||
LD_LIBRARY_PATH: "/home/runner/BUILD_${{matrix.arch_name}}/INSTALL/lib:/home/runner/BUILD_${{matrix.arch_name}}/INSTALL/lib${{matrix.lib_postfix}}"
|
||||
LD_LIBRARY_PATH: "/home/runner/BUILD_${{matrix.target}}/INSTALL/lib:/home/runner/BUILD_${{matrix.target}}/INSTALL/lib${{matrix.lib_postfix}}"
|
||||
SKIP_BIG_MEMORY_TEST: 1
|
||||
|
||||
- name: Publish coverage
|
||||
if: matrix.coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
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 }}
|
||||
|
||||
102
.github/workflows/package.yml
vendored
102
.github/workflows/package.yml
vendored
@@ -1,29 +1,15 @@
|
||||
name: Packages
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
release:
|
||||
types: [published]
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
build-deb:
|
||||
runs-on: ubuntu-22.04
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
distro:
|
||||
# - debian-unstable
|
||||
# - debian-trixie
|
||||
# - debian-bookworm
|
||||
# - debian-bullseye
|
||||
- ubuntu-noble
|
||||
- ubuntu-jammy
|
||||
|
||||
distro: [ubuntu-hirsute, ubuntu-groovy, ubuntu-focal, ubuntu-bionic]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
# Determine which PPA we should upload to
|
||||
- name: PPA
|
||||
@@ -31,81 +17,71 @@ jobs:
|
||||
run: |
|
||||
if [[ $REF == refs/tags* ]]
|
||||
then
|
||||
echo "ppa=kiwixteam/release" >> $GITHUB_OUTPUT
|
||||
echo "::set-output name=ppa::kiwixteam/release"
|
||||
else
|
||||
echo "ppa=kiwixteam/dev" >> $GITHUB_OUTPUT
|
||||
echo "::set-output name=ppa::kiwixteam/dev"
|
||||
fi
|
||||
env:
|
||||
REF: ${{ github.ref }}
|
||||
|
||||
- uses: legoktm/gh-action-auto-dch@main
|
||||
- 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@debian-unstable
|
||||
# if: matrix.distro == 'debian-unstable'
|
||||
# name: Build package for debian-unstable
|
||||
# id: build-debian-unstable
|
||||
# with:
|
||||
# args: --no-sign
|
||||
#
|
||||
# - uses: legoktm/gh-action-build-deb@b47978ba8498dc8b8153cc3b5f99a5fc1afa5de1 # pin@debian-trixie
|
||||
# if: matrix.distro == 'debian-trixie'
|
||||
# name: Build package for debian-trixie
|
||||
# id: build-debian-trixie
|
||||
# with:
|
||||
# args: --no-sign
|
||||
#
|
||||
# - uses: legoktm/gh-action-build-deb@1f4e86a6bb34aaad388167eaf5eb85d553935336 # pin@debian-bookworm
|
||||
# if: matrix.distro == 'debian-bookworm'
|
||||
# name: Build package for debian-bookworm
|
||||
# id: build-debian-bookworm
|
||||
# with:
|
||||
# args: --no-sign
|
||||
#
|
||||
# - uses: legoktm/gh-action-build-deb@084b4263209252ec80a75d2c78a586192c17f18d # pin@debian-bullseye
|
||||
# if: matrix.distro == 'debian-bullseye'
|
||||
# name: Build package for debian-bullseye
|
||||
# id: build-debian-bullseye
|
||||
# with:
|
||||
# args: --no-sign
|
||||
|
||||
- uses: legoktm/gh-action-build-deb@9114a536498b65c40b932209b9833aa942bf108d # pin@ubuntu-noble
|
||||
if: matrix.distro == 'ubuntu-noble'
|
||||
name: Build package for ubuntu-noble
|
||||
id: build-ubuntu-noble
|
||||
- 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-jammy
|
||||
if: matrix.distro == 'ubuntu-jammy'
|
||||
name: Build package for ubuntu-jammy
|
||||
id: build-ubuntu-jammy
|
||||
- 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: actions/upload-artifact@v4
|
||||
- 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@main
|
||||
- uses: legoktm/gh-action-dput@master
|
||||
name: Upload dev package
|
||||
# Only upload on pushes to main
|
||||
if: github.event_name == 'push' && github.event.ref == 'refs/heads/main' && startswith(matrix.distro, 'ubuntu-')
|
||||
# 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@main
|
||||
- uses: legoktm/gh-action-dput@master
|
||||
name: Upload release package
|
||||
if: github.event_name == 'release' && startswith(matrix.distro, 'ubuntu-')
|
||||
# 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
|
||||
|
||||
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -4,6 +4,3 @@ subprojects/googletest-release*
|
||||
*.class
|
||||
build/
|
||||
.vscode/
|
||||
builddir/
|
||||
.cache/
|
||||
.clangd/
|
||||
|
||||
@@ -1,21 +0,0 @@
|
||||
# Read the Docs configuration file
|
||||
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||
|
||||
# Required
|
||||
version: 2
|
||||
|
||||
# Set the version of Python and other tools you might need
|
||||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.11"
|
||||
|
||||
# Build documentation in the docs/ directory with Sphinx
|
||||
sphinx:
|
||||
configuration: docs/conf.py
|
||||
|
||||
# We recommend specifying your dependencies to enable reproducible builds:
|
||||
# https://docs.readthedocs.io/en/stable/guides/reproducible-builds.html
|
||||
python:
|
||||
install:
|
||||
- requirements: docs/requirements.txt
|
||||
286
ChangeLog
286
ChangeLog
@@ -1,289 +1,3 @@
|
||||
libkiwix 14.1.1
|
||||
===============
|
||||
|
||||
* Server:
|
||||
- Fix regression for kiwix-serve --nosearchbar (@veloman-yunkan #1250)
|
||||
- Avoid results content interpretation... crash in fulltext search (@vighnesh-sawant #1241)
|
||||
- Fix for intermittent /content/blank.html errors (@veloman-yunkan #1249)
|
||||
|
||||
libkiwix 14.1.0
|
||||
===============
|
||||
|
||||
* Server:
|
||||
- Viewer detects & tracks intrapage navigation anchors too (@veloman-yunkan #1213)
|
||||
- Add support for catalog only mode (@veloman-yunkan #1219)
|
||||
- Add API which returns server access url (@vighnesh-sawant #1234)
|
||||
- Fix chrome searchbar placeholder text overflow (@aditii2712 #1185)
|
||||
- Fix magnet link queryStyring (@rgaudin #1160)
|
||||
- Improve chrome printing stylesheet (@kelson42 #1202)
|
||||
- Default white background (@kelson42 #1205)
|
||||
|
||||
* Other:
|
||||
- Switched to the new libzim illustrations API (@veloman-yunkan #1226)
|
||||
- Stop building Windows with DEBUG symbols in CI (@kelson42 #1165)
|
||||
- Update many things in the CI/CD (@kelson42 #1203 #1194 #1209 #1207 #1235)
|
||||
- Requires now libzim 9.4.0 (@kelson42 #1231)
|
||||
- Fix compilation for FreeBSD (@OICe2 #1173 #1174)
|
||||
- Wait up to 1s to let aria2c to start before complaining (@kelson42 #1169)
|
||||
|
||||
libkiwix 14.0.0
|
||||
===============
|
||||
|
||||
* Server:
|
||||
- Support of IPv6 (@veloman-yunkan @aryanA101a #1074 #1093)
|
||||
- Better public IP configuration/detection (@sgourdas #1132)
|
||||
- Fix API errors in catalog searches if Xapian keyword in used (@veloman-yunkan #1137)
|
||||
- Clearly define which Web browsers are supported (@kelson42 @rgaudin @jaifroid @benoit74 #1132)
|
||||
- Improve welcome page download buttons (@veloman-yunkan #1094)
|
||||
- Better handling of external (non-HTTP) links (@veloman-yunkan #1123)
|
||||
- Fix book illustration size on welcome page to 48x48 pixels (@veloman-yunkan #1127)
|
||||
- Remove "Multiple Languages" in language filter (@veloman-yunkan #1098)
|
||||
- Stop transforming tags casing (@kelson42 @veloman-yunkan #1079 #1121)
|
||||
- ZIM file size consistently advertised in MiB (@harsha-mangena #1132)
|
||||
- Few new supported languages in the filter (@kelson42 #1080)
|
||||
- Improve accesskeys (@kelson42 #1075)
|
||||
- Add OpenSearch <link> to head of pages (@kelson42 #1070)
|
||||
* Compilation/Packaging:
|
||||
- Multiple fixes around deb packaging (@kelson42 #1108 #1114 #1135)
|
||||
- Generating of libkiwix.pc via Meson (@veloman-yunkan #1133)
|
||||
- Native Windows CI/CD (@mgautierfr @kelson42 #1113 #1125)
|
||||
- Better check (maximum) libzim version (@kelson42 #1124)
|
||||
- Multiple automated tests improvements (@veloman-yunkan #1068 #1067)
|
||||
* Other:
|
||||
- Deleted supported env. variable `$KIWIX_DATA_DIR` and `kiwix::getDataDirectory()` (@sgourdas #1107)
|
||||
- New string slugification for filenames (@shaopenglin #1105)
|
||||
- Multiple improvements around aria2c download mgmt. (@veloman-yunkan #1097)
|
||||
|
||||
libkiwix 13.1.0
|
||||
===============
|
||||
|
||||
* Server:
|
||||
- Properly translated error pages (@veloman-yunkan #1032)
|
||||
- Properly translated search result page (@veloman-yunkan #1046)
|
||||
- Default UI language is resolved in frontend (@veloman-yunkan #1044)
|
||||
- Better support of older Web browsers by polyfilling replaceAll() (@veloman-yunkan #1054)
|
||||
* New API to migrate bookmarks between books (@mgautierfr #1043)
|
||||
* Fixed compilation on Haiku OS (@Begasus #1048)
|
||||
|
||||
libkiwix 13.0.0
|
||||
===============
|
||||
|
||||
* Server:
|
||||
- Improved look & feel of kiwix-serve UI (@veloman-yunkan #917 #1021)
|
||||
- Increase tolerance to malformed (control characters) ZIM entry titles (@veloman-yunkan #1023)
|
||||
- API allowing to filter many categories at once (@juuz0 #974)
|
||||
- Cookie-less user language control (@veloman-yumkan #997)
|
||||
- Hack to fix Mirrorbrain based broken magnet URLs (@rgaudin #1001)
|
||||
* Fix handling of books with 'Name' metadata with dots (@mgautier #1016)
|
||||
* New method beautifyFileSize() to provide nice-looking book sizes (@vuuz0 #971)
|
||||
* Fix a few missing includes (@mgautierfr #978)
|
||||
* New functions to read - kiwix-serve - languages and categories streams (@juuz0 #967)
|
||||
* Add support of Fon language (@kelson42 #1013)
|
||||
* C++17 code base compliancy (@mgautierfr #996)
|
||||
* Use everywhere std::shared_ptr in place of raw pointer (@mgautierfr #991)
|
||||
* Do not use [[nodiscard]] attribute on compiler not supporting it (@mgautierfr #1003)
|
||||
* Add a non minified version of autoComplete.js (@mgautierfr #1008)
|
||||
* Multiple CI/CD improvements (@kelson42 #982)
|
||||
|
||||
libkiwix 12.1.0
|
||||
===============
|
||||
|
||||
* Server:
|
||||
- Introduce a `/nojs` endpoint to browse catalog and zim files with a browser without js (@juuz0 #897)
|
||||
- Translate the viewer (@veloman-yunkan #871 #846)
|
||||
- Display `mul` on tile when zim is multi-languages (@juuz0 #934)
|
||||
- Suggestion links point to the `/content` endpoint (@veloman-yunkan #862)
|
||||
- Correctly compress web fonts in http answers (@kelson42 #856)
|
||||
- Correctly encode link in suggestions (@veloman-yunkan #859 #860 #963)
|
||||
- Correctly encode url redirection (@veloman-yunkan #866 #890)
|
||||
- Properly handle user language, through cookies and http headers (@veloman-yunkan #849 #869)
|
||||
- Fix url encoding (@veloman-yunkan #870)
|
||||
- Fix viewer for viewer for SeaMonkey (@veloman-yunkan #887)
|
||||
- Make the downloader threadsafe (@mgautierfr #886)
|
||||
- Add RSS feed in the main page (pointing to the catalog) (@juuz0 #882 #920)
|
||||
- Correctly set the mimetype for json and ico (@veloman-yunkan #892)
|
||||
- `count=-1` correspond to unlimited count (instead of 0) (@veloman-yunkan #894)
|
||||
- Keep the navigation bar on top (@juuz0 #896)
|
||||
- Make the viewer's iframe "safe" (@veloman-yunkan #906 #930)
|
||||
- Correctly escape search link in XML Opds output (@veloman-yunkan #936)
|
||||
- Store values needed for the viewer js in the url fragment instead of the query string (@juuz0 #907)
|
||||
- Get rid of legacy OPDS API usage in the viewer (@veloman-yunkan #939)
|
||||
- Fix charset encoding declaration in OPDS response MIME types (@veloman-yunkan #942)
|
||||
- Fix PDF in the viewer (@veloman-yunkan #940)
|
||||
- Fix external links handling in the viewer (@veloman-yunkan #959)
|
||||
- Add tests of searching with accents (@mgautierfs #954)
|
||||
* Fix handling of missing illustration in the book (@veloman-yunkan #961)
|
||||
* Add support for multi languages zim files (@veloman-yunkan #904)
|
||||
* Fix includes for openbsd (@bentley #949)
|
||||
* Fix pathes in git to allow git clone on Windows (@adamlamar #868)
|
||||
* Switch to `main` as principal branch (instead of `master`) (@kelson42)
|
||||
* Remove libkiwix android publisher from the repository (@kelson42 #884)
|
||||
* Various fixes of meson and CI. (@mgautierfr @kelson42)
|
||||
|
||||
libkiwix 12.0.0
|
||||
===============
|
||||
|
||||
* [API Break] Remove wrapper around libzim (@mgautierfr #789)
|
||||
* Allow kiwix-serve to use custom resource files (@veloman-yunkan #779)
|
||||
* Properly handle searchProtocolPrefix when rendering search result (@veloman-yunkan #823)
|
||||
* Prevent search on multi language content (@veloman-yunkan #838)
|
||||
* Use new `zim::Archive::getMediaCount` from libzim (@mgautierfr #836)
|
||||
* Catalog:
|
||||
- Include tags in free text catalog search (@veloman-yunkan #802)
|
||||
- Illustration's url is based on book's uuid (@veloman-yunkan #804)
|
||||
- Cleanup of the opds-dumper (@veloman-yunkan #829)
|
||||
- Allow filtering of catalog content using multiple languages (@veloman-yunkan #841)
|
||||
- Make opds-dumper respect the namemapper (@mgautierfr #837)
|
||||
* Server:
|
||||
- Correctly handle `\` in suggestion json generation (@veloman-yunkan #843)
|
||||
- Better http caching (@veloman-yunkan #833)
|
||||
- Make `/suggest` endpoint thread-safe (@veloman-yunkan #834)
|
||||
- Better redirection of main page (@veloman-yunkan #827)
|
||||
- Remove jquery (@mgautierfr @juuz0 #796)
|
||||
- Better Viewer of zim content :
|
||||
. Introduce `/content` endpoints (@veloman-yunkan #806)
|
||||
. Switch to iframe based content viewer (@veloman-yunkan #716)
|
||||
- Optimised design of the welcome page:
|
||||
. Alignement (@juuz0 @kelson42 #786)
|
||||
. Exit download modal on pressing escape key (@juzz0 #800)
|
||||
. Add favicon for different devices (@juzz0 #805)
|
||||
. Fix auto hidding of the toolbar (@veloman-yunkan #821)
|
||||
. Allow user to filter books by tags in the front page (@juuz0 #711)
|
||||
* CI :
|
||||
- Trigger CI on pull_request (@kelson42 #791)
|
||||
- Drop Ubuntu Impish packaging (@legoktm #825)
|
||||
- Add Ubuntu Kinetic packaging (@legoktm #801)
|
||||
* Testing:
|
||||
- Test ICULanguageInfo (@veloman-yunkan #795)
|
||||
- Introduce fake `test` language to test i18n (@veloman-yunkan #848)
|
||||
* Fix documentation (@kelson42 #816)
|
||||
* Udpate translation (#787 #839 #847)
|
||||
|
||||
libkiwix 11.0.0
|
||||
===============
|
||||
|
||||
* [server] Add support for internationalization (@veloman-yunkan #679)
|
||||
* [server] Use gzip compression instead of deflat (mgautierfr #757)
|
||||
* [server] Version the static resources. This allow better invalidating
|
||||
browser cache when resources are changed (@veloman-yunkan #712)
|
||||
* [server|front] Use integer to query the host for page length (@juuz0 #772)
|
||||
* [server] Improve multizim search API:
|
||||
- Improvement of the cache system
|
||||
- Better API to select on which books to search in.
|
||||
- SysAdmin is now able to limit the number of book we search in for a multizim search
|
||||
* [server] Introduce a opensearch API for multizim fulltext search
|
||||
* [wrapper] Remove java wrapper
|
||||
* Testing:
|
||||
- Testing of search result pages content (@veloman-yunkan #765)
|
||||
- Better testing structure of xml search result (@veloman-yunkan #780)
|
||||
|
||||
libkiwix 10.1.1
|
||||
===============
|
||||
|
||||
* Correctly detect the number of article for older zims (<=6) (@mgautier #743)
|
||||
* [server] Fix fulltext search (@mgautierfr #724)
|
||||
* [server][internal] New way to build Error message (@veloman-yunkan #732 #738 #744)
|
||||
* Fix CI (@mgautierfr #736)
|
||||
|
||||
libkiwix 10.1.0
|
||||
===============
|
||||
|
||||
This release is an important one as it fixes a Xss vulnerability introduced
|
||||
in libkiwix 10.0.0
|
||||
|
||||
* [SECURITY] Fix a Xss attack vulnerability (introduced in 10.0.0) (@juuz0 #721)
|
||||
* [server] Add a option to set a limit on the number of connexion per IP (@kelson42 #700)
|
||||
* [server] Do not display a lang tag in the UI if the book has no language (@juuz0 #706)
|
||||
* [server] Add the book title associated to a search results (@thavelick #705, @mgautierfr #718)
|
||||
* Add `dc:issued` to opds output stream (@veloman-yunkan #715)
|
||||
* Add handling of several languages not provided by ICU (@juuz0 #701)
|
||||
* [server] Add a caching system for search and suggestion (@maneeshpm #620)
|
||||
* Fix cross-compilation (@kelson42 #703)
|
||||
* Add unit-testing of suggestions and error pages (@veloman-yunkan #709 #710 #727)
|
||||
* Better testing system of html response (@veloman-yunkan #725)
|
||||
|
||||
libkiwix 10.0.1
|
||||
===============
|
||||
|
||||
* [server] The catalog search interpret `count=0` as no limit.
|
||||
This was the case for a long time. This was changed unintentionally
|
||||
(@veloman-yunkan #686)
|
||||
* [server] Correctly generere a human friendly title in the server frontend.
|
||||
(@juuz0 #687, @kelson42 #689)
|
||||
* [server] Fix download button if there is no url do download from.
|
||||
(@juuz0 #691)
|
||||
* Add non-minified isotope.pkdg.js
|
||||
Needed for debian packaging as we need the source and minified version is
|
||||
not the source (@legoktm #693)
|
||||
* [server] Add a tooltip with the full language for the lang tag.
|
||||
* CI fixes (@kelson42 @legoktm)
|
||||
|
||||
libkiwix 10.0.0
|
||||
===============
|
||||
|
||||
This release is huge release.
|
||||
The project has been renamed to libkiwix, it is more coherent with the library name.
|
||||
|
||||
* Server front page :
|
||||
- Use js in the front page to display the available book,
|
||||
using the OPDS stream as source. The front page is now populated only with
|
||||
the visible books and user can search for books. (@MananJethwany #530, #541, #534)
|
||||
(@kelson42 #628)
|
||||
- Revamp css (@MananJethwany #559)
|
||||
- Correctly Convert 3iso language code to 2iso (@juuz0 #672)
|
||||
|
||||
* Server suggestions search :
|
||||
- Add pagination for suggestion search (@maneeshpm #591)
|
||||
- Fix suggestion system (@MananJethwany #498)
|
||||
- Provide the kind and path (when adapted) to the suggestion answer (@MananJethwany #464)
|
||||
- The displayed suggestion have now highligth on the searched terms (@maneeshpm #505)
|
||||
- Properly handle html encoding of suggestions (@veloman-yunkan #458)
|
||||
|
||||
* Server improvements :
|
||||
- Remove meta endpoints (@mgautier #669)
|
||||
- Add raw endpoints to get the raw content of a zim (@mgautierfr #646)
|
||||
- Add details on 404 error pages (@soumyankar #490)
|
||||
- Fix headbar insertion when `<head>` tag has attributes (@kelson42 #440)
|
||||
- Better headbar insertion (after charset definition) (@kelson42 #442)
|
||||
|
||||
* New OPDS Stream v2 :
|
||||
- Add a list of categories (@veloman-yunkan)
|
||||
- Support for partial entries (@veloman-yunkan #602)
|
||||
- Support multiple icons size in the OPDS stream (@veloman-yunkan #577 #630)
|
||||
- Add language endpoint to catalog (@veloman-yunkan #553)
|
||||
- Add illustration API to get the illustration of a book (@mgautierfr #645)
|
||||
- OPDS search can now filter books by category (@veloman-yunkan #459)
|
||||
|
||||
* Library improvements :
|
||||
- Allow the libray to be live reloaded when the library.xml changes (@veloman-yunkan #636)
|
||||
- Properly handle removing of book from the library (@veloman-yunkan #485)
|
||||
- Use xapian to search for books in the library (@veloman-yunkan #460, #488)
|
||||
|
||||
* Added methods/functions :
|
||||
- Fix `fileExist` and introduce `fileReadable` (@juuz0 #668)
|
||||
- Add `getVersions` and `printVersions` functions (@kelson42 #665)
|
||||
- Add `getNetworkInterfaces()` and `getBestPublicIP()` functions (@juuz0 #622)
|
||||
- Add `get_zimid()` method to the search result (@maneeshpm #510)
|
||||
|
||||
* Various improvements :
|
||||
- Better secret value for aria2c rpc (@juuz0 #666)
|
||||
- Avoid duplicated Archive/Reader in the Searcher (@veloman-yunkan #648)
|
||||
- Add basic documentation (@mgautierfr #640)
|
||||
- Do not use Reader internally (@maneeshpm #536 #576)
|
||||
- Remove dependency headers from our public headers (@mgautierfr #574)
|
||||
- Downloader now don't write metalink on the filesystem (@kelson42 #502)
|
||||
- Support opening a zim file using a fd (@veloman-yukan #429)
|
||||
- Use C++11 std::thread instead of pthread (@mgautierfr #445)
|
||||
- [READER] Do not crash if zim file has no `Counter` metadata (@mgautierfr #449)
|
||||
- Ensure libzim dependency is compiled with xapian (@mgautierfr #434)
|
||||
- Support video and audio mimetype in `getMediaCount` (@kelson42 #439)
|
||||
- Better parsing of the counterMap (@kelson42 #437)
|
||||
- Adapt libkiwix to libzim 7.0.0 (@mgautierfr #428)
|
||||
- Remove deprecated methods (@mgautierfr)
|
||||
- CI: Build package for Ubuntu Hirsute, Impish and Jammy (@legoktm #431 #568) and remove Groovy
|
||||
- Fix compilation for FreeBSD (@swills g#432)
|
||||
- Many fixes and improvement (@MananJethwany, @maneeshpm, @veloman-yunkan, @mgautierfr)
|
||||
|
||||
kiwix-lib 9.4.1
|
||||
===============
|
||||
|
||||
|
||||
154
README.md
154
README.md
@@ -1,52 +1,50 @@
|
||||
Libkiwix
|
||||
========
|
||||
Kiwix library
|
||||
=============
|
||||
|
||||
The Libkiwix provides the [Kiwix](https://kiwix.org) software suite
|
||||
core. It contains the code shared by all Kiwix ports (Windows,
|
||||
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, ...).
|
||||
|
||||
[](https://download.kiwix.org/release/libkiwix/)
|
||||
[](https://github.com/kiwix/libkiwix/wiki/Repology)
|
||||
[](https://github.com/kiwix/libkiwix/actions?query=branch%3Amain)
|
||||
[](https://libkiwix.readthedocs.org/en/latest/?badge=latest)
|
||||
[](https://www.codefactor.io/repository/github/kiwix/libkiwix)
|
||||
[](https://codecov.io/gh/kiwix/libkiwix)
|
||||
[](https://bintray.com/kiwix/kiwix/kiwixlib/_latestVersion)
|
||||
[](https://github.com/kiwix/kiwix-lib/actions?query=branch%3Amaster)
|
||||
[](https://www.codefactor.io/repository/github/kiwix/kiwix-lib)
|
||||
[](https://codecov.io/gh/kiwix/kiwix-lib)
|
||||
[](https://www.gnu.org/licenses/gpl-3.0)
|
||||
|
||||
[](https://repology.org/project/kiwix-lib/versions)
|
||||
|
||||
Disclaimer
|
||||
----------
|
||||
|
||||
This document assumes you have a little knowledge about software
|
||||
compilation. If you experience difficulties with the dependencies or
|
||||
with the Libkiwix compilation itself, we recommend to have a look to
|
||||
[kiwix-build](https://github.com/kiwix/kiwix-build).
|
||||
with the Kiwix library compilation itself, we recommend to have a look
|
||||
to [kiwix-build](https://github.com/kiwix/kiwix-build).
|
||||
|
||||
Preamble
|
||||
--------
|
||||
|
||||
Although the Libkiwix 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 on recent
|
||||
releases of Ubuntu and Fedora.
|
||||
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
|
||||
on recent releases of Ubuntu and Fedora.
|
||||
|
||||
Dependencies
|
||||
------------
|
||||
|
||||
The Libkiwix relies on many third party software libraries. They are
|
||||
prerequisites to the Libkiwix compilation. Following libraries need to
|
||||
be available:
|
||||
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 4.1 or above.
|
||||
* [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)
|
||||
|
||||
To test the code:
|
||||
* [Google Test](https://github.com/google/googletest) (package `googletest` on Ubuntu)
|
||||
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)
|
||||
@@ -54,16 +52,16 @@ The following dependency needs to be available at runtime:
|
||||
These dependencies may or may not be packaged by your operating
|
||||
system. They may also be packaged but only in an older version. The
|
||||
compilation script will tell you if one of them is missing or too old.
|
||||
In the worst case, you will have to download and compile bleeding edge
|
||||
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
|
||||
`libkiwix` directory as install prefix.
|
||||
`kiwix-lib` directory as install prefix.
|
||||
|
||||
Environment
|
||||
-------------
|
||||
|
||||
The Libkiwix builds using [Meson](https://mesonbuild.com/) version
|
||||
The Kiwix library builds using [Meson](https://mesonbuild.com/) version
|
||||
0.45 or higher. Meson relies itself on Ninja, pkg-config and few other
|
||||
compilation tools.
|
||||
|
||||
@@ -79,7 +77,7 @@ section.
|
||||
Compilation
|
||||
-----------
|
||||
|
||||
Once all dependencies are installed, you can compile the Libkiwix
|
||||
Once all dependencies are installed, you can compile the Kiwix library
|
||||
with:
|
||||
```bash
|
||||
meson . build
|
||||
@@ -87,47 +85,12 @@ ninja -C build
|
||||
```
|
||||
|
||||
By default, it will compile dynamic linked libraries. All binary files
|
||||
will be created in the `build` directory created automatically by
|
||||
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`.
|
||||
|
||||
The android wrapper uses deprecated methods of libkiwix so it cannot be compiled
|
||||
with `werror=true` (the default). So you must pass `-Dwerror=false` to meson:
|
||||
|
||||
```bash
|
||||
meson . build -Dwrapper=android -Dwerror=false
|
||||
ninja -C build
|
||||
```
|
||||
|
||||
Static files compilation
|
||||
------------------------
|
||||
|
||||
Libkiwix has a few static files 'compiled' within the binary
|
||||
code. This is mostly Javascript/HTML/pictures necessary for the HTTP
|
||||
daemon.
|
||||
|
||||
These static files are available in the `static` directory and are
|
||||
compiled by custom Python code available in this repository `scripts`
|
||||
directory. This happens automatically at compilation time without any
|
||||
additional command to run.
|
||||
|
||||
To avoid HTTP caching issues, the URLs (to the static content) are
|
||||
appended with a `cacheid` parameter (this is called "cache
|
||||
busting"). This `cacheid` value derived from the
|
||||
[sha1sum](https://en.wikipedia.org/wiki/Sha1sum) of each targeted
|
||||
static file. As a consequence, each time you change a static file, the
|
||||
corresponding `cacheid` value will change.
|
||||
|
||||
To properly test this feature, this `cacheid` needs to be added
|
||||
manually to the automated tests and has to be commited. After
|
||||
modifying the needed static file, [run the automated
|
||||
tests](#Testing). They will fail, but the inspection of the testing
|
||||
log will give you the new `cacheid` value(s). Finally update
|
||||
`test/server.cpp` with the appropriate `cacheid` value(s) which have
|
||||
changed.
|
||||
|
||||
Testing
|
||||
-------
|
||||
|
||||
@@ -140,7 +103,7 @@ meson test
|
||||
Installation
|
||||
------------
|
||||
|
||||
If you want to install the Libkiwix and the headers you just have
|
||||
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
|
||||
@@ -151,7 +114,7 @@ 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
|
||||
@@ -161,55 +124,6 @@ ninja -C build uninstall
|
||||
Like for the installation, you might need to run the command as `root`
|
||||
(or using `sudo`).
|
||||
|
||||
Custom Index Page
|
||||
-----------------
|
||||
|
||||
to use custom welcome page mention `customIndexPage` argument in `kiwix::internalServer()` or use `kiwix::server->setCustomIndexTemplate()`.
|
||||
(note - while using custom html file please mention all external links as absolute path.)
|
||||
|
||||
to create a HTML template with custom JS you need to have a look at various OPDS based endpoints as mentioned [here](https://wiki.kiwix.org/wiki/OPDS) to load books.
|
||||
|
||||
To use JS provided by kiwix-serve you can use the following template to start with ->
|
||||
|
||||
```
|
||||
<!DOCTYPE html>
|
||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width,initial-scale=1" />
|
||||
<title><-- Custom Tittle --></title>
|
||||
<script src="{{root}}/skin/isotope.pkgd.min.js" defer></script>
|
||||
<script src="{{root}}/skin/iso6391To3.js"></script>
|
||||
<script type="text/javascript" src="{{root}}/skin/index.js" defer></script>
|
||||
</head>
|
||||
<body>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
- To get books listed using `index.js` add - `<div class="book__list"></div>` under body tag.
|
||||
- To get number of books listed add - `<h3 class="kiwixHomeBody__results"></h3>` under body tag.
|
||||
- To add language select box add - `<select id="languageFilter"></select>` under body tag.
|
||||
- To add category select box add - `<select id="categoryFilter"></select>` under body tag.
|
||||
- To add search box for books use following form -
|
||||
```
|
||||
<form id='kiwixSearchForm'>
|
||||
<input type="text" name="q" placeholder="Search" id="searchFilter" class='kiwixSearch filter'>
|
||||
<input type="submit" class="kiwixButton" value="Search"/>
|
||||
</form>
|
||||
```
|
||||
|
||||
|
||||
If you compile manually Libmicrohttpd, you might need to compile it
|
||||
without GNU TLS, a bug here will impeach further compilation
|
||||
otherwise.
|
||||
|
||||
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.
|
||||
|
||||
Troubleshooting
|
||||
---------------
|
||||
|
||||
@@ -232,6 +146,12 @@ 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.
|
||||
|
||||
License
|
||||
-------
|
||||
|
||||
|
||||
13
android-kiwix-lib-publisher/.gitignore
vendored
Normal file
13
android-kiwix-lib-publisher/.gitignore
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
*.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
|
||||
25
android-kiwix-lib-publisher/build.gradle
Normal file
25
android-kiwix-lib-publisher/build.gradle
Normal file
@@ -0,0 +1,25 @@
|
||||
// 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
|
||||
}
|
||||
15
android-kiwix-lib-publisher/gradle.properties
Normal file
15
android-kiwix-lib-publisher/gradle.properties
Normal file
@@ -0,0 +1,15 @@
|
||||
# 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
|
||||
BIN
android-kiwix-lib-publisher/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
BIN
android-kiwix-lib-publisher/gradle/wrapper/gradle-wrapper.jar
vendored
Normal file
Binary file not shown.
6
android-kiwix-lib-publisher/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
6
android-kiwix-lib-publisher/gradle/wrapper/gradle-wrapper.properties
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
#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
|
||||
172
android-kiwix-lib-publisher/gradlew
vendored
Executable file
172
android-kiwix-lib-publisher/gradlew
vendored
Executable file
@@ -0,0 +1,172 @@
|
||||
#!/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" "$@"
|
||||
84
android-kiwix-lib-publisher/gradlew.bat
vendored
Executable file
84
android-kiwix-lib-publisher/gradlew.bat
vendored
Executable file
@@ -0,0 +1,84 @@
|
||||
@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
|
||||
1
android-kiwix-lib-publisher/kiwixLibAndroid/.gitignore
vendored
Normal file
1
android-kiwix-lib-publisher/kiwixLibAndroid/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
64
android-kiwix-lib-publisher/kiwixLibAndroid/build.gradle
Normal file
64
android-kiwix-lib-publisher/kiwixLibAndroid/build.gradle
Normal file
@@ -0,0 +1,64 @@
|
||||
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")
|
||||
}
|
||||
|
||||
21
android-kiwix-lib-publisher/kiwixLibAndroid/proguard-rules.pro
vendored
Normal file
21
android-kiwix-lib-publisher/kiwixLibAndroid/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# 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
|
||||
@@ -0,0 +1,10 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
package="org.kiwix.kiwixlib">
|
||||
|
||||
<application
|
||||
android:allowBackup="true"
|
||||
android:supportsRtl="true">
|
||||
|
||||
</application>
|
||||
|
||||
</manifest>
|
||||
1
android-kiwix-lib-publisher/settings.gradle
Normal file
1
android-kiwix-lib-publisher/settings.gradle
Normal file
@@ -0,0 +1 @@
|
||||
include ':kiwixLibAndroid'
|
||||
19
debian/control
vendored
19
debian/control
vendored
@@ -3,31 +3,31 @@ Priority: optional
|
||||
Maintainer: Kiwix team <kiwix@kiwix.org>
|
||||
Build-Depends: debhelper-compat (= 13),
|
||||
meson,
|
||||
pkgconf,
|
||||
libzim-dev (>= 9.0), libzim-dev (<< 10.0),
|
||||
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/libkiwix
|
||||
Homepage: https://github.com/kiwix/kiwix-lib
|
||||
Rules-Requires-Root: no
|
||||
|
||||
Package: libkiwix-dev
|
||||
Section: libdevel
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends: libkiwix14 (= ${binary:Version}), ${misc:Depends}, python3,
|
||||
libzim-dev (>= 9.0), libzim-dev (<< 10.0),
|
||||
Depends: libkiwix10 (= ${binary:Version}), ${misc:Depends}, python3,
|
||||
libzim-dev (>= 6.0.0),
|
||||
libicu-dev,
|
||||
libpugixml-dev,
|
||||
libcurl4-gnutls-dev,
|
||||
libmicrohttpd-dev,
|
||||
zlib1g-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
|
||||
@@ -35,12 +35,11 @@ Description: library of common code for Kiwix (development)
|
||||
.
|
||||
This package contains development files.
|
||||
|
||||
Package: libkiwix14
|
||||
Package: libkiwix10
|
||||
Architecture: any
|
||||
Multi-Arch: same
|
||||
Depends: ${shlibs:Depends}, ${misc:Depends}, aria2
|
||||
Conflicts: libkiwix0, libkiwix3, libkiwix9, libkiwix10, libkiwix11, libkiwix12, libkiwix13
|
||||
Replaces: libkiwix0, libkiwix3, libkiwix9, libkiwix10, libkiwix11, libkiwix12, libkiwix13
|
||||
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
|
||||
|
||||
1
debian/libkiwix-dev.manpages
vendored
1
debian/libkiwix-dev.manpages
vendored
@@ -1,2 +1 @@
|
||||
usr/share/man/man1/kiwix-compile-resources.1*
|
||||
usr/share/man/man1/kiwix-compile-i18n.1*
|
||||
|
||||
2
docs/.gitignore
vendored
2
docs/.gitignore
vendored
@@ -1,2 +0,0 @@
|
||||
api
|
||||
xml
|
||||
68
docs/conf.py
68
docs/conf.py
@@ -1,68 +0,0 @@
|
||||
# Configuration file for the Sphinx documentation builder.
|
||||
#
|
||||
# This file only contains a selection of the most common options. For a full
|
||||
# list see the documentation:
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||
|
||||
# -- Path setup --------------------------------------------------------------
|
||||
|
||||
# If extensions (or modules to document with autodoc) are in another directory,
|
||||
# add these directories to sys.path here. If the directory is relative to the
|
||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||
#
|
||||
import os
|
||||
# import sys
|
||||
# sys.path.insert(0, os.path.abspath('.'))
|
||||
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
|
||||
project = 'libkiwix'
|
||||
copyright = '2022, libkiwix-team'
|
||||
author = 'libkiwix-team'
|
||||
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
||||
# Add any Sphinx extension module names here, as strings. They can be
|
||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||
# ones.
|
||||
extensions = [
|
||||
'breathe',
|
||||
'exhale'
|
||||
]
|
||||
|
||||
# Add any paths that contain templates here, relative to this directory.
|
||||
templates_path = ['_templates']
|
||||
|
||||
# List of patterns, relative to source directory, that match files and
|
||||
# directories to ignore when looking for source files.
|
||||
# This pattern also affects html_static_path and html_extra_path.
|
||||
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
||||
|
||||
html_theme = 'sphinx_rtd_theme'
|
||||
|
||||
# Add any paths that contain custom static files (such as style sheets) here,
|
||||
# relative to this directory. They are copied after the builtin static files,
|
||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||
html_static_path = ['_static']
|
||||
|
||||
breathe_projects = {
|
||||
"libkiwix": "./xml"
|
||||
}
|
||||
breathe_default_project = 'libkiwix'
|
||||
|
||||
exhale_args = {
|
||||
"containmentFolder": "./api",
|
||||
"rootFileName": "ref_api.rst",
|
||||
"rootFileTitle": "Reference API",
|
||||
"doxygenStripFromPath":"..",
|
||||
"treeViewIsBootstrap": True,
|
||||
"createTreeView" : True,
|
||||
"exhaleExecutesDoxygen": True,
|
||||
"exhaleDoxygenStdin": "INPUT = ../include"
|
||||
}
|
||||
|
||||
primary_domain = 'cpp'
|
||||
|
||||
highlight_language = 'cpp'
|
||||
@@ -1,14 +0,0 @@
|
||||
.. libkiwix documentation master file, created by
|
||||
sphinx-quickstart on Fri Jul 24 15:40:50 2020.
|
||||
You can adapt this file completely to your liking, but it should at least
|
||||
contain the root `toctree` directive.
|
||||
|
||||
Welcome to libkiwix's documentation!
|
||||
==================================
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
:caption: Contents:
|
||||
|
||||
usage
|
||||
api/ref_api
|
||||
@@ -1,7 +0,0 @@
|
||||
|
||||
sphinx = find_program('sphinx-build', native:true)
|
||||
|
||||
sphinx_target = run_target('doc',
|
||||
command: [sphinx, '-bhtml',
|
||||
meson.current_source_dir(),
|
||||
meson.current_build_dir()])
|
||||
@@ -1,3 +0,0 @@
|
||||
breathe
|
||||
exhale
|
||||
sphinx_rtd_theme
|
||||
@@ -1,15 +0,0 @@
|
||||
Libkiwix programming
|
||||
====================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
libkiwix is written in C++. To use the library, you need the include files of libkiwix have
|
||||
to link against libzim.
|
||||
|
||||
Errors are handled with exceptions. When something goes wrong, libkiwix throws an error,
|
||||
which is always derived from std::exception.
|
||||
|
||||
All classes are defined in the namespace kiwix.
|
||||
|
||||
libkiwix is a set of tools to manage zim files and provide some common functionnality.
|
||||
36
format_code.sh
Executable file
36
format_code.sh
Executable file
@@ -0,0 +1,36 @@
|
||||
#!/usr/bin/bash
|
||||
|
||||
files=(
|
||||
"include/library.h"
|
||||
"include/common/stringTools.h"
|
||||
"include/common/pathTools.h"
|
||||
"include/common/otherTools.h"
|
||||
"include/common/regexTools.h"
|
||||
"include/common/networkTools.h"
|
||||
"include/manager.h"
|
||||
"include/reader.h"
|
||||
"include/kiwix.h"
|
||||
"include/xapianSearcher.h"
|
||||
"include/searcher.h"
|
||||
"src/library.cpp"
|
||||
"src/android/kiwix.cpp"
|
||||
"src/android/org/kiwix/kiwixlib/JNIKiwixBool.java"
|
||||
"src/android/org/kiwix/kiwixlib/JNIKiwix.java"
|
||||
"src/android/org/kiwix/kiwixlib/JNIKiwixString.java"
|
||||
"src/android/org/kiwix/kiwixlib/JNIKiwixInt.java"
|
||||
"src/searcher.cpp"
|
||||
"src/common/pathTools.cpp"
|
||||
"src/common/regexTools.cpp"
|
||||
"src/common/otherTools.cpp"
|
||||
"src/common/networkTools.cpp"
|
||||
"src/common/stringTools.cpp"
|
||||
"src/xapianSearcher.cpp"
|
||||
"src/manager.cpp"
|
||||
"src/reader.cpp"
|
||||
)
|
||||
|
||||
for i in "${files[@]}"
|
||||
do
|
||||
echo $i
|
||||
clang-format -i -style=file $i
|
||||
done
|
||||
@@ -21,54 +21,28 @@
|
||||
#define KIWIX_BOOK_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include "common.h"
|
||||
|
||||
namespace pugi {
|
||||
class xml_node;
|
||||
}
|
||||
|
||||
namespace zim {
|
||||
class Archive;
|
||||
}
|
||||
|
||||
namespace kiwix
|
||||
{
|
||||
|
||||
class OPDSDumper;
|
||||
class Reader;
|
||||
|
||||
/**
|
||||
* A class to store information about a book (a zim file)
|
||||
*/
|
||||
class Book
|
||||
{
|
||||
public: // types
|
||||
class Illustration
|
||||
{
|
||||
friend class Book;
|
||||
public:
|
||||
uint16_t width = 48;
|
||||
uint16_t height = 48;
|
||||
std::string mimeType;
|
||||
std::string url;
|
||||
|
||||
const std::string& getData() const;
|
||||
|
||||
private:
|
||||
mutable std::string data;
|
||||
mutable std::mutex mutex;
|
||||
};
|
||||
|
||||
typedef std::vector<std::shared_ptr<const Illustration>> Illustrations;
|
||||
|
||||
public: // functions
|
||||
public:
|
||||
Book();
|
||||
~Book();
|
||||
|
||||
bool update(const Book& other);
|
||||
void update(const zim::Archive& archive);
|
||||
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;
|
||||
@@ -79,15 +53,12 @@ class Book
|
||||
bool isPathValid() const { return m_pathValid; }
|
||||
const std::string& getTitle() const { return m_title; }
|
||||
const std::string& getDescription() const { return m_description; }
|
||||
DEPRECATED const std::string& getLanguage() const { return m_language; }
|
||||
const std::string& getCommaSeparatedLanguages() const { return m_language; }
|
||||
const std::vector<std::string> getLanguages() const;
|
||||
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; }
|
||||
std::string getCategory() const;
|
||||
const std::string& getTags() const { return m_tags; }
|
||||
std::string getTagStr(const std::string& tagName) const;
|
||||
bool getTagBool(const std::string& tagName) const;
|
||||
@@ -96,13 +67,9 @@ class Book
|
||||
const uint64_t& getArticleCount() const { return m_articleCount; }
|
||||
const uint64_t& getMediaCount() const { return m_mediaCount; }
|
||||
const uint64_t& getSize() const { return m_size; }
|
||||
DEPRECATED const std::string& getFavicon() const;
|
||||
DEPRECATED const std::string& getFaviconUrl() const;
|
||||
DEPRECATED const std::string& getFaviconMimeType() const;
|
||||
|
||||
Illustrations getIllustrations() const;
|
||||
std::shared_ptr<const Illustration> getIllustration(unsigned int size) const;
|
||||
|
||||
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; }
|
||||
@@ -123,20 +90,17 @@ class Book
|
||||
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; }
|
||||
|
||||
private: // functions
|
||||
std::string getCategoryFromTags() const;
|
||||
const Illustration& getDefaultIllustration() const;
|
||||
|
||||
protected: // data
|
||||
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_category;
|
||||
std::string m_language;
|
||||
std::string m_creator;
|
||||
std::string m_publisher;
|
||||
@@ -150,11 +114,9 @@ class Book
|
||||
uint64_t m_mediaCount = 0;
|
||||
bool m_readOnly = false;
|
||||
uint64_t m_size = 0;
|
||||
Illustrations m_illustrations;
|
||||
|
||||
// Used as the return value of getDefaultIllustration() when no default
|
||||
// illustration is found in the book
|
||||
static const Illustration missingDefaultIllustration;
|
||||
mutable std::string m_favicon;
|
||||
std::string m_faviconUrl;
|
||||
std::string m_faviconMimeType;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@@ -29,33 +29,19 @@ class xml_node;
|
||||
namespace kiwix
|
||||
{
|
||||
|
||||
class Book;
|
||||
/**
|
||||
* A class to store information about a bookmark (an article in a book)
|
||||
*/
|
||||
class Bookmark
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Create an empty bookmark.
|
||||
*
|
||||
* Bookmark must be populated with `set*` methods
|
||||
*/
|
||||
Bookmark();
|
||||
|
||||
/**
|
||||
* Create a bookmark given a Book, a path and a title.
|
||||
*/
|
||||
Bookmark(const Book& book, const std::string& path, const std::string& title);
|
||||
|
||||
~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& getBookName() const { return m_bookName; }
|
||||
const std::string& getBookFlavour() const { return m_bookFlavour; }
|
||||
const std::string& getUrl() const { return m_url; }
|
||||
const std::string& getTitle() const { return m_title; }
|
||||
const std::string& getLanguage() const { return m_language; }
|
||||
@@ -63,8 +49,6 @@ class Bookmark
|
||||
|
||||
void setBookId(const std::string& bookId) { m_bookId = bookId; }
|
||||
void setBookTitle(const std::string& bookTitle) { m_bookTitle = bookTitle; }
|
||||
void setBookName(const std::string& bookName) { m_bookName = bookName; }
|
||||
void setBookFlavour(const std::string& bookFlavour) { m_bookFlavour = bookFlavour; }
|
||||
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; }
|
||||
@@ -73,8 +57,6 @@ class Bookmark
|
||||
protected:
|
||||
std::string m_bookId;
|
||||
std::string m_bookTitle;
|
||||
std::string m_bookName;
|
||||
std::string m_bookFlavour;
|
||||
std::string m_url;
|
||||
std::string m_title;
|
||||
std::string m_language;
|
||||
|
||||
@@ -16,7 +16,6 @@
|
||||
|
||||
namespace kiwix {
|
||||
|
||||
enum class IpMode { IPV4, IPV6, ALL, AUTO }; // AUTO: Server decides the protocol
|
||||
typedef zim::size_type size_type;
|
||||
typedef zim::offset_type offset_type;
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <stdexcept>
|
||||
#include <mutex>
|
||||
|
||||
namespace kiwix
|
||||
{
|
||||
@@ -44,14 +43,6 @@ class AriaError : public std::runtime_error {
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* A representation of a current download.
|
||||
*
|
||||
* `Download` is not thread safe. User must care to not call method on a
|
||||
* same download from different threads.
|
||||
* However, it is safe to use different `Download`s from different threads.
|
||||
*/
|
||||
|
||||
class Download {
|
||||
public:
|
||||
typedef enum { K_ACTIVE, K_WAITING, K_PAUSED, K_ERROR, K_COMPLETE, K_REMOVED, K_UNKNOWN } StatusResult;
|
||||
@@ -62,89 +53,19 @@ class Download {
|
||||
: mp_aria(p_aria),
|
||||
m_status(K_UNKNOWN),
|
||||
m_did(did) {};
|
||||
|
||||
/**
|
||||
* Update the status of the download.
|
||||
*
|
||||
* This call make an aria rpc call and is blocking.
|
||||
* Some download (started with a metalink) are in fact several downloads.
|
||||
* - A first one to download the metadlink.
|
||||
* - A second one to download the real file.
|
||||
*
|
||||
* If `follow` is true, updateStatus tries to detect that and tracks
|
||||
* the second download when the first one is finished.
|
||||
* By passing false to `follow`, `Download` will only track the first download.
|
||||
*
|
||||
* `getFoo` methods are based on the last statusUpdate.
|
||||
*
|
||||
* @param follow: Do we have to follow following downloads.
|
||||
*/
|
||||
void updateStatus(bool follow);
|
||||
|
||||
/**
|
||||
* Pause the download (and call updateStatus)
|
||||
*/
|
||||
void updateStatus(bool follow=false);
|
||||
void pauseDownload();
|
||||
|
||||
/**
|
||||
* Resume the download (and call updateStatus)
|
||||
*/
|
||||
void resumeDownload();
|
||||
|
||||
/**
|
||||
* Cancel the download.
|
||||
*
|
||||
* A canceled downlod cannot be resume and updateStatus does nothing.
|
||||
* However, you can still get information based on the last known information.
|
||||
*/
|
||||
void cancelDownload();
|
||||
|
||||
/*
|
||||
* Get the status of the download.
|
||||
*/
|
||||
StatusResult getStatus() const { return m_status; }
|
||||
|
||||
/*
|
||||
* Get the id of the download.
|
||||
*/
|
||||
const std::string& getDid() const { return m_did; }
|
||||
|
||||
/*
|
||||
* Get the id of the "second" download.
|
||||
*
|
||||
* Set only if the "first" download is a metalink and is complete.
|
||||
*/
|
||||
const std::string& getFollowedBy() const { return m_followedBy; }
|
||||
|
||||
/*
|
||||
* Get the total length of the download.
|
||||
*/
|
||||
uint64_t getTotalLength() const { return m_totalLength; }
|
||||
|
||||
/*
|
||||
* Get the completed length of the download.
|
||||
*/
|
||||
uint64_t getCompletedLength() const { return m_completedLength; }
|
||||
|
||||
/*
|
||||
* Get the download speed of the download.
|
||||
*/
|
||||
uint64_t getDownloadSpeed() const { return m_downloadSpeed; }
|
||||
|
||||
/*
|
||||
* Get the verified length of the download.
|
||||
*/
|
||||
uint64_t getVerifiedLength() const { return m_verifiedLength; }
|
||||
|
||||
/*
|
||||
* Get the path (local file) of the download.
|
||||
*/
|
||||
const std::string& getPath() const { return m_path; }
|
||||
|
||||
/*
|
||||
* Get the download uris of the download.
|
||||
*/
|
||||
const std::vector<std::string>& getUris() const { return m_uris; }
|
||||
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;
|
||||
@@ -162,69 +83,23 @@ class Download {
|
||||
/**
|
||||
* A tool to download things.
|
||||
*
|
||||
* A Downloader manages `Download` using aria2 in the background.
|
||||
* `Downloader` is threadsafe.
|
||||
* However, the returned `Download`s are NOT threadsafe.
|
||||
*/
|
||||
class Downloader
|
||||
{
|
||||
public: // types
|
||||
typedef std::vector<std::pair<std::string, std::string>> Options;
|
||||
|
||||
public: // functions
|
||||
/*
|
||||
* Create a new Downloader object.
|
||||
*
|
||||
* @param sessionFileDir: The directory where aria2 will store its session file.
|
||||
*/
|
||||
explicit Downloader(std::string sessionFileDir);
|
||||
public:
|
||||
Downloader();
|
||||
virtual ~Downloader();
|
||||
|
||||
void close();
|
||||
|
||||
/**
|
||||
* Start a new download.
|
||||
*
|
||||
* This method is thread safe and returns a pointer to a newly created
|
||||
* `Download` or an existing one with a matching URI. In the latter case
|
||||
* the options parameter is ignored, which can lead to surprising results.
|
||||
* For example, if the old and new download requests (sharing the same URI)
|
||||
* have different values for the download directory or output file name
|
||||
* options, after the download is reported to be complete the downloaded file
|
||||
* will be present only at the location specified for the first request.
|
||||
*
|
||||
* User should call `update` on the returned `Download` to have an accurate status.
|
||||
*
|
||||
* @param uri: The uri of the thing to download.
|
||||
* @param downloadDir: The download directory where the thing should be stored (takes precedence over any "dir" in `options`).
|
||||
* @param options: A series of pair <option_name, option_value> to pass to aria.
|
||||
* @return: The newly created Download.
|
||||
*/
|
||||
std::shared_ptr<Download> startDownload(const std::string& uri, const std::string& downloadDir, Options options = {});
|
||||
Download* startDownload(const std::string& uri, const std::vector<std::pair<std::string, std::string>>& options = {});
|
||||
Download* getDownload(const std::string& did);
|
||||
|
||||
/**
|
||||
* Get a download corrsponding to a download id (did)
|
||||
* User should call `update` on the returned `Download` to have an accurate status.
|
||||
*
|
||||
* @param did: The download id to search for.
|
||||
* @return: The Download corresponding to did.
|
||||
* @throw: Throw std::out_of_range if did is not found.
|
||||
*/
|
||||
std::shared_ptr<Download> getDownload(const std::string& did);
|
||||
size_t getNbDownload() { return m_knownDownloads.size(); }
|
||||
std::vector<std::string> getDownloadIds();
|
||||
|
||||
/**
|
||||
* Get the number of downloads currently managed.
|
||||
*/
|
||||
size_t getNbDownload() const;
|
||||
|
||||
/**
|
||||
* Get the ids of the managed downloads.
|
||||
*/
|
||||
std::vector<std::string> getDownloadIds() const;
|
||||
|
||||
private: // data
|
||||
mutable std::mutex m_lock;
|
||||
std::map<std::string, std::shared_ptr<Download>> m_knownDownloads;
|
||||
private:
|
||||
std::map<std::string, std::unique_ptr<Download>> m_knownDownloads;
|
||||
std::shared_ptr<Aria2> mp_aria;
|
||||
};
|
||||
}
|
||||
|
||||
183
include/entry.h
Normal file
183
include/entry.h
Normal file
@@ -0,0 +1,183 @@
|
||||
/*
|
||||
* 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
|
||||
@@ -1,92 +0,0 @@
|
||||
/*
|
||||
* Copyright 2024 Veloman Yunkan <veloman.yunkan@gmail.com>
|
||||
*
|
||||
* 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_I18N
|
||||
#define KIWIX_I18N
|
||||
|
||||
#include <map>
|
||||
#include <string>
|
||||
|
||||
namespace kiwix
|
||||
{
|
||||
|
||||
std::string getTranslatedString(const std::string& lang, const std::string& key);
|
||||
|
||||
namespace i18n
|
||||
{
|
||||
|
||||
typedef std::map<std::string, std::string> Parameters;
|
||||
|
||||
std::string expandParameterizedString(const std::string& lang,
|
||||
const std::string& key,
|
||||
const Parameters& params);
|
||||
|
||||
class GetTranslatedString
|
||||
{
|
||||
public:
|
||||
explicit GetTranslatedString(const std::string& lang) : m_lang(lang) {}
|
||||
|
||||
std::string operator()(const std::string& key) const
|
||||
{
|
||||
return getTranslatedString(m_lang, key);
|
||||
}
|
||||
|
||||
std::string operator()(const std::string& key, const Parameters& params) const
|
||||
{
|
||||
return expandParameterizedString(m_lang, key, params);
|
||||
}
|
||||
|
||||
private:
|
||||
const std::string m_lang;
|
||||
};
|
||||
|
||||
} // namespace i18n
|
||||
|
||||
class ParameterizedMessage
|
||||
{
|
||||
public: // types
|
||||
typedef i18n::Parameters Parameters;
|
||||
|
||||
public: // functions
|
||||
ParameterizedMessage(const std::string& msgId, const Parameters& params)
|
||||
: msgId(msgId)
|
||||
, params(params)
|
||||
{}
|
||||
|
||||
std::string getText(const std::string& lang) const;
|
||||
|
||||
const std::string& getMsgId() const { return msgId; }
|
||||
const Parameters& getParams() const { return params; }
|
||||
|
||||
private: // data
|
||||
const std::string msgId;
|
||||
const Parameters params;
|
||||
};
|
||||
|
||||
inline ParameterizedMessage nonParameterizedMessage(const std::string& msgId)
|
||||
{
|
||||
const ParameterizedMessage::Parameters noParams;
|
||||
return ParameterizedMessage(msgId, noParams);
|
||||
}
|
||||
|
||||
std::string translateBookCategory(const std::string& lang, const std::string& category);
|
||||
|
||||
} // namespace kiwix
|
||||
|
||||
#endif // KIWIX_I18N
|
||||
@@ -22,4 +22,4 @@
|
||||
|
||||
#include "library.h"
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -24,9 +24,6 @@
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <zim/archive.h>
|
||||
#include <zim/search.h>
|
||||
|
||||
#include "book.h"
|
||||
#include "bookmark.h"
|
||||
@@ -34,15 +31,10 @@
|
||||
|
||||
#define KIWIX_LIBRARY_VERSION "20110515"
|
||||
|
||||
namespace Xapian {
|
||||
class WritableDatabase;
|
||||
};
|
||||
|
||||
namespace kiwix
|
||||
{
|
||||
|
||||
class OPDSDumper;
|
||||
class Library;
|
||||
|
||||
enum supportedListSortBy { UNSORTED, TITLE, SIZE, DATE, CREATOR, PUBLISHER };
|
||||
enum supportedListMode {
|
||||
@@ -55,41 +47,19 @@ enum supportedListMode {
|
||||
NOVALID = 1 << 5
|
||||
};
|
||||
|
||||
enum MigrationMode {
|
||||
/** When migrating bookmarks, do not allow to migrate to an older book than the currently pointed one
|
||||
* (or date stored in the bookmark if book is invalid)
|
||||
*
|
||||
* If no newer books are found, no upgrade is made.
|
||||
*/
|
||||
UPGRADE_ONLY = 0,
|
||||
|
||||
/** Try hard to do a migration. This mostly does:
|
||||
* - Try to find a newer book.
|
||||
* - If book is invalid: find a best book, potentially older.
|
||||
* Older book will never be returned if current book is a valid one.
|
||||
*/
|
||||
ALLOW_DOWNGRADE = 1,
|
||||
};
|
||||
|
||||
class Filter {
|
||||
public: // types
|
||||
using Tags = std::vector<std::string>;
|
||||
|
||||
private: // data
|
||||
private:
|
||||
uint64_t activeFilters;
|
||||
Tags _acceptTags;
|
||||
Tags _rejectTags;
|
||||
std::string _category;
|
||||
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;
|
||||
bool _queryIsPartial;
|
||||
std::string _name;
|
||||
std::string _flavour;
|
||||
|
||||
public: // functions
|
||||
public:
|
||||
Filter();
|
||||
~Filter() = default;
|
||||
|
||||
@@ -123,129 +93,33 @@ class Filter {
|
||||
/**
|
||||
* Set the filter to only accept book with corresponding tag.
|
||||
*/
|
||||
Filter& acceptTags(const Tags& tags);
|
||||
Filter& rejectTags(const Tags& tags);
|
||||
Filter& acceptTags(std::vector<std::string> tags);
|
||||
Filter& rejectTags(std::vector<std::string> tags);
|
||||
|
||||
/**
|
||||
* Set the filter to only accept books in the specified category.
|
||||
*
|
||||
* Multiple categories can be specified as a comma-separated list (in
|
||||
* which case a book in any of those categories will match).
|
||||
*/
|
||||
Filter& category(std::string category);
|
||||
|
||||
/**
|
||||
* Set the filter to only accept books in the specified language.
|
||||
*
|
||||
* Multiple languages can be specified as a comma-separated list (in
|
||||
* which case a book in any of those languages will match).
|
||||
*/
|
||||
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, bool partial=true);
|
||||
Filter& query(std::string query);
|
||||
Filter& name(std::string name);
|
||||
Filter& flavour(std::string flavour);
|
||||
Filter& clearLang();
|
||||
Filter& clearCategory();
|
||||
|
||||
bool hasQuery() const;
|
||||
const std::string& getQuery() const { return _query; }
|
||||
bool queryIsPartial() const { return _queryIsPartial; }
|
||||
|
||||
bool hasName() const;
|
||||
const std::string& getName() const { return _name; }
|
||||
|
||||
bool hasCategory() const;
|
||||
const std::string& getCategory() const { return _category; }
|
||||
|
||||
bool hasLang() const;
|
||||
const std::string& getLang() const { return _lang; }
|
||||
|
||||
bool hasPublisher() const;
|
||||
const std::string& getPublisher() const { return _publisher; }
|
||||
|
||||
bool hasCreator() const;
|
||||
const std::string& getCreator() const { return _creator; }
|
||||
|
||||
bool hasFlavour() const;
|
||||
const std::string& getFlavour() const { return _flavour; }
|
||||
|
||||
const Tags& getAcceptTags() const { return _acceptTags; }
|
||||
const Tags& getRejectTags() const { return _rejectTags; }
|
||||
|
||||
private: // functions
|
||||
friend class Library;
|
||||
|
||||
bool accept(const Book& book) const;
|
||||
};
|
||||
|
||||
|
||||
class ZimSearcher : public zim::Searcher
|
||||
{
|
||||
public:
|
||||
explicit ZimSearcher(zim::Searcher&& searcher)
|
||||
: zim::Searcher(searcher)
|
||||
{}
|
||||
|
||||
std::unique_lock<std::mutex> getLock() {
|
||||
return std::unique_lock<std::mutex>(m_mutex);
|
||||
}
|
||||
virtual ~ZimSearcher() = default;
|
||||
private:
|
||||
std::mutex m_mutex;
|
||||
};
|
||||
|
||||
template<typename, typename>
|
||||
class ConcurrentCache;
|
||||
|
||||
template<typename, typename>
|
||||
class MultiKeyCache;
|
||||
|
||||
using LibraryPtr = std::shared_ptr<Library>;
|
||||
using ConstLibraryPtr = std::shared_ptr<const Library>;
|
||||
|
||||
|
||||
// Some compiler we use don't have [[nodiscard]] attribute.
|
||||
// We don't want to declare `create` with it in this case.
|
||||
#define LIBKIWIX_NODISCARD
|
||||
#if defined __has_cpp_attribute
|
||||
#if __has_cpp_attribute (nodiscard)
|
||||
#undef LIBKIWIX_NODISCARD
|
||||
#define LIBKIWIX_NODISCARD [[nodiscard]]
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/**
|
||||
* A Library store several books.
|
||||
*/
|
||||
class Library: public std::enable_shared_from_this<Library>
|
||||
class Library
|
||||
{
|
||||
public:
|
||||
typedef uint64_t Revision;
|
||||
typedef std::vector<std::string> BookIdCollection;
|
||||
typedef std::map<std::string, int> AttributeCounts;
|
||||
typedef std::set<std::string> BookIdSet;
|
||||
std::map<std::string, kiwix::Book> m_books;
|
||||
std::map<std::string, std::shared_ptr<Reader>> m_readers;
|
||||
std::vector<kiwix::Bookmark> m_bookmarks;
|
||||
|
||||
private:
|
||||
public:
|
||||
Library();
|
||||
|
||||
public:
|
||||
LIBKIWIX_NODISCARD static LibraryPtr create() {
|
||||
return LibraryPtr(new Library());
|
||||
}
|
||||
~Library();
|
||||
|
||||
/**
|
||||
* Library is not a copiable object. However it can be moved.
|
||||
*/
|
||||
Library(const Library& ) = delete;
|
||||
Library(Library&& ) = delete;
|
||||
void operator=(const Library& ) = delete;
|
||||
Library& operator=(Library&& ) = delete;
|
||||
|
||||
/**
|
||||
* Add a book to the library.
|
||||
*
|
||||
@@ -258,11 +132,6 @@ class Library: public std::enable_shared_from_this<Library>
|
||||
*/
|
||||
bool addBook(const Book& book);
|
||||
|
||||
/**
|
||||
* A self-explanatory alias for addBook()
|
||||
*/
|
||||
bool addOrUpdateBook(const Book& book) { return addBook(book); }
|
||||
|
||||
/**
|
||||
* Add a bookmark to the library.
|
||||
*
|
||||
@@ -271,7 +140,7 @@ class Library: public std::enable_shared_from_this<Library>
|
||||
void addBookmark(const Bookmark& bookmark);
|
||||
|
||||
/**
|
||||
* Remove a bookmark
|
||||
* Remove a bookmarkk
|
||||
*
|
||||
* @param zimId The zimId of the bookmark.
|
||||
* @param url The url of the bookmark.
|
||||
@@ -279,78 +148,9 @@ class Library: public std::enable_shared_from_this<Library>
|
||||
*/
|
||||
bool removeBookmark(const std::string& zimId, const std::string& url);
|
||||
|
||||
/**
|
||||
* Migrate all invalid bookmarks.
|
||||
*
|
||||
* All invalid bookmarks (ie pointing to unknown books, no check is made on bookmark pointing to
|
||||
* invalid articles of valid book) will be migrated (if possible) to a better book.
|
||||
* "Better book", will be determined using method `getBestTargetBookId`.
|
||||
*
|
||||
* @return A tuple<int, int>: <The number of bookmarks updated>, <Number of invalid bookmarks before migration was performed>.
|
||||
*/
|
||||
std::tuple<int, int> migrateBookmarks(MigrationMode migrationMode = ALLOW_DOWNGRADE);
|
||||
|
||||
/**
|
||||
* Migrate all bookmarks associated to a specific book.
|
||||
*
|
||||
* All bookmarks associated to `sourceBookId` book will be migrated to a better book.
|
||||
* "Better book", will be determined using method `getBestTargetBookId`.
|
||||
*
|
||||
* @param sourceBookId the source bookId of the bookmarks to migrate.
|
||||
* @param migrationMode how we will find the best book.
|
||||
* @return The number of bookmarks updated.
|
||||
*/
|
||||
int migrateBookmarks(const std::string& sourceBookId, MigrationMode migrationMode = UPGRADE_ONLY);
|
||||
|
||||
/**
|
||||
* Migrate bookmarks
|
||||
*
|
||||
* Migrate all bookmarks pointing to `source` to `destination`.
|
||||
*
|
||||
* @param sourceBookId the source bookId of the bookmarks to migrate.
|
||||
* @param targetBookId the destination bookId to migrate the bookmarks to.
|
||||
* @return The number of bookmarks updated.
|
||||
*/
|
||||
int migrateBookmarks(const std::string& sourceBookId, const std::string& targetBookId);
|
||||
|
||||
/**
|
||||
* Get the best available bookId for a bookmark.
|
||||
*
|
||||
* Given a bookmark, return the best available bookId.
|
||||
* "best available bookId" is determined using heuristitcs based on book name, flavour and date.
|
||||
*
|
||||
* @param bookmark The bookmark to search the bookId for.
|
||||
* @param migrationMode The migration mode to use.
|
||||
* @return A bookId. Potentially empty string if no suitable book found.
|
||||
*/
|
||||
std::string getBestTargetBookId(const Bookmark& bookmark, MigrationMode migrationMode) const;
|
||||
|
||||
/**
|
||||
* Get the best bookId for a combination of book's name, flavour and date.
|
||||
*
|
||||
* Given a bookName (mandatory), try to find the best book.
|
||||
* If preferedFlavour is given, will try to find a book with the same flavour. If not found, return a book with a different flavour.
|
||||
* If minDate is given, return a book newer than minDate. If not found, return a empty bookId.
|
||||
*
|
||||
* @param bookName The name of the book
|
||||
* @param preferedFlavour The prefered flavour.
|
||||
* @param minDate the minimal book date acceptable. Must be a string in the format "YYYY-MM-DD".
|
||||
* @return A bookId corresponding to the query, or empty string if not found.
|
||||
*/
|
||||
std::string getBestTargetBookId(const std::string& bookName, const std::string& preferedFlavour="", const std::string& minDate="") const;
|
||||
|
||||
// XXX: This is a non-thread-safe operation
|
||||
const Book& getBookById(const std::string& id) const;
|
||||
// XXX: This is a non-thread-safe operation
|
||||
const Book& getBookByPath(const std::string& path) const;
|
||||
|
||||
Book getBookByIdThreadSafe(const std::string& id) const;
|
||||
|
||||
std::shared_ptr<zim::Archive> getArchiveById(const std::string& id);
|
||||
std::shared_ptr<ZimSearcher> getSearcherById(const std::string& id) {
|
||||
return getSearcherByIds(BookIdSet{id});
|
||||
}
|
||||
std::shared_ptr<ZimSearcher> getSearcherByIds(const BookIdSet& ids);
|
||||
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.
|
||||
@@ -366,7 +166,7 @@ class Library: public std::enable_shared_from_this<Library>
|
||||
* @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) const;
|
||||
bool writeToFile(const std::string& path);
|
||||
|
||||
/**
|
||||
* Write the library bookmarks to a file.
|
||||
@@ -374,7 +174,7 @@ class Library: public std::enable_shared_from_this<Library>
|
||||
* @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) const;
|
||||
bool writeBookmarksToFile(const std::string& path);
|
||||
|
||||
/**
|
||||
* Get the number of book in the library.
|
||||
@@ -383,56 +183,53 @@ class Library: public std::enable_shared_from_this<Library>
|
||||
* @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) const;
|
||||
unsigned int getBookCount(const bool localBooks, const bool remoteBooks);
|
||||
|
||||
/**
|
||||
* Get all languagues of the books in the library.
|
||||
* Get all langagues of the books in the library.
|
||||
*
|
||||
* @return A list of languages.
|
||||
*/
|
||||
std::vector<std::string> getBooksLanguages() const;
|
||||
|
||||
/**
|
||||
* Get all languagues of the books in the library with counts.
|
||||
*
|
||||
* @return A list of languages with the count of books in each language.
|
||||
*/
|
||||
AttributeCounts getBooksLanguagesWithCounts() const;
|
||||
|
||||
/**
|
||||
* Get all categories of the books in the library.
|
||||
*
|
||||
* @return A list of categories.
|
||||
*/
|
||||
std::vector<std::string> getBooksCategories() const;
|
||||
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() const;
|
||||
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() const;
|
||||
std::vector<std::string> getBooksPublishers();
|
||||
|
||||
/**
|
||||
* Get all bookmarks.
|
||||
*
|
||||
* @return A list of bookmarks
|
||||
*/
|
||||
const std::vector<kiwix::Bookmark> getBookmarks(bool onlyValidBookmarks = true) const;
|
||||
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.
|
||||
*/
|
||||
BookIdCollection getBooksIds() const;
|
||||
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.
|
||||
@@ -440,7 +237,7 @@ class Library: public std::enable_shared_from_this<Library>
|
||||
* @param filter The filter to use.
|
||||
* @return The list of bookIds corresponding to the filter.
|
||||
*/
|
||||
BookIdCollection filter(const Filter& filter) const;
|
||||
std::vector<std::string> filter(const Filter& filter);
|
||||
|
||||
|
||||
/**
|
||||
@@ -450,62 +247,43 @@ class Library: public std::enable_shared_from_this<Library>
|
||||
* @param comparator how to sort the books
|
||||
* @return The sorted list of books
|
||||
*/
|
||||
void sort(BookIdCollection& bookIds, supportedListSortBy sortBy, bool ascending) const;
|
||||
void sort(std::vector<std::string>& bookIds, supportedListSortBy sortBy, bool ascending);
|
||||
|
||||
/**
|
||||
* Return the current revision of the library.
|
||||
* List books in the library.
|
||||
*
|
||||
* The revision of the library is updated (incremented by one) by
|
||||
* the addBook() and removeBookById() operations.
|
||||
*
|
||||
* @return Current revision of 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.
|
||||
*/
|
||||
Revision getRevision() const;
|
||||
|
||||
/**
|
||||
* Remove books that have not been updated since the specified revision.
|
||||
*
|
||||
* @param rev the library revision to use
|
||||
* @return Count of books that were removed by this operation.
|
||||
*/
|
||||
uint32_t removeBooksNotUpdatedSince(Revision rev);
|
||||
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;
|
||||
|
||||
private: // types
|
||||
typedef const std::string& (Book::*BookStrPropMemFn)() const;
|
||||
struct Entry : Book
|
||||
{
|
||||
Library::Revision lastUpdatedRevision = 0;
|
||||
};
|
||||
|
||||
private: // functions
|
||||
AttributeCounts getBookAttributeCounts(BookStrPropMemFn p) const;
|
||||
std::vector<std::string> getBookPropValueSet(BookStrPropMemFn p) const;
|
||||
BookIdCollection filterViaBookDB(const Filter& filter) const;
|
||||
std::string getBestFromBookCollection(BookIdCollection books, const Bookmark& bookmark, MigrationMode migrationMode) const;
|
||||
unsigned int getBookCount_not_protected(const bool localBooks, const bool remoteBooks) const;
|
||||
void updateBookDB(const Book& book);
|
||||
void dropCache(const std::string& bookId);
|
||||
|
||||
private: //data
|
||||
mutable std::recursive_mutex m_mutex;
|
||||
Library::Revision m_revision;
|
||||
std::map<std::string, Entry> m_books;
|
||||
using ArchiveCache = ConcurrentCache<std::string, std::shared_ptr<zim::Archive>>;
|
||||
std::unique_ptr<ArchiveCache> mp_archiveCache;
|
||||
using SearcherCache = MultiKeyCache<std::string, std::shared_ptr<ZimSearcher>>;
|
||||
std::unique_ptr<SearcherCache> mp_searcherCache;
|
||||
std::vector<kiwix::Bookmark> m_bookmarks;
|
||||
std::unique_ptr<Xapian::WritableDatabase> m_bookDB;
|
||||
};
|
||||
|
||||
// We don't need it anymore and we don't want to polute any other potential usage
|
||||
// of `LIBKIWIX_NODISCARD` token.
|
||||
#undef LIBKIWIX_NODISCARD
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -38,7 +38,7 @@ class LibXMLDumper
|
||||
{
|
||||
public:
|
||||
LibXMLDumper() = default;
|
||||
LibXMLDumper(const Library* library);
|
||||
LibXMLDumper(Library* library);
|
||||
~LibXMLDumper();
|
||||
|
||||
/**
|
||||
@@ -69,10 +69,10 @@ class LibXMLDumper
|
||||
*
|
||||
* @param library The library to dump.
|
||||
*/
|
||||
void setLibrary(const Library* library) { this->library = library; }
|
||||
void setLibrary(Library* library) { this->library = library; }
|
||||
|
||||
protected:
|
||||
const kiwix::Library* library;
|
||||
kiwix::Library* library;
|
||||
std::string baseDir;
|
||||
private:
|
||||
void handleBook(Book book, pugi::xml_node root_node);
|
||||
@@ -22,10 +22,10 @@
|
||||
|
||||
#include "book.h"
|
||||
#include "library.h"
|
||||
#include "reader.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <memory>
|
||||
|
||||
namespace pugi {
|
||||
class xml_document;
|
||||
@@ -34,25 +34,26 @@ class xml_document;
|
||||
namespace kiwix
|
||||
{
|
||||
|
||||
class LibraryManipulator
|
||||
{
|
||||
public: // functions
|
||||
explicit LibraryManipulator(LibraryPtr library);
|
||||
virtual ~LibraryManipulator();
|
||||
class LibraryManipulator {
|
||||
public:
|
||||
virtual ~LibraryManipulator() {}
|
||||
virtual bool addBookToLibrary(Book book) = 0;
|
||||
virtual void addBookmarkToLibrary(Bookmark bookmark) = 0;
|
||||
};
|
||||
|
||||
LibraryPtr getLibrary() const { return library; }
|
||||
|
||||
bool addBookToLibrary(const Book& book);
|
||||
void addBookmarkToLibrary(const Bookmark& bookmark);
|
||||
uint32_t removeBooksNotUpdatedSince(Library::Revision rev);
|
||||
|
||||
protected: // overrides
|
||||
virtual void bookWasAddedToLibrary(const Book& book);
|
||||
virtual void bookmarkWasAddedToLibrary(const Bookmark& bookmark);
|
||||
virtual void booksWereRemovedFromLibrary();
|
||||
|
||||
private: // data
|
||||
LibraryPtr library;
|
||||
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;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -60,12 +61,10 @@ class LibraryManipulator
|
||||
*/
|
||||
class Manager
|
||||
{
|
||||
public: // types
|
||||
typedef std::vector<std::string> Paths;
|
||||
|
||||
public: // functions
|
||||
explicit Manager(LibraryManipulator manipulator);
|
||||
explicit Manager(LibraryPtr library);
|
||||
public:
|
||||
Manager(LibraryManipulator* manipulator);
|
||||
Manager(Library* library);
|
||||
~Manager();
|
||||
|
||||
/**
|
||||
* Read a `library.xml` and add book in the file to the library.
|
||||
@@ -73,22 +72,10 @@ class Manager
|
||||
* @param path The (utf8) path to the `library.xml`.
|
||||
* @param readOnly Set if the libray path could be overwritten latter with
|
||||
* updated content.
|
||||
* @param trustLibrary use book metadata coming from XML.
|
||||
* @return True if file has been properly parsed.
|
||||
*/
|
||||
bool readFile(const std::string& path, bool readOnly = true, bool trustLibrary = true);
|
||||
|
||||
/**
|
||||
* Sync the contents of the library with one or more `library.xml` files.
|
||||
*
|
||||
* The metadata of the library files is trusted unconditionally.
|
||||
* Any books not present in the input library.xml files are removed
|
||||
* from the library.
|
||||
*
|
||||
* @param paths The (utf8) paths to the `library.xml` files.
|
||||
*/
|
||||
void reload(const Paths& paths);
|
||||
|
||||
/**
|
||||
* Load a library content store in the string.
|
||||
*
|
||||
@@ -155,15 +142,6 @@ class Manager
|
||||
const std::string& url = "",
|
||||
const bool checkMetaData = false);
|
||||
|
||||
/**
|
||||
* Add all books from the directory tree into the library.
|
||||
*
|
||||
* @param path The path of the directory to scan.
|
||||
* @param verboseFlag Verbose logs flag.
|
||||
*/
|
||||
void addBooksFromDirectory(const std::string& path,
|
||||
const bool verboseFlag = false);
|
||||
|
||||
std::string writableLibraryPath;
|
||||
|
||||
bool m_hasSearchResult = false;
|
||||
@@ -172,7 +150,8 @@ class Manager
|
||||
uint64_t m_itemsPerPage = 0;
|
||||
|
||||
protected:
|
||||
kiwix::LibraryManipulator manipulator;
|
||||
kiwix::LibraryManipulator* manipulator;
|
||||
bool mustDeleteManipulator;
|
||||
|
||||
bool readBookFromPath(const std::string& path, Book* book);
|
||||
bool parseXmlDom(const pugi::xml_document& doc,
|
||||
|
||||
@@ -4,15 +4,27 @@ headers = [
|
||||
'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',
|
||||
'spelling_correction.h',
|
||||
'kiwixserve.h',
|
||||
'name_mapper.h',
|
||||
'tools.h',
|
||||
'version.h',
|
||||
'i18n.h'
|
||||
'name_mapper.h'
|
||||
]
|
||||
|
||||
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'
|
||||
)
|
||||
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
|
||||
namespace kiwix
|
||||
{
|
||||
@@ -33,15 +31,15 @@ class Library;
|
||||
class NameMapper {
|
||||
public:
|
||||
virtual ~NameMapper() = default;
|
||||
virtual std::string getNameForId(const std::string& id) const = 0;
|
||||
virtual std::string getIdForName(const std::string& name) const = 0;
|
||||
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) const { return id; };
|
||||
virtual std::string getIdForName(const std::string& name) const { return name; };
|
||||
virtual std::string getNameForId(const std::string& id) { return id; };
|
||||
virtual std::string getIdForName(const std::string& name) { return name; };
|
||||
};
|
||||
|
||||
class HumanReadableNameMapper : public NameMapper {
|
||||
@@ -50,34 +48,13 @@ class HumanReadableNameMapper : public NameMapper {
|
||||
std::map<std::string, std::string> m_nameToId;
|
||||
|
||||
public:
|
||||
HumanReadableNameMapper(const kiwix::Library& library, bool withAlias);
|
||||
HumanReadableNameMapper(kiwix::Library& library, bool withAlias);
|
||||
virtual ~HumanReadableNameMapper() = default;
|
||||
virtual std::string getNameForId(const std::string& id) const;
|
||||
virtual std::string getIdForName(const std::string& name) const;
|
||||
|
||||
private:
|
||||
void mapName(const kiwix::Library& lib, std::string name, std::string id);
|
||||
virtual std::string getNameForId(const std::string& id);
|
||||
virtual std::string getIdForName(const std::string& name);
|
||||
};
|
||||
|
||||
class UpdatableNameMapper : public NameMapper {
|
||||
typedef std::shared_ptr<NameMapper> NameMapperHandle;
|
||||
public:
|
||||
UpdatableNameMapper(std::shared_ptr<Library> library, bool withAlias);
|
||||
|
||||
virtual std::string getNameForId(const std::string& id) const;
|
||||
virtual std::string getIdForName(const std::string& name) const;
|
||||
|
||||
void update();
|
||||
|
||||
private:
|
||||
NameMapperHandle currentNameMapper() const;
|
||||
|
||||
private:
|
||||
mutable std::mutex mutex;
|
||||
std::shared_ptr<Library> library;
|
||||
NameMapperHandle nameMapper;
|
||||
const bool withAlias;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
/*
|
||||
* Copyright 2023 Nikhil Tanwar <2002nikhiltanwar@gmail.com>
|
||||
* Copyright 2017 Matthieu Gautier <mgautier@kymeria.fr>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
@@ -18,30 +17,58 @@
|
||||
* MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef KIWIX_LIBRARY_DUMPER_H
|
||||
#define KIWIX_LIBRARY_DUMPER_H
|
||||
#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 "name_mapper.h"
|
||||
#include <mustache.hpp>
|
||||
#include "reader.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace kiwix
|
||||
{
|
||||
|
||||
/**
|
||||
* A base class to dump Library in various formats.
|
||||
* A tool to dump a `Library` into a opds stream.
|
||||
*
|
||||
*/
|
||||
class LibraryDumper
|
||||
class OPDSDumper
|
||||
{
|
||||
public:
|
||||
LibraryDumper(const Library* library, const NameMapper* NameMapper);
|
||||
~LibraryDumper();
|
||||
OPDSDumper() = default;
|
||||
OPDSDumper(Library* library);
|
||||
~OPDSDumper();
|
||||
|
||||
void setLibraryId(const std::string& id) { this->libraryId = id;}
|
||||
/**
|
||||
* 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.
|
||||
@@ -51,11 +78,11 @@ class LibraryDumper
|
||||
void setRootLocation(const std::string& rootLocation) { this->rootLocation = rootLocation; }
|
||||
|
||||
/**
|
||||
* Set the URL for accessing book content
|
||||
* Set the search url.
|
||||
*
|
||||
* @param url the URL of the /content endpoint of the content server
|
||||
* @param searchUrl the search url to use.
|
||||
*/
|
||||
void setContentAccessUrl(const std::string& url) { this->contentAccessUrl = url; }
|
||||
void setSearchDescriptionUrl(const std::string& searchDescriptionUrl) { this->searchDescriptionUrl = searchDescriptionUrl; }
|
||||
|
||||
/**
|
||||
* Set some informations about the search results.
|
||||
@@ -67,33 +94,27 @@ class LibraryDumper
|
||||
void setOpenSearchInfo(int totalResult, int startIndex, int count);
|
||||
|
||||
/**
|
||||
* Sets user default language
|
||||
* Set the library to dump.
|
||||
*
|
||||
* @param userLang the user language to be set
|
||||
* @param library The library to dump.
|
||||
*/
|
||||
void setUserLanguage(std::string userLang) { this->m_userLang = userLang; }
|
||||
|
||||
/**
|
||||
* Get the data of categories
|
||||
*/
|
||||
kainjow::mustache::list getCategoryData() const;
|
||||
|
||||
/**
|
||||
* Get the data of languages
|
||||
*/
|
||||
kainjow::mustache::list getLanguageData() const;
|
||||
void setLibrary(Library* library) { this->library = library; }
|
||||
|
||||
protected:
|
||||
const kiwix::Library* const library;
|
||||
const kiwix::NameMapper* const nameMapper;
|
||||
std::string libraryId;
|
||||
kiwix::Library* library;
|
||||
std::string id;
|
||||
std::string title;
|
||||
std::string date;
|
||||
std::string rootLocation;
|
||||
std::string contentAccessUrl;
|
||||
std::string m_userLang;
|
||||
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_LIBRARY_DUMPER_H
|
||||
#endif // KIWIX_OPDS_DUMPER_H
|
||||
463
include/reader.h
Normal file
463
include/reader.h
Normal file
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
* 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_READER_H
|
||||
#define KIWIX_READER_H
|
||||
|
||||
#include <stdio.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"
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
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 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 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 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,
|
||||
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 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 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.
|
||||
*/
|
||||
unsigned int getFileSize() const;
|
||||
|
||||
/**
|
||||
* Get the zim file handler.
|
||||
*
|
||||
* @return The libzim file handler.
|
||||
*/
|
||||
zim::Archive* getZimArchive() const;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<zim::Archive> zimArchive;
|
||||
std::string zimFilePath;
|
||||
|
||||
SuggestionsList_t suggestions;
|
||||
SuggestionsList_t::iterator suggestionsOffset;
|
||||
|
||||
private:
|
||||
std::map<const std::string, unsigned int> parseCounterMetadata() const;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -21,12 +21,11 @@
|
||||
#define KIWIX_SEARCH_RENDERER_H
|
||||
|
||||
#include <string>
|
||||
#include <zim/search.h>
|
||||
#include "library.h"
|
||||
|
||||
namespace kiwix
|
||||
{
|
||||
|
||||
class Searcher;
|
||||
class NameMapper;
|
||||
/**
|
||||
* The SearcherRenderer class is used to render a search result to a html page.
|
||||
@@ -35,25 +34,21 @@ class SearchRenderer
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Construct a SearchRenderer from a SearchResultSet.
|
||||
* The default constructor.
|
||||
*
|
||||
* @param srs The `SearchResultSet` to render.
|
||||
* @param start The start offset used for the srs.
|
||||
* @param estimatedResultCount The estimatedResultCount of the whole search
|
||||
* @param humanReadableName The global zim's humanReadableName.
|
||||
* Used to generate pagination links.
|
||||
*/
|
||||
SearchRenderer(zim::SearchResultSet srs, unsigned int start, unsigned int estimatedResultCount);
|
||||
SearchRenderer(Searcher* searcher, NameMapper* mapper);
|
||||
|
||||
~SearchRenderer();
|
||||
|
||||
/**
|
||||
* Set the search pattern used to do the search
|
||||
*/
|
||||
void setSearchPattern(const std::string& pattern);
|
||||
|
||||
/**
|
||||
* Set the querystring used to select books
|
||||
* Set the search content id.
|
||||
*/
|
||||
void setSearchBookQuery(const std::string& bookQuery);
|
||||
void setSearchContent(const std::string& name);
|
||||
|
||||
/**
|
||||
* Set protocol prefix.
|
||||
@@ -72,47 +67,22 @@ class SearchRenderer
|
||||
this->pageLength = pageLength;
|
||||
}
|
||||
|
||||
/**
|
||||
* set user language
|
||||
*/
|
||||
void setUserLang(const std::string& lang){
|
||||
this->userlang = lang;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate the html page with the resutls of the search.
|
||||
*
|
||||
* @param mapper The `NameMapper` to use to do the rendering.
|
||||
* @param library The `Library` to use to look up book details for search results.
|
||||
May be nullptr. In this case, bookName is not set in the rendered string.
|
||||
* @return The html string
|
||||
*/
|
||||
std::string getHtml(const NameMapper& mapper, const Library* library);
|
||||
|
||||
/**
|
||||
* Generate the xml page with the resutls of the search.
|
||||
*
|
||||
* @param mapper The `NameMapper` to use to do the rendering.
|
||||
* @param library The `Library` to use to look up book details for search results.
|
||||
May be nullptr. In this case, bookName is not set in the rendered string.
|
||||
* @return The xml string
|
||||
*/
|
||||
std::string getXml(const NameMapper& mapper, const Library* library);
|
||||
|
||||
protected: // function
|
||||
std::string renderTemplate(const std::string& tmpl_str, const NameMapper& mapper, const Library *library);
|
||||
std::string getHtml();
|
||||
|
||||
protected:
|
||||
std::string beautifyInteger(const unsigned int number);
|
||||
zim::SearchResultSet m_srs;
|
||||
std::string searchBookQuery;
|
||||
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;
|
||||
std::string userlang = "en";
|
||||
};
|
||||
|
||||
|
||||
|
||||
171
include/searcher.h
Normal file
171
include/searcher.h
Normal file
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* 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_SEARCHER_H
|
||||
#define KIWIX_SEARCHER_H
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unicode/putil.h>
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <locale>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <vector>
|
||||
#include "tools/pathTools.h"
|
||||
#include "tools/stringTools.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
namespace kiwix
|
||||
{
|
||||
class Reader;
|
||||
class Result
|
||||
{
|
||||
public:
|
||||
virtual ~Result(){};
|
||||
virtual std::string get_url() = 0;
|
||||
virtual std::string get_title() = 0;
|
||||
virtual int get_score() = 0;
|
||||
virtual std::string get_snippet() = 0;
|
||||
virtual std::string get_content() = 0;
|
||||
virtual int get_wordCount() = 0;
|
||||
virtual int get_size() = 0;
|
||||
virtual int get_readerIndex() = 0;
|
||||
};
|
||||
|
||||
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();
|
||||
|
||||
/**
|
||||
* 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,
|
||||
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();
|
||||
|
||||
unsigned int getResultStart() { return resultStart; }
|
||||
unsigned int getResultEnd() { return resultEnd; }
|
||||
|
||||
protected:
|
||||
std::string beautifyInteger(const unsigned int number);
|
||||
void closeIndex();
|
||||
void searchInIndex(string& search,
|
||||
const unsigned int resultStart,
|
||||
const unsigned int resultEnd,
|
||||
const bool verbose = false);
|
||||
|
||||
std::vector<Reader*> readers;
|
||||
SearcherInternal* internal;
|
||||
std::string searchPattern;
|
||||
unsigned int estimatedResultCount;
|
||||
unsigned int resultStart;
|
||||
unsigned int resultEnd;
|
||||
|
||||
private:
|
||||
void reset();
|
||||
|
||||
};
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -22,7 +22,6 @@
|
||||
|
||||
#include <string>
|
||||
#include <memory>
|
||||
#include "tools.h"
|
||||
|
||||
namespace kiwix
|
||||
{
|
||||
@@ -37,7 +36,7 @@ namespace kiwix
|
||||
*
|
||||
* @param library The library to serve.
|
||||
*/
|
||||
Server(std::shared_ptr<Library> library, std::shared_ptr<NameMapper> nameMapper=nullptr);
|
||||
Server(Library* library, NameMapper* nameMapper=nullptr);
|
||||
|
||||
virtual ~Server();
|
||||
|
||||
@@ -52,42 +51,26 @@ namespace kiwix
|
||||
void stop();
|
||||
|
||||
void setRoot(const std::string& root);
|
||||
void setAddress(const std::string& addr);
|
||||
void setAddress(const std::string& addr) { m_addr = addr; }
|
||||
void setPort(int port) { m_port = port; }
|
||||
void setNbThreads(int threads) { m_nbThreads = threads; }
|
||||
void setMultiZimSearchLimit(unsigned int limit) { m_multizimSearchLimit = limit; }
|
||||
void setIpConnectionLimit(int limit) { m_ipConnectionLimit = limit; }
|
||||
void setVerbose(bool verbose) { m_verbose = verbose; }
|
||||
void setIndexTemplateString(const std::string& indexTemplateString) { m_indexTemplateString = indexTemplateString; }
|
||||
void setTaskbar(bool withTaskbar, bool withLibraryButton)
|
||||
{ m_withTaskbar = withTaskbar; m_withLibraryButton = withLibraryButton; }
|
||||
void setBlockExternalLinks(bool blockExternalLinks)
|
||||
{ m_blockExternalLinks = blockExternalLinks; }
|
||||
void setCatalogOnlyMode(bool enable) { m_catalogOnlyMode = enable; }
|
||||
void setContentServerUrl(std::string url) { m_contentServerUrl = url; }
|
||||
void setIpMode(IpMode mode) { m_ipMode = mode; }
|
||||
int getPort() const;
|
||||
IpAddress getAddress() const;
|
||||
IpMode getIpMode() const;
|
||||
std::vector<std::string> getServerAccessUrls() const;
|
||||
|
||||
protected:
|
||||
std::shared_ptr<Library> mp_library;
|
||||
std::shared_ptr<NameMapper> mp_nameMapper;
|
||||
Library* mp_library;
|
||||
NameMapper* mp_nameMapper;
|
||||
std::string m_root = "";
|
||||
IpAddress m_addr;
|
||||
std::string m_indexTemplateString = "";
|
||||
std::string m_addr = "";
|
||||
int m_port = 80;
|
||||
int m_nbThreads = 1;
|
||||
unsigned int m_multizimSearchLimit = 0;
|
||||
bool m_verbose = false;
|
||||
bool m_withTaskbar = true;
|
||||
bool m_withLibraryButton = true;
|
||||
bool m_blockExternalLinks = false;
|
||||
IpMode m_ipMode = IpMode::AUTO;
|
||||
int m_ipConnectionLimit = 0;
|
||||
bool m_catalogOnlyMode = false;
|
||||
std::string m_contentServerUrl;
|
||||
std::unique_ptr<InternalServer> mp_server;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2025 Veloman Yunkan
|
||||
*
|
||||
* 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_SPELLING_CORRECTION_H
|
||||
#define KIWIX_SPELLING_CORRECTION_H
|
||||
|
||||
#include <filesystem>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
namespace zim
|
||||
{
|
||||
class Archive;
|
||||
}
|
||||
|
||||
namespace Xapian
|
||||
{
|
||||
class Database;
|
||||
}
|
||||
|
||||
namespace kiwix
|
||||
{
|
||||
|
||||
class SpellingsDB
|
||||
{
|
||||
public: // functions
|
||||
SpellingsDB(const zim::Archive& archive, std::filesystem::path cacheDirPath);
|
||||
~SpellingsDB();
|
||||
|
||||
SpellingsDB(const SpellingsDB& ) = delete;
|
||||
void operator=(const SpellingsDB& ) = delete;
|
||||
|
||||
std::vector<std::string> getSpellingCorrections(const std::string& word, uint32_t maxCount) const;
|
||||
|
||||
private: // data
|
||||
std::unique_ptr<Xapian::Database> impl_;
|
||||
};
|
||||
|
||||
} // namespace kiwix
|
||||
|
||||
#endif // KIWIX_SPELLING_CORRECTION_H
|
||||
271
include/tools.h
271
include/tools.h
@@ -1,271 +0,0 @@
|
||||
/*
|
||||
* Copyright 2021 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_TOOLS_H
|
||||
#define KIWIX_TOOLS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <cstdint>
|
||||
#include "common.h"
|
||||
|
||||
namespace kiwix
|
||||
{
|
||||
|
||||
struct IpAddress
|
||||
{
|
||||
std::string addr; // IPv4 address
|
||||
std::string addr6; // IPv6 address
|
||||
};
|
||||
|
||||
typedef std::pair<std::string, std::string> LangNameCodePair;
|
||||
typedef std::vector<LangNameCodePair> FeedLanguages;
|
||||
typedef std::vector<std::string> FeedCategories;
|
||||
|
||||
/**
|
||||
* Return the current directory.
|
||||
*
|
||||
* @return the current directory (utf8 encoded)
|
||||
*/
|
||||
std::string getCurrentDirectory();
|
||||
|
||||
/** Return the path of the executable
|
||||
*
|
||||
* Some application may be packaged in auto extractible archive (Appimage) and the
|
||||
* real executable is different of the path of the archive.
|
||||
* If `realPathOnly` is true, return the path of the real executable instead of the
|
||||
* archive launched by the user.
|
||||
*
|
||||
* @param realPathOnly If we must return the real path of the executable.
|
||||
* @return the path of the executable (utf8 encoded)
|
||||
*/
|
||||
std::string getExecutablePath(bool realPathOnly = false);
|
||||
|
||||
/** Tell if the path is a relative path.
|
||||
*
|
||||
* This function is provided as a small helper. It is probably better to use native tools
|
||||
* to manipulate paths.
|
||||
*
|
||||
* @param path A utf8 encoded path.
|
||||
* @return true if the path is relative.
|
||||
*/
|
||||
bool isRelativePath(const std::string& path);
|
||||
|
||||
/** Append a path to another one.
|
||||
*
|
||||
* This function is provided as a small helper. It is probably better to use native tools
|
||||
* to manipulate paths.
|
||||
*
|
||||
* @param basePath the base path.
|
||||
* @param relativePath a path to add to the base path, must be a relative path.
|
||||
* @return The concatenation of the paths, using the right separator.
|
||||
*/
|
||||
std::string appendToDirectory(const std::string& basePath, const std::string& relativePath);
|
||||
|
||||
/** Remove the last element of a path.
|
||||
*
|
||||
* This function is provided as a small helper. It is probably better to use native tools
|
||||
* to manipulate paths.
|
||||
*
|
||||
* @param path a path.
|
||||
* @return The parent directory (or empty string if none).
|
||||
*/
|
||||
std::string removeLastPathElement(const std::string& path);
|
||||
|
||||
/** Get the last element of a path.
|
||||
*
|
||||
* This function is provided as a small helper. It is probably better to use native tools
|
||||
* to manipulate paths.
|
||||
*
|
||||
* @param path a path.
|
||||
* @return The base name of the path or empty string if none (ending with a separator).
|
||||
*/
|
||||
std::string getLastPathElement(const std::string& path);
|
||||
|
||||
/** Compute the absolute path of a relative path based on another one
|
||||
*
|
||||
* Equivalent to appendToDirectory followed by a normalization of the path.
|
||||
*
|
||||
* This function is provided as a small helper. It is probably better to use native tools
|
||||
* to manipulate paths.
|
||||
*
|
||||
* @param path the base path (if empty, current directory is taken).
|
||||
* @param relativePath the relative path.
|
||||
* @return a absolute path.
|
||||
*/
|
||||
std::string computeAbsolutePath(const std::string& path, const std::string& relativePath);
|
||||
|
||||
/** Compute the relative path of a path relative to another one
|
||||
*
|
||||
* This function is provided as a small helper. It is probably better to use native tools
|
||||
* to manipulate paths.
|
||||
*
|
||||
* @param path the base path.
|
||||
* @param absolutePath the absolute path to find the relative path for.
|
||||
* @return a relative path (pointing to absolutePath, relative to path).
|
||||
*/
|
||||
std::string computeRelativePath(const std::string& path, const std::string& absolutePath);
|
||||
|
||||
/** Sleep the current thread.
|
||||
*
|
||||
* This function is provided as a small helper. It is probably better to use native tools.
|
||||
*
|
||||
* @param milliseconds The number of milliseconds to wait for.
|
||||
*/
|
||||
void sleep(unsigned int milliseconds);
|
||||
|
||||
/** Split a string
|
||||
*
|
||||
* This function is provided as a small helper. It is probably better to use native tools.
|
||||
*
|
||||
* Assuming text = "foo:;bar;baz,oups;"
|
||||
*
|
||||
* split(text, ":;", true, true) => ["foo", ":", ";", "bar", ";", "baz,oups", ";"]
|
||||
* split(text, ":;", true, false) => ["foo", "bar", "baz,oups"] (default)
|
||||
* split(text, ":;", false, true) => ["foo", ":", "", ";", "bar", ";", "baz,oups", ";", ""]
|
||||
* split(text, ":;", false, false) => ["foo", "", "bar", "baz,oups", ""]
|
||||
*
|
||||
* @param str The string to split.
|
||||
* @param delims A string of potential delimiters.
|
||||
* Each charater in the string can be a individual delimiters.
|
||||
* @param dropEmpty true if empty part must be dropped from the result.
|
||||
* @param keepDelim true if delimiter must be included from the result.
|
||||
* @return a list of part (potentially containing delimiters)
|
||||
*/
|
||||
std::vector<std::string> split(const std::string& str, const std::string& delims, bool dropEmpty=true, bool keepDelim = false);
|
||||
|
||||
/** Convert language code from iso2 code to iso3
|
||||
*
|
||||
* This function is provided as a small helper. It is probably better to use native tools
|
||||
* to manipulate locales.
|
||||
*
|
||||
* @param a2code a iso2 code string.
|
||||
* @return the corresponding iso3 code.
|
||||
* @throw std::out_of_range if iso2 code is not known.
|
||||
*/
|
||||
std::string converta2toa3(const std::string& a2code);
|
||||
|
||||
/** Extracts content from given file.
|
||||
*
|
||||
* This function provides content of a file provided it's path.
|
||||
*
|
||||
* @param path The absolute path provided in string format.
|
||||
* @return Content of corresponding file in string format.
|
||||
*/
|
||||
std::string getFileContent(const std::string& path);
|
||||
|
||||
/** Checks if file exists.
|
||||
*
|
||||
* This function returns boolean stating if file exists.
|
||||
*
|
||||
* @param path The absolute path provided in string format.
|
||||
* @return Boolean representing if file exists or not.
|
||||
*/
|
||||
bool fileExists(const std::string& path);
|
||||
|
||||
/** Checks if file is readable.
|
||||
*
|
||||
* This function returns boolean stating if file is readable.
|
||||
*
|
||||
* @param path The absolute path provided in string format.
|
||||
* @return Boolean representing if file is readale or not.
|
||||
*/
|
||||
bool fileReadable(const std::string& path);
|
||||
|
||||
/** Provides mimetype from filename.
|
||||
*
|
||||
* This function provides mimetype from file-name.
|
||||
*
|
||||
* @param filename string containing filename.
|
||||
* @return mimetype from filename in string format.
|
||||
*/
|
||||
std::string getMimeTypeForFile(const std::string& filename);
|
||||
|
||||
/** Provides all available network interfaces
|
||||
*
|
||||
* This function provides the available IPv4 and IPv6 network interfaces
|
||||
* as a map from the interface name to its IPv4 and/or IPv6 address(es).
|
||||
*/
|
||||
std::map<std::string, IpAddress> getNetworkInterfacesIPv4Or6();
|
||||
|
||||
/** Provides all available IPv4 network interfaces
|
||||
*
|
||||
* This function provides the available IPv4 network interfaces
|
||||
* as a map from the interface name to its IPv4 address.
|
||||
*
|
||||
* Provided for backward compatibility with libkiwix v13.1.0.
|
||||
*/
|
||||
std::map<std::string, std::string> getNetworkInterfaces();
|
||||
|
||||
/** Provides the best IP address
|
||||
* This function provides the best IP addresses for both ipv4 and ipv6 protocols,
|
||||
* in an IpAddress struct, based on the list given by getNetworkInterfacesIPv4Or6()
|
||||
*/
|
||||
IpAddress getBestPublicIps();
|
||||
|
||||
/** Provides the best IPv4 adddress
|
||||
* Equivalent to getBestPublicIp(false). Provided for backward compatibility
|
||||
* with libkiwix v13.1.0.
|
||||
*/
|
||||
std::string getBestPublicIp();
|
||||
|
||||
/** Converts file size to human readable format.
|
||||
*
|
||||
* This function will convert a number to its equivalent size using units.
|
||||
*
|
||||
* @param number file size in bytes.
|
||||
* @return a human-readable string representation of the size, e.g., "2.3 KB", "1.8 MB", "5.2 GB".
|
||||
*/
|
||||
std::string beautifyFileSize(uint64_t number);
|
||||
|
||||
/**
|
||||
* Load languages stored in an OPDS stream.
|
||||
*
|
||||
* @param content the OPDS stream.
|
||||
* @return vector containing pairs of language code and their corresponding full language name.
|
||||
*/
|
||||
FeedLanguages readLanguagesFromFeed(const std::string& content);
|
||||
|
||||
/**
|
||||
* Load categories stored in an OPDS stream .
|
||||
*
|
||||
* @param content the OPDS stream.
|
||||
* @return vector containing category strings.
|
||||
*/
|
||||
FeedCategories readCategoriesFromFeed(const std::string& content);
|
||||
|
||||
/**
|
||||
* Retrieve the full language name associated with a given ISO 639-3 language code.
|
||||
*
|
||||
* @param lang ISO 639-3 language code.
|
||||
* @return full language name.
|
||||
*/
|
||||
std::string getLanguageSelfName(const std::string& lang);
|
||||
|
||||
/**
|
||||
* Slugifies the filename by converting any characters reserved by the operating
|
||||
* system to '_'. Note filename is only the file name and not a path.
|
||||
*
|
||||
* @param filename Valid UTF-8 encoded file name string.
|
||||
* @return slugified string.
|
||||
*/
|
||||
std::string getSlugifiedFileName(const std::string& filename);
|
||||
}
|
||||
#endif // KIWIX_TOOLS_H
|
||||
@@ -23,23 +23,17 @@
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <map>
|
||||
#include <cstdlib>
|
||||
#include <zim/zim.h>
|
||||
#include <mustache.hpp>
|
||||
|
||||
#include "stringTools.h"
|
||||
|
||||
namespace pugi {
|
||||
class xml_node;
|
||||
}
|
||||
|
||||
namespace zim {
|
||||
class SuggestionItem;
|
||||
}
|
||||
|
||||
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
|
||||
@@ -49,44 +43,8 @@ namespace kiwix
|
||||
const std::string& tagName);
|
||||
bool convertStrToBool(const std::string& value);
|
||||
|
||||
std::string gen_date_str();
|
||||
std::string gen_uuid(const std::string& s);
|
||||
|
||||
// if s is empty then returns kainjow::mustache::data(false)
|
||||
// otherwise kainjow::mustache::data(value)
|
||||
kainjow::mustache::data onlyAsNonEmptyMustacheValue(const std::string& s);
|
||||
|
||||
std::string render_template(const std::string& template_str, kainjow::mustache::data data);
|
||||
|
||||
template<typename T>
|
||||
T getEnvVar(const char* name, const T& defaultValue)
|
||||
{
|
||||
try {
|
||||
const char* envString = std::getenv(name);
|
||||
if (envString == nullptr) {
|
||||
throw std::runtime_error("Environment variable not set");
|
||||
}
|
||||
return extractFromString<T>(envString);
|
||||
} catch (...) {}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
class Suggestions
|
||||
{
|
||||
public:
|
||||
Suggestions();
|
||||
|
||||
void add(const zim::SuggestionItem& suggestion);
|
||||
|
||||
void addFTSearchSuggestion(const std::string& uiLang,
|
||||
const std::string& query);
|
||||
|
||||
std::string getJSON() const;
|
||||
|
||||
private:
|
||||
kainjow::mustache::data m_data;
|
||||
};
|
||||
using MimeCounterType = std::map<const std::string, zim::entry_index_type>;
|
||||
MimeCounterType parseMimetypeCounter(const std::string& counterData);
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -26,12 +26,23 @@
|
||||
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
|
||||
|
||||
@@ -26,5 +26,11 @@ bool matchRegex(const std::string& content, const std::string& regex);
|
||||
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& replacement);
|
||||
std::string prependToFirstOccurence(const std::string& content,
|
||||
const std::string& regex,
|
||||
const std::string& replacement);
|
||||
|
||||
#endif
|
||||
@@ -21,16 +21,15 @@
|
||||
#define KIWIX_STRINGTOOLS_H
|
||||
|
||||
#include <unicode/unistr.h>
|
||||
#include <unicode/locid.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sstream>
|
||||
#include <stdexcept>
|
||||
|
||||
namespace kiwix
|
||||
{
|
||||
std::string beautifyInteger(uint64_t number);
|
||||
std::string beautifyFileSize(uint64_t number);
|
||||
void printStringInHexadecimal(const char* s);
|
||||
void printStringInHexadecimal(icu::UnicodeString s);
|
||||
void stringReplacement(std::string& str,
|
||||
@@ -41,34 +40,16 @@ std::string encodeDiples(const std::string& str);
|
||||
std::string removeAccents(const std::string& text);
|
||||
void loadICUExternalTables();
|
||||
|
||||
class ICULanguageInfo
|
||||
{
|
||||
public:
|
||||
explicit ICULanguageInfo(const std::string& langCode);
|
||||
|
||||
std::string iso3Code() const;
|
||||
std::string selfName() const;
|
||||
|
||||
private:
|
||||
const icu::Locale locale;
|
||||
};
|
||||
|
||||
std::string escapeForJSON(const std::string& s, bool escapeQuote = true);
|
||||
|
||||
/* urlEncode() is the equivalent of JS encodeURIComponent(), with the only
|
||||
* difference that the slash (/) symbol is NOT encoded. */
|
||||
std::string urlEncode(const std::string& value);
|
||||
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::string ucAll(const std::string& word);
|
||||
std::string lcAll(const std::string& word);
|
||||
std::string ucFirst(const std::string& word);
|
||||
std::string lcFirst(const std::string& word);
|
||||
|
||||
/* This function is broken, related Github issue
|
||||
* https://github.com/kiwix/libkiwix/issues/1188 */
|
||||
std::string toTitle(const std::string& word);
|
||||
|
||||
std::string normalize(const std::string& word);
|
||||
@@ -85,19 +66,9 @@ T extractFromString(const std::string& str) {
|
||||
std::istringstream iss(str);
|
||||
T ret;
|
||||
iss >> ret;
|
||||
if(iss.fail() || !iss.eof()) {
|
||||
throw std::invalid_argument("no conversion");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
template<>
|
||||
std::string extractFromString(const std::string& str);
|
||||
|
||||
bool startsWith(const std::string& base, const std::string& start);
|
||||
|
||||
std::string stripSuffix(const std::string& str, const std::string& suffix);
|
||||
|
||||
std::vector<std::string> getTitleVariants(const std::string& title);
|
||||
} //namespace kiwix
|
||||
#endif
|
||||
10
kiwix.pc.in
Normal file
10
kiwix.pc.in
Normal file
@@ -0,0 +1,10 @@
|
||||
prefix=@prefix@
|
||||
libdir=${prefix}/lib64
|
||||
includedir=${prefix}/include
|
||||
|
||||
Name: libkiwix
|
||||
Description: A library that contains a lot of things used by used by other kiwix programs
|
||||
Version: @version@
|
||||
Requires: @requires@
|
||||
Libs: -L${libdir} -lkiwix @extra_libs@
|
||||
Cflags: -I${includedir}/ @extra_cflags@
|
||||
124
meson.build
124
meson.build
@@ -1,66 +1,39 @@
|
||||
project('libkiwix', 'cpp',
|
||||
version : '14.1.1',
|
||||
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++17', 'werror=true'])
|
||||
default_options : ['c_std=c11', 'cpp_std=c++11', 'werror=true'])
|
||||
|
||||
compiler = meson.get_compiler('cpp')
|
||||
static_deps = get_option('static-linkage') or get_option('default_library') == 'static'
|
||||
extra_libs = []
|
||||
|
||||
# Atomics as compiled by GCC or clang can lead to external references to
|
||||
# functions depending on the type size and the platform. LLVM provides them in
|
||||
# 'libcompiler_rt', which clang normally automatically links in, while GNU
|
||||
# provides them in 'libatomic', which GCC *does not* link in automatically (but
|
||||
# this is probably going to change, see
|
||||
# https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81358). Regardless of the setup
|
||||
# of the compiler driver itself (GCC or clang), we can thus assume that if some
|
||||
# atomic references can't be resolved, then 'libatomic' is missing.
|
||||
atomics_program = '''
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
wrapper = get_option('wrapper')
|
||||
|
||||
using namespace std;
|
||||
|
||||
int main() {
|
||||
volatile atomic_bool a_b(true);
|
||||
volatile atomic_ullong a_ull(-1);
|
||||
// Next two lines are to cover atomic<socket_t> from 'httplib.h'.
|
||||
volatile atomic<uint32_t> a_u32(-1);
|
||||
volatile atomic<uint64_t> a_u64(-1);
|
||||
|
||||
return atomic_load(&a_b) == false && atomic_load(&a_ull) == 0 &&
|
||||
atomic_load(&a_u32) == 0 && atomic_load(&a_u64) == 0;
|
||||
}
|
||||
'''
|
||||
if not compiler.links(atomics_program,
|
||||
name: 'compiler driver readily supports atomics')
|
||||
libatomic = compiler.find_library('atomic')
|
||||
compiler.links(atomics_program, name: 'atomics work with libatomic',
|
||||
dependencies: libatomic, required: true)
|
||||
extra_libs += ['-latomic']
|
||||
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
|
||||
|
||||
# C++ std::thread is implemented using pthread on Linux by GCC, and on FreeBSD
|
||||
# for both GCC and LLVM.
|
||||
if (host_machine.system() == 'linux' and compiler.get_id() == 'gcc') or \
|
||||
host_machine.system() == 'freebsd'
|
||||
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
|
||||
|
||||
libicu_dep = dependency('icu-i18n', static:static_deps)
|
||||
if libicu_dep.version().version_compare('>= 76')
|
||||
libicu_deps = [libicu_dep, dependency('icu-uc', static:static_deps)]
|
||||
else
|
||||
libicu_deps = [libicu_dep]
|
||||
endif
|
||||
|
||||
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)
|
||||
xapian_dep = dependency('xapian-core', static:static_deps)
|
||||
|
||||
if compiler.has_header('mustache.hpp')
|
||||
extra_include = []
|
||||
@@ -70,53 +43,48 @@ else
|
||||
error('Cannot found header mustache.hpp')
|
||||
endif
|
||||
|
||||
libzim_dep = dependency('libzim', version:['>=9.4.0', '<10.0.0'], static:static_deps)
|
||||
|
||||
if not compiler.has_header_symbol('zim/zim.h', 'LIBZIM_WITH_XAPIAN', dependencies: libzim_dep)
|
||||
error('Libzim seems to be compiled without Xapian. Xapian support is mandatory.')
|
||||
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.')
|
||||
endif
|
||||
|
||||
|
||||
extra_cflags = ''
|
||||
if host_machine.system() == 'windows' and static_deps
|
||||
if target_machine.system() == 'windows' and static_deps
|
||||
add_project_arguments('-DCURL_STATICLIB', language : 'cpp')
|
||||
extra_cflags += '-DCURL_STATICLIB'
|
||||
endif
|
||||
|
||||
if host_machine.system() == 'windows'
|
||||
add_project_arguments('-DNOMINMAX', language: 'cpp')
|
||||
extra_libs += ['-liphlpapi']
|
||||
endif
|
||||
|
||||
if build_machine.system() == 'windows'
|
||||
extra_libs += ['-lshlwapi', '-lwinmm']
|
||||
endif
|
||||
|
||||
|
||||
# Dependencies as string
|
||||
all_deps = [thread_dep, libzim_dep, pugixml_dep, libcurl_dep, microhttpd_dep, zlib_dep, xapian_dep]
|
||||
|
||||
# Dependencies as array
|
||||
all_deps += libicu_deps
|
||||
all_deps = [thread_dep, libicu_dep, libzim_dep, pugixml_dep, libcurl_dep, microhttpd_dep, zlib_dep]
|
||||
|
||||
inc = include_directories('include', extra_include)
|
||||
|
||||
conf = configuration_data()
|
||||
conf.set('LIBKIWIX_VERSION', '"@0@"'.format(meson.project_version()))
|
||||
conf.set('VERSION', '"@0@"'.format(meson.project_version()))
|
||||
|
||||
if build_machine.system() == 'windows'
|
||||
extra_link_args = ['-lshlwapi', '-lwinmm']
|
||||
else
|
||||
extra_link_args = []
|
||||
endif
|
||||
|
||||
subdir('include')
|
||||
subdir('scripts')
|
||||
subdir('static')
|
||||
subdir('src')
|
||||
subdir('test')
|
||||
if get_option('doc')
|
||||
subdir('docs')
|
||||
endif
|
||||
|
||||
pkg_mod = import('pkgconfig')
|
||||
pkg_mod.generate(libraries : [libkiwix] + extra_libs,
|
||||
version : meson.project_version(),
|
||||
name : 'libkiwix',
|
||||
filebase : 'libkiwix',
|
||||
description : 'A library that contains useful primitives that Kiwix readers have in common',
|
||||
extra_cflags: extra_cflags)
|
||||
pkg_requires = ['libzim', 'icu-i18n', 'pugixml', 'libcurl', 'libmicrohttpd']
|
||||
|
||||
pkg_conf = configuration_data()
|
||||
pkg_conf.set('prefix', get_option('prefix'))
|
||||
pkg_conf.set('requires', ' '.join(pkg_requires))
|
||||
pkg_conf.set('extra_libs', ' '.join(extra_libs))
|
||||
pkg_conf.set('extra_cflags', extra_cflags)
|
||||
pkg_conf.set('version', meson.project_version())
|
||||
configure_file(output : 'kiwix.pc',
|
||||
configuration : pkg_conf,
|
||||
input : 'kiwix.pc.in',
|
||||
install_dir: get_option('libdir')+'/pkgconfig'
|
||||
)
|
||||
|
||||
|
||||
@@ -1,4 +1,2 @@
|
||||
option('static-linkage', type : 'boolean', value : false,
|
||||
description : 'Link statically with the dependencies.')
|
||||
option('doc', type : 'boolean', value : false,
|
||||
description : 'Build the documentations.')
|
||||
option('wrapper', type:'array', choices:['java', 'android'], value:[],
|
||||
description: 'The wrapper to generate.')
|
||||
|
||||
10
prototype/README.md
Normal file
10
prototype/README.md
Normal file
@@ -0,0 +1,10 @@
|
||||
# kiwixprototype
|
||||
Revamping the landing page
|
||||
## I made a simple mockup using pages
|
||||

|
||||

|
||||
## and here's the final version
|
||||
|
||||

|
||||
|
||||

|
||||
132
prototype/css/jquery.uls.css
Normal file
132
prototype/css/jquery.uls.css
Normal file
@@ -0,0 +1,132 @@
|
||||
.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;
|
||||
}
|
||||
307
prototype/css/jquery.uls.grid.css
Normal file
307
prototype/css/jquery.uls.grid.css
Normal file
@@ -0,0 +1,307 @@
|
||||
/* 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;
|
||||
}
|
||||
140
prototype/css/jquery.uls.lcd.css
Normal file
140
prototype/css/jquery.uls.lcd.css
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* 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;
|
||||
}
|
||||
307
prototype/css/jquery.uls.mobile.css
Normal file
307
prototype/css/jquery.uls.mobile.css
Normal file
@@ -0,0 +1,307 @@
|
||||
/* 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;
|
||||
}
|
||||
505
prototype/css/style.css
Normal file
505
prototype/css/style.css
Normal file
@@ -0,0 +1,505 @@
|
||||
* {
|
||||
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;
|
||||
}
|
||||
}
|
||||
20
prototype/i18n/aeb-latn.json
Normal file
20
prototype/i18n/aeb-latn.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
26
prototype/i18n/af.json
Normal file
26
prototype/i18n/af.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
22
prototype/i18n/am.json
Normal file
22
prototype/i18n/am.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"@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": "ቋንቋ ለመፈለግ"
|
||||
}
|
||||
21
prototype/i18n/anp.json
Normal file
21
prototype/i18n/anp.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"@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": "भाषा लेली खोजऽ"
|
||||
}
|
||||
26
prototype/i18n/ar.json
Normal file
26
prototype/i18n/ar.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"@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": "بحث عن لغة"
|
||||
}
|
||||
22
prototype/i18n/arz.json
Normal file
22
prototype/i18n/arz.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"@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": "دوّر على لغة"
|
||||
}
|
||||
23
prototype/i18n/as.json
Normal file
23
prototype/i18n/as.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"@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": "ভাষা এটাৰ সন্ধান কৰক"
|
||||
}
|
||||
21
prototype/i18n/ast.json
Normal file
21
prototype/i18n/ast.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
20
prototype/i18n/av.json
Normal file
20
prototype/i18n/av.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"@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": "МацӀ цӀехей"
|
||||
}
|
||||
23
prototype/i18n/awa.json
Normal file
23
prototype/i18n/awa.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"@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": "भाषा खोज"
|
||||
}
|
||||
24
prototype/i18n/az.json
Normal file
24
prototype/i18n/az.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
23
prototype/i18n/azb.json
Normal file
23
prototype/i18n/azb.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"@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": "بیر دیلی آختار"
|
||||
}
|
||||
22
prototype/i18n/ba.json
Normal file
22
prototype/i18n/ba.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"@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": "Тел буйынса эҙләү"
|
||||
}
|
||||
22
prototype/i18n/ban.json
Normal file
22
prototype/i18n/ban.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
17
prototype/i18n/bbc-latn.json
Normal file
17
prototype/i18n/bbc-latn.json
Normal file
@@ -0,0 +1,17 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
21
prototype/i18n/bcc.json
Normal file
21
prototype/i18n/bcc.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"@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": "زبانء شۏھاز"
|
||||
}
|
||||
21
prototype/i18n/bci.json
Normal file
21
prototype/i18n/bci.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
22
prototype/i18n/bcl.json
Normal file
22
prototype/i18n/bcl.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
23
prototype/i18n/be-tarask.json
Normal file
23
prototype/i18n/be-tarask.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"@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": "Пошук мовы"
|
||||
}
|
||||
22
prototype/i18n/be.json
Normal file
22
prototype/i18n/be.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"@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": "Пошук мовы"
|
||||
}
|
||||
25
prototype/i18n/bg.json
Normal file
25
prototype/i18n/bg.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"@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": "Търсене на език"
|
||||
}
|
||||
22
prototype/i18n/bgn.json
Normal file
22
prototype/i18n/bgn.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"@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": "گَشتین په یک زبانئ خاتیرا"
|
||||
}
|
||||
26
prototype/i18n/bn.json
Normal file
26
prototype/i18n/bn.json
Normal file
@@ -0,0 +1,26 @@
|
||||
{
|
||||
"@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": "একটি ভাষার জন্য অনুসন্ধান করুন"
|
||||
}
|
||||
22
prototype/i18n/br.json
Normal file
22
prototype/i18n/br.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
24
prototype/i18n/bs.json
Normal file
24
prototype/i18n/bs.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
13
prototype/i18n/bto.json
Normal file
13
prototype/i18n/bto.json
Normal file
@@ -0,0 +1,13 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
24
prototype/i18n/ca.json
Normal file
24
prototype/i18n/ca.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
21
prototype/i18n/ce.json
Normal file
21
prototype/i18n/ce.json
Normal file
@@ -0,0 +1,21 @@
|
||||
{
|
||||
"@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": "Лаха мотт"
|
||||
}
|
||||
24
prototype/i18n/ckb.json
Normal file
24
prototype/i18n/ckb.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"@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": "گەڕان بەدوای زمانێکدا"
|
||||
}
|
||||
20
prototype/i18n/cop.json
Normal file
20
prototype/i18n/cop.json
Normal file
@@ -0,0 +1,20 @@
|
||||
{
|
||||
"@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": "ϫⲉⲙⲣⲁⲧⲕ `ⲛⲟⲩⲁⲥⲡⲓ"
|
||||
}
|
||||
23
prototype/i18n/cs.json
Normal file
23
prototype/i18n/cs.json
Normal file
@@ -0,0 +1,23 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
22
prototype/i18n/cv.json
Normal file
22
prototype/i18n/cv.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"@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": "Чĕлхе шыра"
|
||||
}
|
||||
22
prototype/i18n/cy.json
Normal file
22
prototype/i18n/cy.json
Normal file
@@ -0,0 +1,22 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
24
prototype/i18n/da.json
Normal file
24
prototype/i18n/da.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"@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"
|
||||
}
|
||||
12
prototype/i18n/de-formal.json
Normal file
12
prototype/i18n/de-formal.json
Normal file
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Kghbln",
|
||||
"Purodha"
|
||||
]
|
||||
},
|
||||
"uls-region-SP": "Extras - kein Schprohche",
|
||||
"uls-no-results-suggestion-title": "Dies könnte Sie interessieren:",
|
||||
"uls-search-help": "Sie können nach dem Namen der Sprache suchen, dem Namen der Schrift, dem ISO-Code der Sprache oder aber die Suche über eine Region durchführen:",
|
||||
"uls-search-placeholder": "Noh Schprohche söhke"
|
||||
}
|
||||
24
prototype/i18n/de.json
Normal file
24
prototype/i18n/de.json
Normal file
@@ -0,0 +1,24 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Kghbln",
|
||||
"Man77",
|
||||
"Metalhead64",
|
||||
"TMg"
|
||||
]
|
||||
},
|
||||
"uls-region-WW": "Weltweit",
|
||||
"uls-region-SP": "Spezial",
|
||||
"uls-region-AM": "Amerika",
|
||||
"uls-region-AF": "Afrika",
|
||||
"uls-region-EU": "Europa",
|
||||
"uls-region-AS": "Asien",
|
||||
"uls-region-ME": "Naher Osten",
|
||||
"uls-region-PA": "Pazifik",
|
||||
"uls-region-all": "Alle Sprachen",
|
||||
"uls-no-results-found": "Es wurden keine Ergebnisse gefunden.",
|
||||
"uls-common-languages": "Vorgeschlagene Sprachen",
|
||||
"uls-no-results-suggestion-title": "Dies könnte dich interessieren:",
|
||||
"uls-search-help": "Du kannst nach dem Namen der Sprache suchen, dem Namen der Schrift, dem ISO-Code der Sprache oder aber die Suche über eine Region durchführen.",
|
||||
"uls-search-placeholder": "Nach einer Sprache suchen"
|
||||
}
|
||||
27
prototype/i18n/diq.json
Normal file
27
prototype/i18n/diq.json
Normal file
@@ -0,0 +1,27 @@
|
||||
{
|
||||
"@metadata": {
|
||||
"authors": [
|
||||
"Asmen",
|
||||
"Erdemaslancan",
|
||||
"Gorizon",
|
||||
"Gırd",
|
||||
"Kumkumuk",
|
||||
"Marmase",
|
||||
"Mirzali"
|
||||
]
|
||||
},
|
||||
"uls-region-WW": "Dınyayi",
|
||||
"uls-region-SP": "Xısusi",
|
||||
"uls-region-AM": "Amerika",
|
||||
"uls-region-AF": "Afrika",
|
||||
"uls-region-EU": "Ewropa",
|
||||
"uls-region-AS": "Asya",
|
||||
"uls-region-ME": "Rocvetışê Miyani",
|
||||
"uls-region-PA": "Pasifik",
|
||||
"uls-region-all": "Zıwani pêro",
|
||||
"uls-no-results-found": "Neticeyi nêvêniyayi",
|
||||
"uls-common-languages": "Zıwanê ke estê.",
|
||||
"uls-no-results-suggestion-title": "Belki şıma cıya eleqederi:",
|
||||
"uls-search-help": "Şıma şenê name dê zıwaniya, skript kodiya, ISO qodiya yana mıntıqa heta cıgeyrayış bıkerê.",
|
||||
"uls-search-placeholder": "Yew zıwani cı geyre"
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user