Compare commits

..

1 Commits

Author SHA1 Message Date
Alexandre Flament
72f5e7cfb8 js_variable_to_python: add tests, handle more JS syntax
The tests from chompjs are copied.
The comment out tests do not pass.
The implementation of js_variable_to_python has been updated:
* in the main looop, try to make the four different cases more clear
* handle decimal number like "-.5", "5." or "- 5"  (without double quote)
* the character ` is seen a string delimiter as intended in JS
* the identifiers follow JS specification ($, _, letters and numbers)
2023-09-16 18:30:57 +00:00
798 changed files with 84564 additions and 175909 deletions

View File

@ -3,8 +3,7 @@
"dockerfile": "Dockerfile"
},
"features": {
"ghcr.io/devcontainers/features/github-cli": {},
"ghcr.io/devcontainers/features/docker-in-docker": {}
"ghcr.io/devcontainers/features/github-cli": {}
},
"customizations": {
"vscode": {

View File

@ -16,17 +16,8 @@ max_line_length = 119
[*.html]
indent_size = 4
[*.css]
indent_size = 2
[*.less]
indent_size = 2
[*.js]
indent_size = 2
[*.json]
indent_size = 2
indent_size = 4
insert_final_newline = ignore
# Minified JavaScript files shouldn't be changed

1
.env
View File

@ -1 +0,0 @@
NEKOSEARCH_PORT="8080"

View File

@ -1,4 +1,4 @@
# https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
version: 2
updates:
- package-ecosystem: "pip"
@ -8,33 +8,10 @@ updates:
day: "friday"
open-pull-requests-limit: 5
target-branch: "master"
commit-message:
prefix: "[upd] pypi:"
- package-ecosystem: "npm"
directory: "/client/simple"
directory: "/searx/static/themes/simple"
schedule:
interval: "weekly"
day: "friday"
open-pull-requests-limit: 5
target-branch: "master"
commit-message:
prefix: "[upd] web-client (simple):"
- package-ecosystem: "docker"
directory: "/"
schedule:
interval: "weekly"
day: "friday"
target-branch: "master"
commit-message:
prefix: "[upd] docker:"
- package-ecosystem: "github-actions"
directory: "/"
schedule:
interval: "weekly"
day: "friday"
target-branch: "master"
commit-message:
prefix: "[upd] github-actions:"

View File

@ -1,46 +0,0 @@
---
name: Checker
# yamllint disable-line rule:truthy
on:
workflow_dispatch:
schedule:
- cron: "0 4 * * 5"
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: false
permissions:
contents: read
env:
PYTHON_VERSION: "3.13"
jobs:
search:
name: Search
runs-on: ubuntu-24.04-arm
steps:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "${{ env.PYTHON_VERSION }}"
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: "false"
- name: Setup cache Python
uses: actions/cache@v4
with:
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
restore-keys: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-"
path: "./local"
- name: Setup venv
run: make V=1 install
- name: Search checker
run: make search.checker

View File

@ -1,27 +1,14 @@
---
name: Update searx.data
# yamllint disable-line rule:truthy
name: "Update searx.data"
on:
workflow_dispatch:
schedule:
- cron: "59 23 28 * *"
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: false
permissions:
contents: read
env:
PYTHON_VERSION: "3.13"
workflow_dispatch:
jobs:
data:
if: github.repository_owner == 'searxng'
name: ${{ matrix.fetch }}
runs-on: ubuntu-24.04-arm
updateData:
name: Update data - ${{ matrix.fetch }}
runs-on: ubuntu-20.04
if: ${{ github.repository_owner == 'searxng'}}
strategy:
fail-fast: false
matrix:
@ -33,51 +20,48 @@ jobs:
- update_engine_traits.py
- update_wikidata_units.py
- update_engine_descriptions.py
permissions:
contents: write
pull-requests: write
steps:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "${{ env.PYTHON_VERSION }}"
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: "false"
- name: Setup cache Python
uses: actions/cache@v4
with:
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
restore-keys: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-"
path: "./local/"
- name: Install Ubuntu packages
run: |
sudo ./utils/searxng.sh install packages
- name: Setup venv
run: make V=1 install
- name: Set up Python
uses: actions/setup-python@v2
with:
python-version: '3.9'
architecture: 'x64'
- name: Install Python dependencies
run: |
make V=1 install
- name: Fetch data
run: V=1 ./manage pyenv.cmd python "./searxng_extra/update/${{ matrix.fetch }}"
env:
FETCH_SCRIPT: ./searxng_extra/update/${{ matrix.fetch }}
run: |
V=1 ./manage pyenv.cmd python "$FETCH_SCRIPT"
- name: Create PR
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v7
uses: peter-evans/create-pull-request@v3
with:
author: "${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>"
committer: "searxng-bot <searxng-bot@users.noreply.github.com>"
title: "[data] update searx.data - ${{ matrix.fetch }}"
commit-message: "[data] update searx.data - ${{ matrix.fetch }}"
branch: "update_data_${{ matrix.fetch }}"
delete-branch: "true"
draft: "false"
signoff: "false"
commit-message: Update searx.data - ${{ matrix.fetch }}
committer: searxng-bot <noreply@github.com>
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
signoff: false
branch: update_data_${{ matrix.fetch }}
delete-branch: true
draft: false
title: 'Update searx.data - ${{ matrix.fetch }}'
body: |
Update searx.data - ${{ matrix.fetch }}
labels: |
data
- name: Display information
- name: Check outputs
run: |
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"

View File

@ -1,66 +0,0 @@
---
name: Documentation
# yamllint disable-line rule:truthy
on:
workflow_dispatch:
push:
branches:
- master
pull_request:
branches:
- master
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: false
permissions:
contents: read
env:
PYTHON_VERSION: "3.13"
jobs:
release:
name: Release
runs-on: ubuntu-24.04-arm
permissions:
# for JamesIves/github-pages-deploy-action to push
contents: write
steps:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "${{ env.PYTHON_VERSION }}"
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: "false"
fetch-depth: "0"
- name: Setup cache Python
uses: actions/cache@v4
with:
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
restore-keys: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-"
path: "./local/"
- name: Setup venv
run: make V=1 install
- name: Build documentation
run: make V=1 docs.clean docs.html
- if: github.ref_name == 'master'
name: Release
uses: JamesIves/github-pages-deploy-action@v4
with:
folder: "dist/docs"
branch: "gh-pages"
commit-message: "[doc] build from commit ${{ github.sha }}"
# Automatically remove deleted files from the deploy branch
clean: "true"
single-commit: "true"

View File

@ -1,109 +1,181 @@
---
name: Integration
# yamllint disable-line rule:truthy
on:
push:
branches:
- master
branches: ["master"]
pull_request:
branches:
- master
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: false
branches: ["master"]
permissions:
contents: read
env:
PYTHON_VERSION: "3.13"
jobs:
test:
python:
name: Python ${{ matrix.python-version }}
runs-on: ubuntu-24.04
runs-on: ubuntu-20.04
strategy:
matrix:
python-version:
- "3.9"
- "3.10"
- "3.11"
- "3.12"
- "3.13"
os: [ubuntu-20.04]
python-version: ["3.8", "3.9", "3.10", "3.11"]
steps:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "${{ matrix.python-version }}"
- name: Checkout
uses: actions/checkout@v4
- name: Install Ubuntu packages
run: |
sudo ./utils/searxng.sh install packages
sudo apt install firefox
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
architecture: 'x64'
- name: Cache Python dependencies
id: cache-python
uses: actions/cache@v3
with:
path: |
./local
./.nvm
./node_modules
key: python-${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('requirements*.txt', 'setup.py') }}
- name: Install Python dependencies
if: steps.cache-python.outputs.cache-hit != 'true'
run: |
make V=1 install
make V=1 gecko.driver
- name: Run tests
run: make V=1 ci.test
- name: Test coverage
run: make V=1 test.coverage
- name: Store coverage result
uses: actions/upload-artifact@v3
with:
name: coverage-${{ matrix.python-version }}
path: coverage/
retention-days: 60
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: "false"
- name: Setup cache Python
uses: actions/cache@v4
with:
key: "python-${{ matrix.python-version }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
restore-keys: "python-${{ matrix.python-version }}-${{ runner.arch }}-"
path: "./local/"
- name: Setup venv
run: make V=1 install
- name: Run tests
run: make V=1 ci.test
theme:
name: Theme
runs-on: ubuntu-24.04-arm
themes:
name: Themes
runs-on: ubuntu-20.04
steps:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "${{ env.PYTHON_VERSION }}"
- name: Checkout
uses: actions/checkout@v4
- name: Install Ubuntu packages
run: sudo ./utils/searxng.sh install buildhost
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
architecture: 'x64'
- name: Cache Python dependencies
id: cache-python
uses: actions/cache@v3
with:
path: |
./local
./.nvm
./node_modules
key: python-ubuntu-20.04-3.9-${{ hashFiles('requirements*.txt', 'setup.py','.nvmrc', 'package.json') }}
- name: Install node dependencies
run: make V=1 node.env
- name: Build themes
run: make V=1 themes.all
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: "false"
documentation:
name: Documentation
runs-on: ubuntu-20.04
permissions:
contents: write # for JamesIves/github-pages-deploy-action to push changes in repo
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: '0'
persist-credentials: false
- name: Install Ubuntu packages
run: sudo ./utils/searxng.sh install buildhost
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
architecture: 'x64'
- name: Cache Python dependencies
id: cache-python
uses: actions/cache@v3
with:
path: |
./local
./.nvm
./node_modules
key: python-ubuntu-20.04-3.9-${{ hashFiles('requirements*.txt', 'setup.py','.nvmrc', 'package.json') }}
- name: Build documentation
run: |
make V=1 docs.clean docs.html
- name: Deploy
if: github.ref == 'refs/heads/master'
uses: JamesIves/github-pages-deploy-action@3.7.1
with:
GITHUB_TOKEN: ${{ github.token }}
BRANCH: gh-pages
FOLDER: dist/docs
CLEAN: true # Automatically remove deleted files from the deploy branch
SINGLE_COMMIT: True
COMMIT_MESSAGE: build from commit ${{ github.sha }}
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: "./.nvmrc"
- name: Setup cache Node.js
uses: actions/cache@v4
with:
key: "nodejs-${{ runner.arch }}-${{ hashFiles('./.nvmrc', './package.json') }}"
path: "./client/simple/node_modules/"
- name: Setup cache Python
uses: actions/cache@v4
with:
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
restore-keys: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-"
path: "./local/"
- name: Setup venv
run: make V=1 install
- name: Build
run: make themes.all
babel:
name: Update translations branch
runs-on: ubuntu-20.04
if: ${{ github.repository_owner == 'searxng' && github.ref == 'refs/heads/master' }}
needs:
- python
- themes
- documentation
permissions:
contents: write # for make V=1 weblate.push.translations
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: '0'
token: ${{ secrets.WEBLATE_GITHUB_TOKEN }}
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
architecture: 'x64'
- name: Cache Python dependencies
id: cache-python
uses: actions/cache@v3
with:
path: |
./local
./.nvm
./node_modules
key: python-ubuntu-20.04-3.9-${{ hashFiles('requirements*.txt', 'setup.py','.nvmrc', 'package.json') }}
- name: weblate & git setup
env:
WEBLATE_CONFIG: ${{ secrets.WEBLATE_CONFIG }}
run: |
mkdir -p ~/.config
echo "${WEBLATE_CONFIG}" > ~/.config/weblate
git config --global user.email "searxng-bot@users.noreply.github.com"
git config --global user.name "searxng-bot"
- name: Update transations
id: update
run: |
git restore utils/brand.env
make V=1 weblate.push.translations
dockers:
name: Docker
if: github.ref == 'refs/heads/master'
needs:
- test
- theme
- python
- themes
- documentation
env:
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
runs-on: ubuntu-24.04
runs-on: ubuntu-20.04
steps:
- name: Checkout
if: env.DOCKERHUB_USERNAME != null
@ -112,19 +184,19 @@ jobs:
# make sure "make docker.push" can get the git history
fetch-depth: '0'
- name: Set up Python
uses: actions/setup-python@v5
uses: actions/setup-python@v4
with:
python-version: '3.12'
python-version: '3.9'
architecture: 'x64'
- name: Cache Python dependencies
id: cache-python
uses: actions/cache@v4
uses: actions/cache@v3
with:
path: |
./local
./.nvm
./node_modules
key: python-ubuntu-20.04-3.12-${{ hashFiles('requirements*.txt', 'setup.py','.nvmrc', 'package.json') }}
key: python-ubuntu-20.04-3.9-${{ hashFiles('requirements*.txt', 'setup.py','.nvmrc', 'package.json') }}
- name: Set up QEMU
if: env.DOCKERHUB_USERNAME != null
uses: docker/setup-qemu-action@v1

View File

@ -1,136 +0,0 @@
---
name: Translation
# yamllint disable-line rule:truthy
on:
workflow_dispatch:
workflow_run:
workflows:
- Integration
types:
- completed
branches:
- master
schedule:
- cron: "05 07 * * 5"
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: false
permissions:
contents: read
env:
PYTHON_VERSION: "3.13"
jobs:
update:
if: github.repository_owner == 'searxng' && github.event.workflow_run.conclusion == 'success'
name: Update
runs-on: ubuntu-24.04-arm
permissions:
# For "make V=1 weblate.push.translations"
contents: write
steps:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "${{ env.PYTHON_VERSION }}"
- name: Checkout
uses: actions/checkout@v4
with:
token: "${{ secrets.WEBLATE_GITHUB_TOKEN }}"
fetch-depth: "0"
- name: Setup cache Python
uses: actions/cache@v4
with:
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
restore-keys: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-"
path: "./local/"
- name: Setup venv
run: make V=1 install
- name: Setup Weblate
run: |
mkdir -p ~/.config
echo "${{ secrets.WEBLATE_CONFIG }}" > ~/.config/weblate
- name: Setup Git
run: |
git config --global user.email "searxng-bot@users.noreply.github.com"
git config --global user.name "searxng-bot"
- name: Update translations
run: make V=1 weblate.push.translations
pr:
if: |
github.repository_owner == 'searxng'
&& (github.event_name == 'workflow_dispatch' || github.event_name == 'schedule')
name: Pull Request
runs-on: ubuntu-24.04-arm
permissions:
# For "make V=1 weblate.translations.commit"
contents: write
# For action "peter-evans/create-pull-request"
pull-requests: write
steps:
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "${{ env.PYTHON_VERSION }}"
- name: Checkout
uses: actions/checkout@v4
with:
token: "${{ secrets.WEBLATE_GITHUB_TOKEN }}"
fetch-depth: "0"
- name: Setup cache Python
uses: actions/cache@v4
with:
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
restore-keys: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-"
path: "./local/"
- name: Setup venv
run: make V=1 install
- name: Setup Weblate
run: |
mkdir -p ~/.config
echo "${{ secrets.WEBLATE_CONFIG }}" > ~/.config/weblate
- name: Setup Git
run: |
git config --global user.email "searxng-bot@users.noreply.github.com"
git config --global user.name "searxng-bot"
- name: Merge and push translation updates
run: make V=1 weblate.translations.commit
- name: Create PR
id: cpr
uses: peter-evans/create-pull-request@v7
with:
author: "${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>"
committer: "searxng-bot <searxng-bot@users.noreply.github.com>"
title: "[l10n] update translations from Weblate"
commit-message: "[l10n] update translations from Weblate"
branch: "translations_update"
delete-branch: "true"
draft: "false"
signoff: "false"
labels: |
translation
- name: Display information
run: |
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"

View File

@ -1,43 +1,28 @@
---
name: Security
# yamllint disable-line rule:truthy
name: "Security checks"
on:
workflow_dispatch:
schedule:
- cron: "42 05 * * *"
concurrency:
group: ${{ github.workflow }}-${{ github.ref_name }}
cancel-in-progress: false
permissions:
contents: read
workflow_dispatch:
jobs:
container:
name: Container
runs-on: ubuntu-24.04-arm
permissions:
security-events: write
dockers:
name: Trivy ${{ matrix.image }}
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v4
with:
persist-credentials: "false"
- name: Run Trivy scanner
uses: aquasecurity/trivy-action@0.30.0
- name: Run Trivy vulnerability scanner
uses: aquasecurity/trivy-action@master
with:
image-ref: "docker.io/searxng/searxng:latest"
vuln-type: "os,library"
severity: "UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL"
ignore-unfixed: "false"
format: "sarif"
output: "./trivy-results.sarif"
image-ref: 'searxng/searxng:latest'
ignore-unfixed: false
vuln-type: 'os,library'
severity: 'UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL'
format: 'sarif'
output: 'trivy-results.sarif'
- name: Upload SARIFs
uses: github/codeql-action/upload-sarif@v3
- name: Upload Trivy scan results to GitHub Security tab
uses: github/codeql-action/upload-sarif@v2
with:
sarif_file: "./trivy-results.sarif"
sarif_file: 'trivy-results.sarif'

View File

@ -0,0 +1,59 @@
name: "Update translations"
on:
schedule:
- cron: "05 07 * * 5"
workflow_dispatch:
jobs:
babel:
name: "create PR for additions from weblate"
runs-on: ubuntu-20.04
if: ${{ github.repository_owner == 'searxng' && github.ref == 'refs/heads/master' }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: '0'
token: ${{ secrets.WEBLATE_GITHUB_TOKEN }}
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: '3.9'
architecture: 'x64'
- name: Cache Python dependencies
id: cache-python
uses: actions/cache@v3
with:
path: |
./local
./.nvm
./node_modules
key: python-ubuntu-20.04-3.9-${{ hashFiles('requirements*.txt', 'setup.py','.nvmrc', 'package.json') }}
- name: weblate & git setup
env:
WEBLATE_CONFIG: ${{ secrets.WEBLATE_CONFIG }}
run: |
mkdir -p ~/.config
echo "${WEBLATE_CONFIG}" > ~/.config/weblate
git config --global user.email "searxng-bot@users.noreply.github.com"
git config --global user.name "searxng-bot"
- name: Merge and push transation updates
run: |
make V=1 weblate.translations.commit
- name: Create Pull Request
id: cpr
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.WEBLATE_GITHUB_TOKEN }}
commit-message: Update translations
committer: searxng-bot <searxng-bot@users.noreply.github.com>
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
signoff: false
branch: translations_update
delete-branch: true
draft: false
title: 'Update translations'
body: |
Update translations
labels: |
translation

3
.gitignore vendored
View File

@ -23,6 +23,3 @@ gh-pages/
.idea/
searx/version_frozen.py
.dir-locals.el
.python-version

2
.nvmrc
View File

@ -1 +1 @@
v23.5
v16.15.1

View File

@ -1,4 +1,4 @@
# -*- coding: utf-8; mode: conf-unix -*-
# -*- coding: utf-8; mode: conf -*-
# lint Python modules using external checkers.
#
# This is the main checker controlling the other ones and the reports
@ -27,7 +27,7 @@ ignore-patterns=
#init-hook=
# Use multiple processes to speed up Pylint.
jobs=0
jobs=1
# List of plugins (as comma separated values of python modules names) to load,
# usually to register additional checkers.
@ -338,7 +338,6 @@ valid-metaclass-classmethod-first-arg=mcs
# Maximum number of arguments for function / method
max-args=8
max-positional-arguments=14
# Maximum number of attributes for a class (see R0902).
max-attributes=20

View File

@ -1,4 +0,0 @@
nodejs 23.5.0
python 3.13.1
shellcheck 0.10.0
sqlite 3.47.2

View File

@ -168,12 +168,4 @@ features or generally made searx better:
- Milad Laly @Milad-Laly
- @llmII
- @blob42 `<https://blob42.xyz>`_
- Paolo Basso `<https://github.com/paolobasso99>`
- Bernie Huang `<https://github.com/BernieHuang2008>`
- Austin Olacsi `<https://github.com/Austin-Olacsi>`
- @micsthepick
- Daniel Kukula `<https://github.com/dkuku>`
- Patrick Evans `https://github.com/holysoles`
- Daniel Mowitz `<https://daniel.mowitz.rocks>`
- `Bearz314 <https://github.com/bearz314>`_
- Tommaso Colella `<https://github.com/gioleppe>`
- Paolo Basso `<https://github.com/paolobasso99>`

View File

@ -2,7 +2,7 @@
## Resources in the documentation
* [Development quickstart](https://docs.searxng.org/dev/quickstart.html)
* [Development quickstart](https://docs.searxng.org/dev/contribution_guide.html)
* [Contribution guide](https://docs.searxng.org/dev/contribution_guide.html)
## Submitting PRs

View File

@ -1,107 +1,88 @@
FROM docker.io/library/python:3.13-slim AS builder
FROM alpine:3.18
ENTRYPOINT ["/sbin/tini","--","/usr/local/searxng/dockerfiles/docker-entrypoint.sh"]
EXPOSE 8080
VOLUME /etc/searxng
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
build-essential \
brotli \
# lxml
ARG SEARXNG_GID=977
ARG SEARXNG_UID=977
RUN addgroup -g ${SEARXNG_GID} searxng && \
adduser -u ${SEARXNG_UID} -D -h /usr/local/searxng -s /bin/sh -G searxng searxng
ENV INSTANCE_NAME=searxng \
AUTOCOMPLETE= \
BASE_URL= \
MORTY_KEY= \
MORTY_URL= \
SEARXNG_SETTINGS_PATH=/etc/searxng/settings.yml \
UWSGI_SETTINGS_PATH=/etc/searxng/uwsgi.ini
WORKDIR /usr/local/searxng
COPY requirements.txt ./requirements.txt
RUN apk add --no-cache -t build-dependencies \
build-base \
py3-setuptools \
python3-dev \
libffi-dev \
libxslt-dev \
libxml2-dev \
libxslt1-dev \
zlib1g-dev \
# uwsgi
libpcre3-dev \
&& rm -rf /var/lib/apt/lists/*
openssl-dev \
tar \
git \
&& apk add --no-cache \
ca-certificates \
su-exec \
python3 \
py3-pip \
libxml2 \
libxslt \
openssl \
tini \
uwsgi \
uwsgi-python3 \
brotli \
&& pip3 install --no-cache -r requirements.txt \
&& apk del build-dependencies \
&& rm -rf /root/.cache
WORKDIR /usr/local/searxng/
COPY ./requirements.txt ./requirements.txt
# Readd on #4707 "--mount=type=cache,id=pip,target=/root/.cache/pip"
RUN python -m venv ./venv \
&& . ./venv/bin/activate \
&& pip install -r requirements.txt \
&& pip install "uwsgi~=2.0"
COPY ./searx/ ./searx/
COPY --chown=searxng:searxng dockerfiles ./dockerfiles
COPY --chown=searxng:searxng searx ./searx
ARG TIMESTAMP_SETTINGS=0
ARG TIMESTAMP_UWSGI=0
ARG VERSION_GITCOMMIT=unknown
RUN python -m compileall -q searx \
&& touch -c --date=@$TIMESTAMP_SETTINGS ./searx/settings.yml \
&& touch -c --date=@$TIMESTAMP_UWSGI ./dockerfiles/uwsgi.ini \
&& find /usr/local/searxng/searx/static \
\( -name '*.html' -o -name '*.css' -o -name '*.js' -o -name '*.svg' -o -name '*.ttf' -o -name '*.eot' \) \
-type f -exec gzip -9 -k {} + -exec brotli --best {} +
RUN su searxng -c "/usr/bin/python3 -m compileall -q searx" \
&& touch -c --date=@${TIMESTAMP_SETTINGS} searx/settings.yml \
&& touch -c --date=@${TIMESTAMP_UWSGI} dockerfiles/uwsgi.ini \
&& find /usr/local/searxng/searx/static -a \( -name '*.html' -o -name '*.css' -o -name '*.js' \
-o -name '*.svg' -o -name '*.ttf' -o -name '*.eot' \) \
-type f -exec gzip -9 -k {} \+ -exec brotli --best {} \+
ARG SEARXNG_UID=977
ARG SEARXNG_GID=977
RUN grep -m1 root /etc/group > /tmp/.searxng.group \
&& grep -m1 root /etc/passwd > /tmp/.searxng.passwd \
&& echo "searxng:x:$SEARXNG_GID:" >> /tmp/.searxng.group \
&& echo "searxng:x:$SEARXNG_UID:$SEARXNG_GID:searxng:/usr/local/searxng:/bin/bash" >> /tmp/.searxng.passwd
FROM docker.io/library/python:3.13-slim
RUN apt-get update \
&& apt-get install -y --no-install-recommends \
# healthcheck
wget \
# lxml (ARMv7)
libxslt1.1 \
# uwsgi
libpcre3 \
libxml2 \
mailcap \
&& rm -rf /var/lib/apt/lists/*
COPY --chown=root:root --from=builder /tmp/.searxng.passwd /etc/passwd
COPY --chown=root:root --from=builder /tmp/.searxng.group /etc/group
ARG LABEL_DATE="0001-01-01T00:00:00Z"
ARG GIT_URL="unspecified"
ARG SEARXNG_GIT_VERSION="unspecified"
ARG LABEL_VCS_REF="unspecified"
ARG LABEL_VCS_URL="unspecified"
WORKDIR /usr/local/searxng/
COPY --chown=searxng:searxng --from=builder /usr/local/searxng/venv/ ./venv/
COPY --chown=searxng:searxng --from=builder /usr/local/searxng/searx/ ./searx/
COPY --chown=searxng:searxng ./dockerfiles/ ./dockerfiles/
LABEL org.opencontainers.image.authors="searxng <$GIT_URL>" \
org.opencontainers.image.created=$LABEL_DATE \
org.opencontainers.image.description="A privacy-respecting, hackable metasearch engine" \
org.opencontainers.image.documentation="https://github.com/searxng/searxng-docker" \
org.opencontainers.image.licenses="AGPL-3.0-or-later" \
org.opencontainers.image.revision=$LABEL_VCS_REF \
org.opencontainers.image.source=$LABEL_VCS_URL \
# Keep these arguments at the end to prevent redundant layer rebuilds
ARG LABEL_DATE=
ARG GIT_URL=unknown
ARG SEARXNG_GIT_VERSION=unknown
ARG SEARXNG_DOCKER_TAG=unknown
ARG LABEL_VCS_REF=
ARG LABEL_VCS_URL=
LABEL maintainer="searxng <${GIT_URL}>" \
description="A privacy-respecting, hackable metasearch engine." \
version="${SEARXNG_GIT_VERSION}" \
org.label-schema.schema-version="1.0" \
org.label-schema.name="searxng" \
org.label-schema.version="${SEARXNG_GIT_VERSION}" \
org.label-schema.url="${LABEL_VCS_URL}" \
org.label-schema.vcs-ref=${LABEL_VCS_REF} \
org.label-schema.vcs-url=${LABEL_VCS_URL} \
org.label-schema.build-date="${LABEL_DATE}" \
org.label-schema.usage="https://github.com/searxng/searxng-docker" \
org.opencontainers.image.title="searxng" \
org.opencontainers.image.url=$LABEL_VCS_URL \
org.opencontainers.image.version=$SEARXNG_GIT_VERSION
ENV CONFIG_PATH=/etc/searxng \
DATA_PATH=/var/cache/searxng
ENV SEARXNG_VERSION=$SEARXNG_GIT_VERSION \
INSTANCE_NAME=searxng \
AUTOCOMPLETE="" \
BASE_URL="" \
BIND_ADDRESS=[::]:8080 \
MORTY_KEY="" \
MORTY_URL="" \
SEARXNG_SETTINGS_PATH=$CONFIG_PATH/settings.yml \
UWSGI_SETTINGS_PATH=$CONFIG_PATH/uwsgi.ini \
UWSGI_WORKERS=%k \
UWSGI_THREADS=4
VOLUME $CONFIG_PATH
VOLUME $DATA_PATH
EXPOSE 8080
HEALTHCHECK CMD wget --quiet --tries=1 --spider http://localhost:8080/healthz || exit 1
ENTRYPOINT ["/usr/local/searxng/dockerfiles/docker-entrypoint.sh"]
org.opencontainers.image.version="${SEARXNG_DOCKER_TAG}" \
org.opencontainers.image.url="${LABEL_VCS_URL}" \
org.opencontainers.image.revision=${LABEL_VCS_REF} \
org.opencontainers.image.source=${LABEL_VCS_URL} \
org.opencontainers.image.created="${LABEL_DATE}" \
org.opencontainers.image.documentation="https://github.com/searxng/searxng-docker"

View File

@ -44,19 +44,19 @@ lxc.clean:
PHONY += search.checker search.checker.%
search.checker: install
$(Q)./manage pyenv.cmd searxng-checker -v
$(Q)./manage pyenv.cmd searx-checker -v
search.checker.%: install
$(Q)./manage pyenv.cmd searxng-checker -v "$(subst _, ,$(patsubst search.checker.%,%,$@))"
$(Q)./manage pyenv.cmd searx-checker -v "$(subst _, ,$(patsubst search.checker.%,%,$@))"
PHONY += test ci.test test.shell
ci.test: test.yamllint test.black test.types.ci test.pylint test.unit test.robot test.rst test.shell test.pybabel
test: test.yamllint test.black test.types.dev test.pylint test.unit test.robot test.rst test.shell
ci.test: test.yamllint test.black test.pyright test.pylint test.unit test.robot test.rst test.pybabel
test: test.yamllint test.black test.pyright test.pylint test.unit test.robot test.rst test.shell
test.shell:
$(Q)shellcheck -x -s dash \
dockerfiles/docker-entrypoint.sh
$(Q)shellcheck -x -s bash \
utils/brand.sh \
utils/brand.env \
$(MTOOLS) \
utils/lib.sh \
utils/lib_sxng*.sh \
@ -74,17 +74,19 @@ test.shell:
# wrap ./manage script
MANAGE += buildenv
MANAGE += weblate.translations.commit weblate.push.translations
MANAGE += data.all data.traits data.useragents data.locales data.currencies
MANAGE += data.all data.traits data.useragents
MANAGE += docs.html docs.live docs.gh-pages docs.prebuild docs.clean
MANAGE += docker.build docker.push docker.buildx
MANAGE += gecko.driver
MANAGE += node.env node.env.dev node.clean
MANAGE += py.build py.clean
MANAGE += pyenv pyenv.install pyenv.uninstall
MANAGE += pypi.upload pypi.upload.test
MANAGE += format.python
MANAGE += test.yamllint test.pylint test.black test.pybabel test.unit test.coverage test.robot test.rst test.clean test.themes test.types.dev test.types.ci
MANAGE += themes.all themes.fix themes.test
MANAGE += test.yamllint test.pylint test.pyright test.black test.pybabel test.unit test.coverage test.robot test.rst test.clean
MANAGE += themes.all themes.simple themes.simple.test pygments.less
MANAGE += static.build.commit static.build.drop static.build.restore
MANAGE += nvm.install nvm.clean nvm.status nvm.nodejs

View File

@ -2,7 +2,7 @@
----
.. figure:: https://raw.githubusercontent.com/searxng/searxng/master/client/simple/src/brand/searxng.svg
.. figure:: https://raw.githubusercontent.com/searxng/searxng/master/src/brand/searxng.svg
:target: https://docs.searxng.org/
:alt: SearXNG
:width: 100%
@ -34,7 +34,7 @@ A user_, admin_ and developer_ handbook is available on the homepage_.
.. _homepage: https://docs.searxng.org/
.. _metasearch engine: https://en.wikipedia.org/wiki/Metasearch_engine
.. |SearXNG logo| image:: https://raw.githubusercontent.com/searxng/searxng/master/client/simple/src/brand/searxng-wordmark.svg
.. |SearXNG logo| image:: https://raw.githubusercontent.com/searxng/searxng/master/src/brand/searxng-wordmark.svg
:target: https://docs.searxng.org/
:width: 5%
@ -66,7 +66,7 @@ A user_, admin_ and developer_ handbook is available on the homepage_.
Contact
=======
Ask questions or chat with the SearXNG community (this not a chatbot) on
Ask questions or just chat about SearXNG on
IRC
`#searxng on libera.chat <https://web.libera.chat/?channel=#searxng>`_
@ -121,9 +121,9 @@ You can contribute from your browser using `GitHub Codespaces`_:
- Click on the ``Codespaces`` tab instead of ``Local``
- Click on ``Create codespace on master``
- VSCode is going to start in the browser
- Wait for ``git pull && make install`` to appear and then disappear
- Wait for ``git pull && make install`` to appears and then to disapear
- You have `120 hours per month`_ (see also your `list of existing Codespaces`_)
- You can start SearXNG using ``make run`` in the terminal or by pressing ``Ctrl+Shift+B``
- You can start SearXNG using ``make run`` in the terminal or by pressing ``Ctrl+Shift+B``.
.. _GitHub Codespaces: https://docs.github.com/en/codespaces/overview
.. _120 hours per month: https://github.com/settings/billing

View File

@ -1,3 +0,0 @@
dist
node_modules
.stylelintcache

View File

@ -1,17 +0,0 @@
{
"formatter": "unix",
"plugins": [ "stylelint-prettier" ],
"extends": [ "stylelint-config-standard-less" ],
"rules": {
"prettier/prettier": true,
"declaration-empty-line-before": null,
"no-invalid-position-at-import-rule": null,
"property-no-vendor-prefix": null,
"selector-no-vendor-prefix": null,
"selector-attribute-quotes": null,
"shorthand-property-no-redundant-values": null,
"at-rule-no-vendor-prefix": null,
"selector-id-pattern": null,
"selector-class-pattern": null
}
}

View File

@ -1,24 +0,0 @@
=====================
MEMO vite development
=====================
Local install::
# in folder ./client/simple/
$ npm install
Start development server::
$ ./manage vite.simple.dev
# in folder ./client/simple/
$ npm exec -- vite
Fix source code::
# in folder ./client/simple/
$ npm run fix
Fix & Build::
$ ./manage vite.simple.build

View File

@ -1,34 +0,0 @@
import globals from "globals";
import pluginJs from "@eslint/js";
/** @type {import('eslint').Linter.Config[]} */
export default [
pluginJs.configs.recommended,
// global "ignores"
// https://eslint.org/docs/latest/use/configure/configuration-files#globally-ignoring-files-with-ignores
{
ignores: ["node_modules/", "dist/"]
},
{
files: [
"**/*.js",
],
linterOptions: {
reportUnusedDisableDirectives: "error",
// noInlineConfig: true
},
languageOptions: {
sourceType: "module",
globals: {
...globals.browser,
}
},
rules: {
indent: ["error", 2],
},
},
];

File diff suppressed because it is too large Load Diff

View File

@ -1,41 +0,0 @@
{
"name": "simple",
"version": "1.0.0",
"type": "module",
"scripts": {
"clean": "rm -Rf node_modules",
"build": "node theme_icons.js && vite build",
"fix": "eslint --fix && stylelint --fix strict 'src/**/*.{css,scss,sass,less,styl,vue,svelte}'",
"icons.html": "node theme_icons.js"
},
"devDependencies": {
"@eslint/js": "^9.25.1",
"copy-webpack-plugin": "^13.0.0",
"css-loader": "^7.1.2",
"edge.js": "^6.2.1",
"eslint": "^9.25.1",
"filemanager-webpack-plugin": "^8.0.0",
"globals": "^16.0.0",
"ionicons": "^8.0.8",
"leaflet": "^1.9.4",
"less": "^4.3.0",
"less-loader": "^12.3.0",
"normalize.css": "^8.0.1",
"sharp": "^0.34.1",
"style-loader": "^4.0.0",
"stylelint": "^16.19.1",
"stylelint-config-standard": "^38.0.0",
"stylelint-config-standard-less": "^3.0.1",
"stylelint-prettier": "^5.0.3",
"svgo": "^3.3.2",
"swiped-events": "^1.2.0",
"vite": "^6.3.4",
"vite-plugin-static-copy": "^2.3.1",
"vite-plugin-stylelint": "^6.0.0",
"webpack": "^5.99.7",
"webpack-cli": "^6.0.1"
},
"dependencies": {
"autocomplete-js": "^2.7.1"
}
}

View File

@ -1,26 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="21.508125mm"
height="21.508017mm"
viewBox="0 0 21.508125 21.508015"
version="1.1"
id="svg1"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg">
<defs
id="defs1" />
<g
id="layer1"
transform="translate(-54.245938,-114.24604)">
<path
style="fill:#222222;fill-opacity:1;stroke:#ffffff;stroke-width:1.50812;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 55,115 5.000001,4.99999 h 5 L 75,130 70.000002,135 H 60.000001 L 55,130 Z"
id="path2" />
<path
style="fill:#222222;fill-opacity:1;stroke:#ffffff;stroke-width:1.50812;stroke-linejoin:round;stroke-dasharray:none;stroke-opacity:1;paint-order:stroke fill markers"
d="m 67,119.99999 h 3.000002 L 75,115 v 12.99999 z"
id="path3" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 980 B

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 310 KiB

View File

@ -1,184 +0,0 @@
/* SPDX-License-Identifier: AGPL-3.0-or-later */
import "../../../node_modules/swiped-events/src/swiped-events.js";
(function (w, d, searxng) {
'use strict';
if (searxng.endpoint !== 'results') {
return;
}
searxng.ready(function () {
d.querySelectorAll('#urls img').forEach(
img =>
img.addEventListener(
'error', () => {
// console.log("ERROR can't load: " + img.src);
img.src = window.searxng.settings.theme_static_path + "/img/img_load_error.svg";
},
{once: true}
));
if (d.querySelector('#search_url button#copy_url')) {
d.querySelector('#search_url button#copy_url').style.display = "block";
}
searxng.on('.btn-collapse', 'click', function () {
var btnLabelCollapsed = this.getAttribute('data-btn-text-collapsed');
var btnLabelNotCollapsed = this.getAttribute('data-btn-text-not-collapsed');
var target = this.getAttribute('data-target');
var targetElement = d.querySelector(target);
var html = this.innerHTML;
if (this.classList.contains('collapsed')) {
html = html.replace(btnLabelCollapsed, btnLabelNotCollapsed);
} else {
html = html.replace(btnLabelNotCollapsed, btnLabelCollapsed);
}
this.innerHTML = html;
this.classList.toggle('collapsed');
targetElement.classList.toggle('invisible');
});
searxng.on('.media-loader', 'click', function () {
var target = this.getAttribute('data-target');
var iframe_load = d.querySelector(target + ' > iframe');
var srctest = iframe_load.getAttribute('src');
if (srctest === null || srctest === undefined || srctest === false) {
iframe_load.setAttribute('src', iframe_load.getAttribute('data-src'));
}
});
searxng.on('#copy_url', 'click', function () {
var target = this.parentElement.querySelector('pre');
navigator.clipboard.writeText(target.innerText);
this.innerText = this.dataset.copiedText;
});
// searxng.selectImage (gallery)
// -----------------------------
// setTimeout() ID, needed to cancel *last* loadImage
let imgTimeoutID;
// progress spinner, while an image is loading
const imgLoaderSpinner = d.createElement('div');
imgLoaderSpinner.classList.add('loader');
// singleton image object, which is used for all loading processes of a
// detailed image
const imgLoader = new Image();
const loadImage = (imgSrc, onSuccess) => {
// if defered image load exists, stop defered task.
if (imgTimeoutID) clearTimeout(imgTimeoutID);
// defer load of the detail image for 1 sec
imgTimeoutID = setTimeout(() => {
imgLoader.src = imgSrc;
}, 1000);
// set handlers in the on-properties
imgLoader.onload = () => {
onSuccess();
imgLoaderSpinner.remove();
};
imgLoader.onerror = () => {
imgLoaderSpinner.remove();
};
};
searxng.selectImage = (resultElement) => {
// add a class that can be evaluated in the CSS and indicates that the
// detail view is open
d.getElementById('results').classList.add('image-detail-open');
// add a hash to the browser history so that pressing back doesn't return
// to the previous page this allows us to dismiss the image details on
// pressing the back button on mobile devices
window.location.hash = '#image-viewer';
searxng.scrollPageToSelected();
// if there is none element given by the caller, stop here
if (!resultElement) return;
// find <img> object in the element, if there is none, stop here.
const img = resultElement.querySelector('.result-images-source img');
if (!img) return;
// <img src="" data-src="http://example.org/image.jpg">
const src = img.getAttribute('data-src');
// already loaded high-res image or no high-res image available
if (!src) return;
// use the image thumbnail until the image is fully loaded
const thumbnail = resultElement.querySelector('.image_thumbnail');
img.src = thumbnail.src;
// show a progress spinner
const detailElement = resultElement.querySelector('.detail');
detailElement.appendChild(imgLoaderSpinner);
// load full size image in background
loadImage(src, () => {
// after the singelton loadImage has loaded the detail image into the
// cache, it can be used in the origin <img> as src property.
img.src = src;
img.removeAttribute('data-src');
});
};
searxng.closeDetail = function () {
d.getElementById('results').classList.remove('image-detail-open');
// remove #image-viewer hash from url by navigating back
if (window.location.hash == '#image-viewer') window.history.back();
searxng.scrollPageToSelected();
};
searxng.on('.result-detail-close', 'click', e => {
e.preventDefault();
searxng.closeDetail();
});
searxng.on('.result-detail-previous', 'click', e => {
e.preventDefault();
searxng.selectPrevious(false);
});
searxng.on('.result-detail-next', 'click', e => {
e.preventDefault();
searxng.selectNext(false);
});
// listen for the back button to be pressed and dismiss the image details when called
window.addEventListener('hashchange', () => {
if (window.location.hash != '#image-viewer') searxng.closeDetail();
});
d.querySelectorAll('.swipe-horizontal').forEach(
obj => {
obj.addEventListener('swiped-left', function () {
searxng.selectNext(false);
});
obj.addEventListener('swiped-right', function () {
searxng.selectPrevious(false);
});
}
);
w.addEventListener('scroll', function () {
var e = d.getElementById('backToTop'),
scrollTop = document.documentElement.scrollTop || document.body.scrollTop,
results = d.getElementById('results');
if (e !== null) {
if (scrollTop >= 100) {
results.classList.add('scrolling');
} else {
results.classList.remove('scrolling');
}
}
}, true);
});
})(window, document, window.searxng);

View File

@ -1 +0,0 @@
import "./head/00_init.js";

View File

@ -1,7 +0,0 @@
import "./main/00_toolkit.js";
import "./main/infinite_scroll.js";
import "./main/keyboard.js";
import "./main/mapresult.js";
import "./main/preferences.js";
import "./main/results.js";
import "./main/search.js";

View File

@ -1,35 +0,0 @@
/*
Layout of the KeyValue result class
*/
#main_results .result-keyvalue {
caption {
padding: 0.8rem 0.5rem;
font-style: italic;
caption-side: bottom;
background-color: var(--color-result-keyvalue-table);
}
.col-key {
width: 25%;
}
table {
word-break: break-word;
table-layout: fixed;
width: 100%;
background-color: var(--color-result-keyvalue-table);
}
tr.odd {
background-color: var(--color-result-keyvalue-odd);
}
tr.even {
background-color: var(--color-result-keyvalue-even);
}
th,
td {
padding: 0.3rem 0.5rem;
}
}

View File

@ -1,45 +0,0 @@
@import (inline) "../../node_modules/normalize.css/normalize.css";
@import "definitions.less";
.text-size-adjust (@property: 100%) {
-webkit-text-size-adjust: @property;
-ms-text-size-adjust: @property;
-moz-text-size-adjust: @property;
text-size-adjust: @property;
}
// Reset padding and margin
html,
body,
main {
padding: 0;
margin: 0;
}
html {
font-family: sans-serif;
font-size: 0.9em;
.text-size-adjust;
color: var(--color-base-font);
background-color: var(--color-base-background);
scroll-behavior: smooth;
}
body {
margin-inline: 1rem;
}
a {
text-decoration: none;
color: var(--color-url-font);
&:visited {
color: var(--color-url-visited-font);
.highlight {
color: var(--color-url-visited-font);
}
}
}

View File

@ -1,29 +0,0 @@
.loader,
.loader::after {
border-radius: 50%;
width: 10em;
height: 10em;
}
.loader {
margin: 60px auto;
font-size: 10px;
position: relative;
text-indent: -9999em;
border-top: 1.1em solid var(--color-loading-indicator);
border-right: 1.1em solid var(--color-loading-indicator);
border-bottom: 1.1em solid var(--color-loading-indicator);
border-left: 1.1em solid var(--color-loading-indicator-gap);
transform: translateZ(0);
animation: load8 1.1s infinite linear;
}
@keyframes load8 {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}

View File

@ -1,4 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<path fill="#58f" d="M11 20.85a.92.92 0 0 1-1.1.93A10 10 0 0 1 2.06 13c-.06-.55.4-1 .95-1h3a1 1 0 0 1 1 1 3 3 0 0 0 3 3 1 1 0 0 1 1 1v3.85Zm6-1.92c0 .77.83 1.23 1.42.74a10 10 0 0 0 2.03-2.32c.39-.61-.09-1.35-.81-1.35H18a1 1 0 0 0-1 1v1.93ZM12 2a10 10 0 0 1 6.65 2.53c.61.55.17 1.47-.65 1.47h-.15A2.85 2.85 0 0 0 15 8.85c0 .33-.18.62-.47.77l-.08.04a1 1 0 0 1-.9 0l-.08-.04a.85.85 0 0 1-.47-.77A2.85 2.85 0 0 0 10.15 6H10a1 1 0 0 1-1-1V3.2c0-.44.28-.84.7-.94C10.45 2.1 11.22 2 12 2Z"/>
<path fill="#58f" d="M3.42 10c-.63 0-1.1-.58-.9-1.18.6-1.8 1.7-3.36 3.12-4.53C6.2 3.82 7 4.26 7 5a3 3 0 0 0 3 3h.15c.47 0 .85.38.85.85 0 1.09.61 2.07 1.58 2.56l.08.04a3 3 0 0 0 2.68 0l.08-.04A2.85 2.85 0 0 0 17 8.85c0-.47.38-.85.85-.85h2.66c.4 0 .77.23.9.6a9.98 9.98 0 0 1 .52 4.6.94.94 0 0 1-.95.8H18a3 3 0 0 0-3 3v3.8c0 .44-.28.84-.7.94l-.2.04a.92.92 0 0 1-1.1-.93V17a3 3 0 0 0-3-3 1 1 0 0 1-1-1 3 3 0 0 0-3-3H3.42Z"/>
</svg>

Before

Width:  |  Height:  |  Size: 989 B

View File

@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M248 64C146.39 64 64 146.39 64 248s82.39 184 184 184 184-82.39 184-184S349.61 64 248 64z" fill="none" stroke="currentColor" stroke-miterlimit="10" stroke-width="32"/>
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32" d="M220 220h32v116"/>
<path fill="none" stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="32" d="M208 340h88"/>
<path d="M248 130a26 26 0 1026 26 26 26 0 00-26-26z" fill="currentColor" stroke="currentColor" stroke-miterlimit="10" stroke-width="1"/>
</svg>

Before

Width:  |  Height:  |  Size: 648 B

View File

@ -1,6 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512">
<path d="M368 415.86V72a24.07 24.07 0 00-24-24H72a24.07 24.07 0 00-24 24v352a40.12 40.12 0 0040 40h328" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32"/>
<path d="M416 464h0a48 48 0 01-48-48V128h72a24 24 0 0124 24v264a48 48 0 01-48 48z" fill="none" stroke="currentColor" stroke-linejoin="round" stroke-width="32"/>
<path d="M240 128h64M240 192h64M112 256h192M112 320h192M112 384h192" fill="none" stroke="currentColor" stroke-linecap="round" stroke-linejoin="round" stroke-width="32"/>
<path d="M176 208h-64a16 16 0 01-16-16v-64a16 16 0 0116-16h64a16 16 0 0116 16v64a16 16 0 01-16 16z" fill="currentColor" stroke="currentColor" stroke-linejoin="round" stroke-width="1" />
</svg>

Before

Width:  |  Height:  |  Size: 787 B

View File

@ -1,2 +0,0 @@
leaflet.css -diff
leaflet.js -diff

View File

@ -1,84 +0,0 @@
/**
* Generate icons.html for the jinja templates of the simple theme.
*/
import { argv } from "node:process";
import { dirname, resolve } from "node:path";
import { jinja_svg_sets } from "./tools/jinja_svg_catalog.js";
const HERE = dirname(argv[1]) + "/";
const dest = resolve(HERE, "../../searx/templates/simple/icons.html");
/** @type import("./tools/jinja_svg_catalog.js").JinjaMacro[] */
const searxng_jinja_macros = [
{ name: "icon", class: "sxng-icon-set" },
{ name: "icon_small", class: "sxng-icon-set-small" },
{ name: "icon_big", class: "sxng-icon-set-big" },
];
const sxng_icon_opts ={
multipass: true,
plugins: [
{ name: "removeTitle" },
{ name: "removeXMLNS" },
{ name: "addAttributesToSVGElement",
params: {
attributes: [
{
"aria-hidden": "true",
}]}}]
};
/** @type import("./tools/jinja_svg_catalog.js").IconSet */
const simple_icons = [
{
base: resolve(HERE, "node_modules/ionicons/dist/svg"),
set: {
"alert": "alert-outline.svg",
"appstore": "apps-outline.svg",
"book": "book-outline.svg",
"close": "close-outline.svg",
"download": "download-outline.svg",
"ellipsis-vertical": "ellipsis-vertical-outline.svg",
"file-tray-full": "file-tray-full-outline.svg",
"film": "film-outline.svg",
"globe": "globe-outline.svg",
"heart": "heart-outline.svg",
"image": "image-outline.svg",
"layers": "layers-outline.svg",
"leecher": "arrow-down.svg",
"location": "location-outline.svg",
"magnet": "magnet-outline.svg",
"musical-notes": "musical-notes-outline.svg",
"navigate-down": "chevron-down-outline.svg",
"navigate-left": "chevron-back-outline.svg",
"navigate-right": "chevron-forward-outline.svg",
"navigate-up": "chevron-up-outline.svg",
"people": "people-outline.svg",
"play": "play-outline.svg",
"radio": "radio-outline.svg",
"save": "save-outline.svg",
"school": "school-outline.svg",
"search": "search-outline.svg",
"seeder": "swap-vertical.svg",
"settings": "settings-outline.svg",
"tv": "tv-outline.svg",
},
svgo_opts: sxng_icon_opts,
},
// some of the ionicons are not suitable for a dark theme, we fixed the svg
// manually in src/svg/ionicons
// - https://github.com/searxng/searxng/pull/4284#issuecomment-2680550342
{
base: resolve(HERE, "src/svg/ionicons"),
set: {
"information-circle": "information-circle-outline.svg",
"newspaper": "newspaper-outline.svg",
},
svgo_opts: sxng_icon_opts,
}
];
jinja_svg_sets(dest, searxng_jinja_macros, simple_icons);

View File

@ -1,78 +0,0 @@
import fs from "fs";
import path from "path";
import sharp from "sharp";
import { optimize as svgo } from "svgo";
/**
* @typedef {object} Src2Dest - Mapping of src to dest
* @property {string} src - Name of the source file.
* @property {string} dest - Name of the destination file.
*/
/**
* Convert a list of SVG files to PNG.
*
* @param {Src2Dest[]} items - Array of SVG files (src: SVG, dest:PNG) to convert.
*/
async function svg2png (items) {
items.forEach(
async (item) => {
try {
fs.mkdir(path.dirname(item.dest), { recursive: true }, (err) => {
if (err)
throw err;
});
const info = await sharp(item.src).png({
force: true,
compressionLevel: 9,
palette: true,
}).toFile(item.dest);
console.log(
`[svg2png] created ${item.dest} -- bytes: ${info.size}, w:${info.width}px, h:${info.height}px`
);
} catch (err) {
console.error(`ERROR: ${item.dest} -- ${err}`);
throw(err);
}
}
);
}
/**
* Optimize SVG images for WEB.
*
* @param {import('svgo').Config} svgo_opts - Options passed to svgo.
* @param {Src2Dest[]} items - Array of SVG files (src:SVG, dest:SVG) to optimize.
*/
async function svg2svg(svgo_opts, items) {
items.forEach(
async (item) => {
try {
fs.mkdir(path.dirname(item.dest), { recursive: true }, (err) => {
if (err)
throw err;
});
const raw = fs.readFileSync(item.src, "utf8");
const opt = svgo(raw, svgo_opts);
fs.writeFileSync(item.dest, opt.data);
console.log(
`[svg2svg] optimized: ${item.dest} -- src: ${item.src}`
);
} catch (err) {
console.error(`ERROR: optimize src: ${item.src} -- ${err}`);
throw(err);
}
}
);
}
export { svg2png, svg2svg };

View File

@ -1,26 +0,0 @@
{{--
This is a EDGE https://edgejs.dev/ template to generate a HTML Jinja template
for the backend. Example output of this EDGE template:
- https://github.com/searxng/searxng/blob/master/searx/templates/simple/icons.html
--}}
{#
Catalog of SVG symbols that can be inserted into the HTML output of a Jinja
template. This file from:
client/simple/tools/icon_catalog.edge.html
#}
{%-
set catalog = {
@each((svg, name) in svg_catalog)
'{{{name}}}' : '{{{svg}}}',
@end
}
-%}
@each(macro in macros)
{% macro {{ macro.name }}(action, alt) -%}
{{ open_curly_brace }} catalog[action] | replace("{{__jinja_class_placeholder__}}", "{{ macro.class }}") | safe {{ close_curly_brace }}
{%- endmacro %}
@end

View File

@ -1,132 +0,0 @@
import fs from "fs";
import { resolve, dirname } from "path";
import { Edge } from 'edge.js';
import { optimize as svgo } from "svgo";
import { fileURLToPath } from 'url';
const __dirname = dirname(fileURLToPath(import.meta.url));
const __jinja_class_placeholder__ = "__jinja_class_placeholder__";
// -- types
/**
* @typedef {object} IconSet - A set of icons
* @property {object[]} set - Array of SVG icons, where property name is the
* name of the icon and value is the src of the SVG (relative to base).
* @property {string} base - Folder in which the SVG src files are located.
* @property {import("svgo").Config} svgo_opts - svgo options for this set.
*/
/**
* @typedef {object} IconSVG - Mapping of icon name to SVG source file.
* @property {string} name - Name of the icon isource file.
* @property {string} src - Name of the destination file.
* @property {import("svgo").Config} svgo_opts - Options passed to svgo.
*/
/**
* @typedef {object} JinjaMacro - Arguments to create a jinja macro
* @property {string} name - Name of the jinja macro.
* @property {string} class - SVG's class name (value of XML class attribute)
*/
// -- functions
/**
* Generate a jinja template with a catalog of SVG icons that can be
* used in in other HTML jinja templates.
*
* @param {string} dest - filename of the generate jinja template.
* @param {JinjaMacro} macros - Jinja macros to create.
* @param {IconSVG[]} items - Array of SVG items.
*/
function jinja_svg_catalog(dest, macros, items) {
const svg_catalog = {};
const edge_template = resolve(__dirname, "jinja_svg_catalog.html.edge");
items.forEach(
(item) => {
/** @type {import("svgo").Config} */
// JSON.stringify & JSON.parse are used to create a deep copy of the
// item.svgo_opts object
const svgo_opts = JSON.parse(JSON.stringify(item.svgo_opts));
svgo_opts.plugins.push({
name: "addClassesToSVGElement",
params: {
classNames: [__jinja_class_placeholder__]
}}
);
try {
const raw = fs.readFileSync(item.src, "utf8");
const opt = svgo(raw, svgo_opts);
svg_catalog[item.name] = opt.data;
} catch (err) {
console.error(`ERROR: jinja_svg_catalog processing ${item.name} src: ${item.src} -- ${err}`);
throw(err);
}
}
);
fs.mkdir(dirname(dest), { recursive: true }, (err) => {
if (err) throw err;
});
const ctx = {
svg_catalog: svg_catalog,
macros: macros,
edge_template: edge_template,
__jinja_class_placeholder__: __jinja_class_placeholder__,
// see https://github.com/edge-js/edge/issues/162
open_curly_brace : "{{",
close_curly_brace : "}}"
};
const jinjatmpl = Edge.create().renderRawSync(
fs.readFileSync(edge_template, "utf-8"),
ctx
);
fs.writeFileSync(dest, jinjatmpl);
console.log(`[jinja_svg_catalog] created: ${dest}`);
}
/**
* Calls jinja_svg_catalog for a collection of icon sets where each set has its
* own parameters.
*
* @param {string} dest - filename of the generate jinja template.
* @param {JinjaMacro} macros - Jinja macros to create.
* @param {IconSet[]} sets - Array of SVG sets.
*/
function jinja_svg_sets(dest, macros, sets) {
/** @type IconSVG[] */
const items = [];
const all = [];
for (const obj of sets) {
for (const [name, file] of Object.entries(obj.set)) {
if (all.includes(name)) {
throw new Error(`ERROR: ${name} has already been defined`);
}
items.push({
name: name,
src: resolve(obj.base, file),
svgo_opts: obj.svgo_opts,
});
}
jinja_svg_catalog(dest, macros, items);
}
}
// -- exports
export {
jinja_svg_sets,
jinja_svg_catalog,
};

View File

@ -1,41 +0,0 @@
/**
* Custom vite plugins to build the web-client components of the simple theme.
*
* HINT:
*
* This is an inital implementation for the migration of the build process
* from grunt to vite. For fully support (vite: build & serve) more work is
* needed.
*/
import { svg2png } from "./img.js";
import { svg2svg } from "./img.js";
/**
* Vite plugin to convert a list of SVG files to PNG.
*
* @param {import('./img.js').Src2Dest} items - Array of SVG files (src: SVG, dest:PNG) to convert.
*/
function plg_svg2png(items) {
return {
name: 'searxng-simple-svg2png',
apply: 'build', // or 'serve'
async writeBundle() { svg2png(items); },
};
}
/**
* Vite plugin to optimize SVG images for WEB.
*
* @param {import('svgo').Config} svgo_opts - Options passed to svgo.
* @param {import('./img.js').Src2Dest} items - Array of SVG files (src:SVG, dest:SVG) to optimize.
*/
function plg_svg2svg(svgo_opts, items) {
return {
name: 'searxng-simple-svg2png',
apply: 'build', // or 'serve'
async writeBundle() { svg2svg(items, svgo_opts); },
};
}
export { plg_svg2png, plg_svg2svg };

View File

@ -1,185 +0,0 @@
/**
* CONFIG: https://vite.dev/config/
*/
import { resolve } from "node:path";
import { defineConfig } from "vite";
import stylelint from "vite-plugin-stylelint";
import { viteStaticCopy } from "vite-plugin-static-copy";
import { plg_svg2png } from "./tools/plg.js";
import { plg_svg2svg } from "./tools/plg.js";
const ROOT = "../.."; // root of the git reposetory
const PATH = {
dist: resolve(ROOT, "searx/static/themes/simple"),
// dist: resolve(ROOT, "client/simple/dist"),
src: "src",
modules: "node_modules",
brand: "src/brand",
static: resolve(ROOT, "client/simple/static"),
leaflet: resolve(ROOT, "client/simple/node_modules/leaflet/dist"),
templates: resolve(ROOT, "searx/templates/simple"),
};
const svg2svg_opts = {
plugins: [
{ name: "preset-default" },
"sortAttrs",
"convertStyleToAttrs",
]
};
const svg2svg_favicon_opts = {
plugins: [
{ name: "preset-default" },
"sortAttrs",
]
};
export default defineConfig({
root: PATH.src,
mode: "production",
// mode: "development",
// FIXME: missing CCS sourcemaps!!
// see: https://github.com/vitejs/vite/discussions/13845#discussioncomment-11992084
//
// what I have tried so far (see config below):
//
// - build.sourcemap
// - esbuild.sourcemap
// - css.preprocessorOptions.less.sourceMap
css: {
devSourcemap: true,
preprocessorOptions: {
less: {
// FIXME: missing CCS sourcemaps!!
sourceMap: {
outputSourceFiles: true,
sourceMapURL: (name) => { const s = name.split('/'); return s[s.length - 1] + '.map'; },
},
// env: 'development',
// relativeUrls: true,
// javascriptEnabled: true,
},
},
}, // end: css
esbuild : {
// FIXME: missing CCS sourcemaps!!
sourcemap: true
},
build: {
manifest: "manifest.json",
emptyOutDir: true,
assetsDir: "",
outDir: PATH.dist,
// FIXME: missing CCS sourcemaps!!
sourcemap: true,
// https://vite.dev/config/build-options.html#build-cssminify
cssMinify: true,
// cssMinify: "esbuild",
minify: "esbuild",
rollupOptions: {
input: {
// build CSS files
"css/searxng.min.css": PATH.src + "/less/style-ltr.less",
"css/searxng-rtl.min.css": PATH.src + "/less/style-rtl.less",
"css/rss.min.css": PATH.src + "/less/rss.less",
// build JS files
"js/searxng.head.min": PATH.src + "/js/searxng.head.js",
"js/searxng.min": PATH.src + "/js/searxng.js",
},
// file naming conventions / pathnames are relative to outDir (PATH.dist)
output: {
entryFileNames: "[name].js",
chunkFileNames: "[name].js",
assetFileNames: "[name].[ext]",
// Vite does not support "rollupOptions.output.sourcemap".
// Please use "build.sourcemap" instead.
// sourcemap: true,
},
},
}, // end: build
plugins: [
stylelint({
build: true,
emitWarningAsError: true,
fix: true,
}),
// Leaflet
viteStaticCopy({
targets: [
{ src: PATH.leaflet + "/leaflet.{js,js.map}", dest: PATH.dist + "/js" },
{ src: PATH.leaflet + "/images/*.png", dest: PATH.dist + "/css/images/" },
{ src: PATH.leaflet + "/*.{css,css.map}", dest: PATH.dist + "/css" },
{ src: PATH.static + "/**/*", dest: PATH.dist },
]
}),
// -- svg images
plg_svg2svg(
[
{ src: PATH.src + "/svg/empty_favicon.svg", dest: PATH.dist + "/img/empty_favicon.svg" },
{ src: PATH.src + "/svg/select-dark.svg", dest: PATH.dist + "/img/select-dark.svg" },
{ src: PATH.src + "/svg/select-light.svg", dest: PATH.dist + "/img/select-light.svg" },
],
svg2svg_opts,
),
// SearXNG brand (static)
plg_svg2png(
[
{ src: PATH.brand + "/searxng-wordmark.svg", dest: PATH.dist + "/img/favicon.png" },
{ src: PATH.brand + "/searxng.svg", dest: PATH.dist + "/img/searxng.png" },
],
),
// -- svg
plg_svg2svg(
[
{ src: PATH.brand + "/searxng.svg", dest: PATH.dist + "/img/searxng.svg" },
{ src: PATH.brand + "/img_load_error.svg", dest: PATH.dist + "/img/img_load_error.svg" },
],
svg2svg_opts,
),
// -- favicon
plg_svg2svg(
[ { src: PATH.brand + "/searxng-wordmark.svg", dest: PATH.dist + "/img/favicon.svg" } ],
svg2svg_favicon_opts,
),
// -- simple templates
plg_svg2svg(
[
{ src: PATH.brand + "/searxng-wordmark.svg", dest: PATH.templates + "/searxng-wordmark.min.svg" },
],
svg2svg_opts
),
] // end: plugins
});

View File

@ -1,7 +0,0 @@
services:
nekosearch:
build: .
pull_policy: build
restart: unless-stopped
ports:
- "${NEKOSEARCH_PORT}:8080"

View File

@ -14,6 +14,8 @@ Environment variables:
BASE_URL settings.yml : server.base_url
MORTY_URL settings.yml : result_proxy.url
MORTY_KEY settings.yml : result_proxy.key
BIND_ADDRESS uwsgi bind to the specified TCP socket using HTTP protocol.
Default value: ${DEFAULT_BIND_ADDRESS}
Volume:
/etc/searxng the docker entry point copies settings.yml and uwsgi.ini in
this directory (see the -f command line option)"
@ -21,6 +23,9 @@ Volume:
EOF
}
export DEFAULT_BIND_ADDRESS="0.0.0.0:8080"
export BIND_ADDRESS="${BIND_ADDRESS:-${DEFAULT_BIND_ADDRESS}}"
# Parse command line
FORCE_CONF_UPDATE=0
DRY_RUN=0
@ -43,7 +48,15 @@ do
esac
done
echo "SearXNG version $SEARXNG_VERSION"
get_searxng_version(){
su searxng -c \
'python3 -c "import six; import searx.version; six.print_(searx.version.VERSION_STRING)"' \
2>/dev/null
}
SEARXNG_VERSION="$(get_searxng_version)"
export SEARXNG_VERSION
echo "SearXNG version ${SEARXNG_VERSION}"
# helpers to update the configuration files
patch_uwsgi_settings() {
@ -68,7 +81,7 @@ patch_searxng_settings() {
-e "s|base_url: false|base_url: ${BASE_URL}|g" \
-e "s/instance_name: \"SearXNG\"/instance_name: \"${INSTANCE_NAME}\"/g" \
-e "s/autocomplete: \"\"/autocomplete: \"${AUTOCOMPLETE}\"/g" \
-e "s/ultrasecretkey/$(head -c 24 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9')/g" \
-e "s/ultrasecretkey/$(openssl rand -hex 32)/g" \
"${CONF}"
# Morty configuration
@ -160,8 +173,6 @@ fi
unset MORTY_KEY
printf 'Listen on %s\n' "${BIND_ADDRESS}"
# Start uwsgi
# TODO: "--http-socket" will be removed in the future (see uwsgi.ini.new config file): https://github.com/searxng/searxng/pull/4578
exec /usr/local/searxng/venv/bin/uwsgi --http-socket "${BIND_ADDRESS}" "${UWSGI_SETTINGS_PATH}"
printf 'Listen on %s\n' "${BIND_ADDRESS}"
exec su-exec searxng:searxng uwsgi --master --http-socket "${BIND_ADDRESS}" "${UWSGI_SETTINGS_PATH}"

View File

@ -1,19 +1,11 @@
[uwsgi]
# Listening address
# default value: [::]:8080 (see Dockerfile)
http-socket = $(BIND_ADDRESS)
# Who will run the code
uid = searxng
gid = searxng
# Number of workers (usually CPU count)
# default value: %k (= number of CPU core, see Dockerfile)
workers = $(UWSGI_WORKERS)
# Number of threads per worker
# default value: 4 (see Dockerfile)
threads = $(UWSGI_THREADS)
workers = %k
threads = 4
# The right granted on the created socket
chmod-socket = 666
@ -21,6 +13,7 @@ chmod-socket = 666
# Plugin to use and interpreter config
single-interpreter = true
master = true
plugin = python3
lazy-apps = true
enable-threads = true
@ -45,11 +38,9 @@ buffer-size = 8192
# See https://github.com/searx/searx-docker/issues/24
add-header = Connection: close
# Follow SIGTERM convention
# See https://github.com/searxng/searxng/issues/3427
die-on-term
# uwsgi serves the static files
# expires set to one year since there are hashes
static-map = /static=/usr/local/searxng/searx/static
static-expires = /* 31557600
static-gzip-all = True
offload-threads = %k

View File

@ -69,6 +69,10 @@ Sample response
{
"enabled": true,
"name": "HTTPS rewrite"
},
{
"enabled": false,
"name": "Vim-like hotkeys"
}
],
"safe_search": 0
@ -84,9 +88,9 @@ HTML of the site. URL of the SearXNG instance and values are customizable.
.. code:: html
<form method="post" action="https://example.org/">
<!-- search --> <input type="text" name="q">
<!-- categories --> <input type="hidden" name="categories" value="general,social media">
<!-- language --> <input type="hidden" name="lang" value="all">
<!-- locale --> <input type="hidden" name="locale" value="en">
<!-- date filter --> <input type="hidden" name="time_range" value="month">
<!-- search --> <input type="text" name="q" />
<!-- categories --> <input type="hidden" name="categories" value="general,social media" />
<!-- language --> <input type="hidden" name="lang" value="all" />
<!-- locale --> <input type="hidden" name="locale" value="en" />
<!-- date filter --> <input type="hidden" name="time_range" value="month" />
</form>

View File

@ -15,8 +15,6 @@ Administrator documentation
installation-apache
update-searxng
answer-captcha
searx.favicons
searx.limiter
api
architecture
plugins

View File

@ -190,7 +190,7 @@ Debian:
Apache modules
--------------
To load additional modules, in most distributions you have to uncomment the
To load additional modules, in most distributions you have to un-comment the
lines with the corresponding LoadModule_ directive, except in :ref:`Debian's
Apache layout`.

View File

@ -92,9 +92,6 @@ instance using `docker run <https://docs.docker.com/engine/reference/run/>`_:
searxng/searxng
2f998.... # container's ID
The environment variables UWSGI_WORKERS and UWSGI_THREADS overwrite the default
number of UWSGI processes and UWSGI threads specified in `/etc/searxng/uwsgi.ini`.
Open your WEB browser and visit the URL:
.. code:: sh

View File

@ -96,7 +96,7 @@ Modify the ``/etc/searxng/settings.yml`` to your needs:
.. literalinclude:: ../../utils/templates/etc/searxng/settings.yml
:language: yaml
:end-before: # preferences:
:end-before: # hostname_replace:
To see the entire file jump to :origin:`utils/templates/etc/searxng/settings.yml`
@ -104,7 +104,7 @@ Modify the ``/etc/searxng/settings.yml`` to your needs:
.. literalinclude:: ../../searx/settings.yml
:language: yaml
:end-before: # hostnames:
:end-before: # hostname_replace:
To see the entire file jump to :origin:`searx/settings.yml`

View File

@ -1,13 +1,16 @@
.. _plugins admin:
.. _plugins generic:
===============
List of plugins
Plugins builtin
===============
Further reading ..
.. sidebar:: Further reading ..
- :ref:`SearXNG settings <settings plugins>`
- :ref:`dev plugin`
- :ref:`dev plugin`
Configuration defaults (at built time):
:DO: Default on
.. _configured plugins:
@ -19,13 +22,18 @@ Further reading ..
:widths: 3 1 9
* - Name
- Active
- DO
- Description
{% for plg in plugins %}
JS & CSS dependencies
* - {{plg.info.name}}
- {{(plg.active and "yes") or "no"}}
- {{plg.info.description}}
{% for plgin in plugins %}
* - {{plgin.name}}
- {{(plgin.default_on and "y") or ""}}
- {{plgin.description}}
{% for dep in (plgin.js_dependencies + plgin.css_dependencies) %}
| ``{{dep}}`` {% endfor %}
{% endfor %}

View File

@ -1,253 +0,0 @@
.. _favicons:
========
Favicons
========
.. sidebar:: warning
Don't activate the favicons before reading the documentation.
.. contents::
:depth: 2
:local:
:backlinks: entry
Activating the favicons in SearXNG is very easy, but this **generates a
significantly higher load** in the client/server communication and increases
resources needed on the server.
To mitigate these disadvantages, various methods have been implemented,
including a *cache*. The cache must be parameterized according to your own
requirements and maintained regularly.
To activate favicons in SearXNG's result list, set a default
``favicon_resolver`` in the :ref:`search <settings search>` settings:
.. code:: yaml
search:
favicon_resolver: "duckduckgo"
By default and without any extensions, SearXNG serves these resolvers:
- ``duckduckgo``
- ``allesedv``
- ``google``
- ``yandex``
With the above setting favicons are displayed, the user has the option to
deactivate this feature in his settings. If the user is to have the option of
selecting from several *resolvers*, a further setting is required / but this
setting will be discussed :ref:`later <register resolvers>` in this article,
first we have to setup the favicons cache.
Infrastructure
==============
The infrastructure for providing the favicons essentially consists of three
parts:
- :py:obj:`Favicons-Proxy <.favicons.proxy>` (aka *proxy*)
- :py:obj:`Favicons-Resolvers <.favicons.resolvers>` (aka *resolver*)
- :py:obj:`Favicons-Cache <.favicons.cache>` (aka *cache*)
To protect the privacy of users, the favicons are provided via a *proxy*. This
*proxy* is automatically activated with the above activation of a *resolver*.
Additional requests are required to provide the favicons: firstly, the *proxy*
must process the incoming requests and secondly, the *resolver* must make
outgoing requests to obtain the favicons from external sources.
A *cache* has been developed to massively reduce both, incoming and outgoing
requests. This *cache* is also activated automatically with the above
activation of a *resolver*. In its defaults, however, the *cache* is minimal
and not well suitable for a production environment!
.. _favicon cache setup:
Setting up the cache
====================
To parameterize the *cache* and more settings of the favicons infrastructure, a
TOML_ configuration is created in the file ``/etc/searxng/favicons.toml``.
.. code:: toml
[favicons]
cfg_schema = 1 # config's schema version no.
[favicons.cache]
db_url = "/var/cache/searxng/faviconcache.db" # default: "/tmp/faviconcache.db"
LIMIT_TOTAL_BYTES = 2147483648 # 2 GB / default: 50 MB
# HOLD_TIME = 5184000 # 60 days / default: 30 days
# BLOB_MAX_BYTES = 40960 # 40 KB / default 20 KB
# MAINTENANCE_MODE = "off" # default: "auto"
# MAINTENANCE_PERIOD = 600 # 10min / default: 1h
:py:obj:`cfg_schema <.FaviconConfig.cfg_schema>`:
Is required to trigger any processes required for future upgrades / don't
change it.
:py:obj:`cache.db_url <.FaviconCacheConfig.db_url>`:
The path to the (SQLite_) database file. The default path is in the `/tmp`_
folder, which is deleted on every reboot and is therefore unsuitable for a
production environment. The FHS_ provides the folder `/var/cache`_ for the
cache of applications, so a suitable storage location of SearXNG's caches is
folder ``/var/cache/searxng``.
In a standard installation (compare :ref:`create searxng user`), the folder
must be created and the user under which the SearXNG process is running must
be given write permission to this folder.
.. code:: bash
$ sudo mkdir /var/cache/searxng
$ sudo chown root:searxng /var/cache/searxng/
$ sudo chmod g+w /var/cache/searxng/
In container systems, a volume should be mounted for this folder. Check
whether the process in the container has read/write access to the mounted
folder.
:py:obj:`cache.LIMIT_TOTAL_BYTES <.FaviconCacheConfig.LIMIT_TOTAL_BYTES>`:
Maximum of bytes stored in the cache of all blobs. The limit is only reached
at each maintenance interval after which the oldest BLOBs are deleted; the
limit is exceeded during the maintenance period.
.. attention::
If the maintenance period is too long or maintenance is switched
off completely, the cache grows uncontrollably.
SearXNG hosters can change other parameters of the cache as required:
- :py:obj:`cache.HOLD_TIME <.FaviconCacheConfig.HOLD_TIME>`
- :py:obj:`cache.BLOB_MAX_BYTES <.FaviconCacheConfig.BLOB_MAX_BYTES>`
Maintenance of the cache
------------------------
Regular maintenance of the cache is required! By default, regular maintenance
is triggered automatically as part of the client requests:
- :py:obj:`cache.MAINTENANCE_MODE <.FaviconCacheConfig.MAINTENANCE_MODE>` (default ``auto``)
- :py:obj:`cache.MAINTENANCE_PERIOD <.FaviconCacheConfig.MAINTENANCE_PERIOD>` (default ``6000`` / 1h)
As an alternative to maintenance as part of the client request process, it is
also possible to carry out maintenance using an external process. For example,
by creating a :man:`crontab` entry for maintenance:
.. code:: bash
$ python -m searx.favicons cache maintenance
The following command can be used to display the state of the cache:
.. code:: bash
$ python -m searx.favicons cache state
.. _favicon proxy setup:
Proxy configuration
===================
Most of the options of the :py:obj:`Favicons-Proxy <.favicons.proxy>` are
already set sensibly with settings from the :ref:`settings.yml <searxng
settings.yml>` and should not normally be adjusted.
.. code:: toml
[favicons.proxy]
max_age = 5184000 # 60 days / default: 7 days (604800 sec)
:py:obj:`max_age <.FaviconProxyConfig.max_age>`:
The `HTTP Cache-Control max-age`_ response directive indicates that the
response remains fresh until N seconds after the response is generated. This
setting therefore determines how long a favicon remains in the client's cache.
As a rule, in the favicons infrastructure of SearXNG's this setting only
affects favicons whose byte size exceeds :ref:`BLOB_MAX_BYTES <favicon cache
setup>` (the other favicons that are already in the cache are embedded as
`data URL`_ in the :py:obj:`generated HTML <.favicons.proxy.favicon_url>`,
which can greatly reduce the number of additional requests).
.. _register resolvers:
Register resolvers
------------------
A :py:obj:`resolver <.favicon.resolvers>` is a function that obtains the favicon
from an external source. The resolver functions available to the user are
registered with their fully qualified name (FQN_) in a ``resolver_map``.
If no ``resolver_map`` is defined in the ``favicon.toml``, the favicon
infrastructure of SearXNG generates this ``resolver_map`` automatically
depending on the ``settings.yml``. SearXNG would automatically generate the
following TOML configuration from the following YAML configuration:
.. code:: yaml
search:
favicon_resolver: "duckduckgo"
.. code:: toml
[favicons.proxy.resolver_map]
"duckduckgo" = "searx.favicons.resolvers.duckduckgo"
If this automatism is not desired, then (and only then) a separate
``resolver_map`` must be created. For example, to give the user two resolvers to
choose from, the following configuration could be used:
.. code:: toml
[favicons.proxy.resolver_map]
"duckduckgo" = "searx.favicons.resolvers.duckduckgo"
"allesedv" = "searx.favicons.resolvers.allesedv"
# "google" = "searx.favicons.resolvers.google"
# "yandex" = "searx.favicons.resolvers.yandex"
.. note::
With each resolver, the resource requirement increases significantly.
The number of resolvers increases:
- the number of incoming/outgoing requests and
- the number of favicons to be stored in the cache.
In the following we list the resolvers available in the core of SearXNG, but via
the FQN_ it is also possible to implement your own resolvers and integrate them
into the *proxy*:
- :py:obj:`searx.favicons.resolvers.duckduckgo`
- :py:obj:`searx.favicons.resolvers.allesedv`
- :py:obj:`searx.favicons.resolvers.google`
- :py:obj:`searx.favicons.resolvers.yandex`
.. _SQLite:
https://www.sqlite.org/
.. _FHS:
https://refspecs.linuxfoundation.org/FHS_3.0/fhs/index.html
.. _`/var/cache`:
https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch05s05.html
.. _`/tmp`:
https://refspecs.linuxfoundation.org/FHS_3.0/fhs/ch03s18.html
.. _TOML:
https://toml.io/en/
.. _HTTP Cache-Control max-age:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Cache-Control#response_directives
.. _data URL:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs
.. _FQN: https://en.wikipedia.org/wiki/Fully_qualified_name

View File

@ -1,17 +0,0 @@
.. _limiter:
=======
Limiter
=======
.. sidebar:: info
The limiter requires a :ref:`Redis <settings redis>` database.
.. contents::
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.limiter
:members:

View File

@ -1,5 +1,3 @@
.. _searxng settings.yml:
========
Settings
========
@ -13,7 +11,7 @@ Settings
:maxdepth: 2
settings
settings_engines
settings_engine
settings_brand
settings_general
settings_search
@ -22,6 +20,6 @@ Settings
settings_redis
settings_outgoing
settings_categories_as_tabs
settings_plugins

View File

@ -59,7 +59,7 @@ and can relied on the default configuration :origin:`searx/settings.yml` using:
use_default_settings: true
server:
secret_key: "ultrasecretkey" # change this!
bind_address: "[::]"
bind_address: "0.0.0.0"
``engines:``
With ``use_default_settings: true``, each settings can be override in a

View File

@ -1,30 +1,14 @@
.. _settings engines:
.. _settings engine:
============
``engines:``
============
===========
``engine:``
===========
.. sidebar:: Further reading ..
- :ref:`configured engines`
- :ref:`engines-dev`
In the section ``engines:`` is a list of the engines that are to be made
available in the instance. Each list entry is in turn a key/value mapping.
.. code:: yaml
engines:
- name: dummy.online
engine: dummy
..
- name: dummy.offline
engine: dummy-offline
..
..
In the code example below a *full fledged* example of a YAML setup from a dummy
engine is shown. Most of the options have a default value or even are optional.
@ -35,7 +19,7 @@ engine is shown. Most of the options have a default value or even are optional.
.. code:: yaml
- name: example
- name: example engine
engine: example
shortcut: demo
base_url: 'https://{language}.example.com/'
@ -148,8 +132,6 @@ engine is shown. Most of the options have a default value or even are optional.
``display_error_messages`` : default ``true``
When an engine returns an error, the message is displayed on the user interface.
.. _engine network:
``network`` : optional
Use the network configuration from another engine.
In addition, there are two default networks:
@ -222,7 +204,7 @@ Example configuration to restrict access to the Arch Linux Wiki engine:
tokens: [ 'my-secret-token' ]
Unless a user has configured the right token, the engine is going to be hidden
from them. It is not going to be included in the list of engines on the
from him/her. It is not going to be included in the list of engines on the
Preferences page and in the output of `/config` REST API call.
Tokens can be added to one's configuration on the Preferences page under "Engine
@ -259,3 +241,4 @@ Example configuration in settings.yml for a German and English speaker:
When searching, the default google engine will return German results and
"google english" will return English results.

View File

@ -13,17 +13,10 @@
donation_url: false
contact_url: false
enable_metrics: true
open_metrics: ''
``debug`` : ``$SEARXNG_DEBUG``
In debug mode, the server provides an interactive debugger, will reload when
code is changed and activates a verbose logging.
.. attention::
The debug setting is intended for local development server. Don't
activate debug (don't use a development server) when deploying to
production.
Allow a more detailed log if you run SearXNG directly. Display *detailed* error
messages in the browser too, so this must be deactivated in production.
``donation_url`` :
Set value to ``true`` to use your own donation page written in the
@ -39,10 +32,3 @@
``enable_metrics``:
Enabled by default. Record various anonymous metrics available at ``/stats``,
``/stats/errors`` and ``/preferences``.
``open_metrics``:
Disabled by default. Set to a secret password to expose an
`OpenMetrics API <https://github.com/prometheus/OpenMetrics>`_ at ``/metrics``,
e.g. for usage with Prometheus. The ``/metrics`` endpoint is using HTTP Basic Auth,
where the password is the value of ``open_metrics`` set above. The username used for
Basic Auth can be randomly chosen as only the password is being validated.

View File

@ -43,7 +43,7 @@ Communication with search engines.
Global timeout of the requests made to others engines in seconds. A bigger
timeout will allow to wait for answers from slow engines, but in consequence
will slow SearXNG reactivity (the result page may take the time specified in the
timeout to load). Can be override by ``timeout`` in the :ref:`settings engines`.
timeout to load). Can be override by ``timeout`` in the :ref:`settings engine`.
``useragent_suffix`` :
Suffix to the user-agent SearXNG uses to send requests to others engines. If an
@ -105,6 +105,6 @@ Communication with search engines.
``using_tor_proxy`` :
Using tor proxy (``true``) or not (``false``) for all engines. The default is
``false`` and can be overwritten in the :ref:`settings engines`
``false`` and can be overwritten in the :ref:`settings engine`

View File

@ -1,77 +0,0 @@
.. _settings plugins:
============
``plugins:``
============
.. attention::
The ``enabled_plugins:`` section in SearXNG's settings no longer exists.
There is no longer a distinction between built-in and external plugin, all
plugins are registered via the settings in the ``plugins:`` section.
.. sidebar:: Further reading ..
- :ref:`plugins admin`
- :ref:`dev plugin`
In SearXNG, plugins can be registered in the :py:obj:`PluginStore
<searx.plugins.PluginStorage>` via a fully qualified class name.
A configuration (:py:obj:`PluginCfg <searx.plugins.PluginCfg>`) can be
transferred to the plugin, e.g. to activate it by default / *opt-in* or
*opt-out* from user's point of view.
Please note that some plugins, such as the :ref:`hostnames plugin` plugin,
require further configuration before they can be made available for selection.
built-in plugins
================
The built-in plugins are all located in the namespace `searx.plugins`.
.. code:: yaml
plugins:
searx.plugins.calculator.SXNGPlugin:
active: true
searx.plugins.hash_plugin.SXNGPlugin:
active: true
searx.plugins.self_info.SXNGPlugin:
active: true
searx.plugins.tracker_url_remover.SXNGPlugin:
active: true
searx.plugins.unit_converter.SXNGPlugin:
active: true
searx.plugins.ahmia_filter.SXNGPlugin:
active: true
searx.plugins.hostnames.SXNGPlugin:
active: true
searx.plugins.oa_doi_rewrite.SXNGPlugin:
active: false
searx.plugins.tor_check.SXNGPlugin:
active: false
.. _settings external_plugins:
external plugins
================
.. _Only show green hosted results:
https://github.com/return42/tgwf-searx-plugins/
SearXNG supports *external plugins* / there is no need to install one, SearXNG
runs out of the box.
- `Only show green hosted results`_
- ..

View File

@ -9,10 +9,8 @@
search:
safe_search: 0
autocomplete: ""
favicon_resolver: ""
default_lang: ""
ban_time_on_fail: 5
max_page: 0
max_ban_time_on_fail: 120
suspended_times:
SearxEngineAccessDenied: 86400
@ -34,34 +32,22 @@
``autocomplete``:
Existing autocomplete backends, leave blank to turn it off.
- ``360search``
- ``baidu``
- ``brave``
- ``dbpedia``
- ``duckduckgo``
- ``google``
- ``mwmbl``
- ``quark``
- ``qwant``
- ``seznam``
- ``sogou``
- ``stract``
- ``startpage``
- ``swisscows``
- ``qwant``
- ``wikipedia``
- ``yandex``
``favicon_resolver``:
To activate favicons in SearXNG's result list select a default
favicon-resolver, leave blank to turn off the feature. Don't activate the
favicons before reading the :ref:`Favicons documentation <favicons>`.
``default_lang``:
Default search language - leave blank to detect from browser information or
use codes from :origin:`searx/sxng_locales.py`.
use codes from :origin:`searx/languages.py`.
``languages``:
List of available languages - leave unset to use all codes from
:origin:`searx/sxng_locales.py`. Otherwise list codes of available languages.
:origin:`searx/languages.py`. Otherwise list codes of available languages.
The ``all`` value is shown as the ``Default language`` in the user interface
(in most cases, it is meant to send the query without a language parameter ;
in some cases, it means the English language) Example:
@ -77,11 +63,6 @@
- fr
- fr-BE
``max_page``:
If engine supports paging, 0 means unlimited numbers of pages. The value
is only applied if the engine itself does not have a max value that is
lower than this one.
``ban_time_on_fail``:
Ban time in seconds after engine errors.

View File

@ -12,52 +12,41 @@
bind_address: "127.0.0.1"
secret_key: "ultrasecretkey" # change this!
limiter: false
public_instance: false
image_proxy: false
method: "POST"
default_http_headers:
X-Content-Type-Options : nosniff
X-XSS-Protection : 1; mode=block
X-Download-Options : noopen
X-Robots-Tag : noindex, nofollow
Referrer-Policy : no-referrer
``base_url`` : ``$SEARXNG_BASE_URL``
The base URL where SearXNG is deployed. Used to create correct inbound links.
``port`` & ``bind_address``: ``$SEARXNG_PORT`` & ``$SEARXNG_BIND_ADDRESS``
``base_url`` : ``$SEARXNG_URL`` :ref:`buildenv <make buildenv>`
The base URL where SearXNG is deployed. Used to create correct inbound links.
If you change the value, don't forget to rebuild instance's environment
(:ref:`utils/brand.env <make buildenv>`)
``port`` & ``bind_address``: ``$SEARXNG_PORT`` & ``$SEARXNG_BIND_ADDRESS`` :ref:`buildenv <make buildenv>`
Port number and *bind address* of the SearXNG web application if you run it
directly using ``python searx/webapp.py``. Doesn't apply to a SearXNG
services running behind a proxy and using socket communications.
.. _server.secret_key:
services running behind a proxy and using socket communications. If you
change the value, don't forget to rebuild instance's environment
(:ref:`utils/brand.env <make buildenv>`)
``secret_key`` : ``$SEARXNG_SECRET``
Used for cryptography purpose.
``limiter`` : ``$SEARXNG_LIMITER``
.. _limiter:
``limiter`` :
Rate limit the number of request on the instance, block some bots. The
:ref:`limiter` requires a :ref:`settings redis` database.
.. _public_instance:
``public_instance`` : ``$SEARXNG_PUBLIC_INSTANCE``
Setting that allows to enable features specifically for public instances (not
needed for local usage). By set to ``true`` the following features are
activated:
- :py:obj:`searx.botdetection.link_token` in the :ref:`limiter`
:ref:`limiter src` requires a :ref:`settings redis` database.
.. _image_proxy:
``image_proxy`` : ``$SEARXNG_IMAGE_PROXY``
``image_proxy`` :
Allow your instance of SearXNG of being able to proxy images. Uses memory space.
.. _method:
``method`` : ``$SEARXNG_METHOD``
Whether to use ``GET`` or ``POST`` HTTP method when searching.
.. _HTTP headers: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
``default_http_headers`` :

View File

@ -19,13 +19,10 @@
default_theme: simple
theme_args:
simple_style: auto
search_on_category_select: true
hotkeys: default
url_formatting: pretty
.. _static_use_hash:
``static_use_hash`` : ``$SEARXNG_STATIC_USE_HASH``
``static_use_hash`` :
Enables `cache busting`_ of static files.
``default_locale`` :
@ -44,7 +41,7 @@
``center_alignment`` : default ``false``
When enabled, the results are centered instead of being in the left (or RTL)
side of the screen. This setting only affects the *desktop layout*
(:origin:`min-width: @tablet <client/simple/src/less/definitions.less>`)
(:origin:`min-width: @tablet <searx/static/themes/simple/src/less/definitions.less>`)
.. cache_url:
@ -59,16 +56,7 @@
Name of the theme you want to use by default on your SearXNG instance.
``theme_args.simple_style``:
Style of simple theme: ``auto``, ``light``, ``dark``, ``black``
Style of simple theme: ``auto``, ``light``, ``dark``
``results_on_new_tab``:
Open result links in a new tab by default.
``search_on_category_select``:
Perform search immediately if a category selected. Disable to select multiple categories.
``hotkeys``:
Hotkeys to use in the search interface: ``default``, ``vim`` (Vim-like).
``url_formatting``:
Formatting type to use for result URLs: ``pretty``, ``full`` or ``host``.

View File

@ -113,7 +113,7 @@ ${fedora_build}
(${SERVICE_USER})$ command -v python && python --version
$SEARXNG_PYENV/bin/python
Python 3.11.10
Python 3.8.1
# update pip's boilerplate ..
pip install -U pip
@ -123,7 +123,7 @@ ${fedora_build}
# jump to SearXNG's working tree and install SearXNG into virtualenv
(${SERVICE_USER})$ cd \"$SEARXNG_SRC\"
(${SERVICE_USER})$ pip install --use-pep517 --no-build-isolation -e .
(${SERVICE_USER})$ pip install -e .
.. END manage.sh update_packages

View File

@ -1,7 +1,7 @@
# -*- coding: utf-8 -*-
# SPDX-License-Identifier: AGPL-3.0-or-later
import sys, os
from pathlib import Path
from pallets_sphinx_themes import ProjectLink
from searx import get_setting
@ -13,6 +13,7 @@ project = 'SearXNG'
copyright = 'SearXNG team'
author = 'SearXNG team'
release, version = VERSION_STRING, VERSION_STRING
SEARXNG_URL = get_setting('server.base_url') or 'https://example.org/searxng'
ISSUE_URL = get_setting('brand.issue_url')
DOCS_URL = get_setting('brand.docs_url')
@ -21,9 +22,6 @@ PRIVACYPOLICY_URL = get_setting('general.privacypolicy_url')
CONTACT_URL = get_setting('general.contact_url')
WIKI_URL = get_setting('brand.wiki_url')
SOURCEDIR = Path(__file__).parent.parent / "searx"
os.environ['SOURCEDIR'] = str(SOURCEDIR)
# hint: sphinx.ext.viewcode won't highlight when 'highlight_language' [1] is set
# to string 'none' [2]
#
@ -54,7 +52,7 @@ searx.engines.load_engines(searx.settings['engines'])
jinja_contexts = {
'searx': {
'engines': searx.engines.engines,
'plugins': searx.plugins.STORAGE,
'plugins': searx.plugins.plugins,
'version': {
'node': os.getenv('NODE_MINIMUM_VERSION')
},
@ -129,9 +127,8 @@ extensions = [
'notfound.extension', # https://github.com/readthedocs/sphinx-notfound-page
]
# autodoc_typehints = "description"
autodoc_default_options = {
'member-order': 'bysource',
'member-order': 'groupwise',
}
myst_enable_extensions = [
@ -143,10 +140,10 @@ suppress_warnings = ['myst.domains']
intersphinx_mapping = {
"python": ("https://docs.python.org/3/", None),
"babel" : ("https://babel.readthedocs.io/en/latest/", None),
"flask": ("https://flask.palletsprojects.com/en/stable/", None),
"flask": ("https://flask.palletsprojects.com/", None),
"flask_babel": ("https://python-babel.github.io/flask-babel/", None),
"werkzeug": ("https://werkzeug.palletsprojects.com/en/stable/", None),
"jinja": ("https://jinja.palletsprojects.com/en/stable/", None),
# "werkzeug": ("https://werkzeug.palletsprojects.com/", None),
"jinja": ("https://jinja.palletsprojects.com/", None),
"linuxdoc" : ("https://return42.github.io/linuxdoc/", None),
"sphinx" : ("https://www.sphinx-doc.org/en/master/", None),
"redis": ('https://redis.readthedocs.io/en/stable/', None),
@ -161,7 +158,7 @@ issues_github_path = "searxng/searxng"
notfound_urls_prefix = '/'
sys.path.append(os.path.abspath('_themes'))
sys.path.insert(0, os.path.abspath("../"))
sys.path.insert(0, os.path.abspath("../utils/"))
html_theme_path = ['_themes']
html_theme = "searxng"
@ -197,7 +194,7 @@ html_sidebars = {
],
}
singlehtml_sidebars = {"index": ["project.html", "localtoc.html"]}
html_logo = "../client/simple/src/brand/searxng-wordmark.svg"
html_logo = "../src/brand/searxng-wordmark.svg"
html_title = "SearXNG Documentation ({})".format(VERSION_STRING)
html_show_sourcelink = True

View File

@ -1,11 +0,0 @@
.. _builtin answerers:
==================
Built-in Answerers
==================
.. toctree::
:maxdepth: 1
random
statistics

View File

@ -1,7 +0,0 @@
.. _dev answerers:
====================
Answerer Development
====================
.. automodule:: searx.answerers

View File

@ -1,9 +0,0 @@
=========
Answerers
=========
.. toctree::
:maxdepth: 2
development
builtins

View File

@ -1,8 +0,0 @@
.. _answerer.random:
======
Random
======
.. autoclass:: searx.answerers.random.SXNGAnswerer
:members:

View File

@ -1,8 +0,0 @@
.. _answerer.statistics:
==========
Statistics
==========
.. autoclass:: searx.answerers.statistics.SXNGAnswerer
:members:

View File

@ -27,24 +27,23 @@ Privacy-by-design
-----------------
SearXNG was born out of the need for a **privacy-respecting** search tool which
can be extended easily to maximize both its search and its privacy protecting
can be extended easily to maximize both, its search and its privacy protecting
capabilities.
Some widely used search engine features may work differently,
may be turned off by default, or may not be implemented at all in SearXNG
**as a consequence of a privacy-by-design approach**.
A few widely used features work differently or turned off by default or not
implemented at all **as a consequence of privacy-by-design**.
Following this approach, features reducing the privacy preserving aspects of SearXNG should be
switched off by default or should not be implemented at all. There are plenty of
search engines already providing such features. If a feature reduces
SearXNG's efficacy in protecting a user's privacy, the user must be informed about
the effect of choosing to enable it. Features that protect privacy but differ from the
expectations of the user should also be carefully explained to them.
If a feature reduces the privacy preserving aspects of searx, it should be
switched off by default or should not implemented at all. There are plenty of
search engines already providing such features. If a feature reduces the
protection of searx, users must be informed about the effect of choosing to
enable it. Features that protect privacy but differ from the expectations of
the user should also be explained.
Also, if you think that something works weird with SearXNG, it might be because
the tool you are using is designed in a way that interferes with SearXNG's privacy aspects.
Submitting a bug report to the vendor of the tool that misbehaves might be a good
feedback for them to reconsider the disrespect to their customers (e.g., ``GET`` vs ``POST``
Also, if you think that something works weird with searx, it's might be because
of the tool you use is designed in a way to interfere with the privacy respect.
Submitting a bugreport to the vendor of the tool that misbehaves might be a good
feedback to reconsider the disrespect to its customers (e.g. ``GET`` vs ``POST``
requests in various browsers).
Remember the other prime directive of SearXNG is to be hackable, so if the above
@ -135,7 +134,7 @@ Here is an example which makes a complete rebuild:
.. _make docs.live:
Live build
live build
----------
.. _sphinx-autobuild:
@ -146,8 +145,8 @@ Live build
It is recommended to assert a complete rebuild before deploying (use
``docs.clean``).
Live build is like WYSIWYG. It's the recommended way to go if you want to edit the documentation.
The Makefile target ``docs.live`` builds the docs, opens
Live build is like WYSIWYG. If you want to edit the documentation, its
recommended to use. The Makefile target ``docs.live`` builds the docs, opens
URL in your favorite browser and rebuilds every time a reST file has been
changed (:ref:`make docs.clean`).
@ -160,9 +159,9 @@ changed (:ref:`make docs.clean`).
... Start watching changes
Live builds are implemented by sphinx-autobuild_. Use environment
``$(SPHINXOPTS)`` to pass arguments to the sphinx-autobuild_ command. You can
pass any argument except for the ``--host`` option (which is always set to ``0.0.0.0``).
E.g., to find and use a free port, use:
``$(SPHINXOPTS)`` to pass arguments to the sphinx-autobuild_ command. Except
option ``--host`` (which is always set to ``0.0.0.0``) you can pass any
argument. E.g to find and use a free port, use:
.. code:: sh

View File

@ -14,7 +14,7 @@ Engine Overview
.. sidebar:: Further reading ..
- :ref:`configured engines`
- :ref:`settings engines`
- :ref:`settings engine`
SearXNG is a metasearch-engine_, so it uses different search engines to provide
better results.
@ -63,7 +63,7 @@ Engine File
Engine ``settings.yml``
-----------------------
For a more detailed description, see :ref:`settings engines` in the :ref:`settings.yml`.
For a more detailed description, see :ref:`settings engine` in the :ref:`settings.yml`.
.. table:: Common options in the engine setup (``settings.yml``)
:width: 100%
@ -87,8 +87,8 @@ For a more detailed description, see :ref:`settings engines` in the :ref:`setti
Overrides
---------
A few of the options have default values in the namespace of the engine's python
module, but are often overwritten by the settings. If ``None`` is assigned to an
A few of the options have default values in the namespace of engine's python
modul, but are often overwritten by the settings. If ``None`` is assigned to an
option in the engine file, it has to be redefined in the settings, otherwise
SearXNG will not start with that engine (global names with a leading underline can
be ``None``).
@ -237,18 +237,232 @@ following parameters can be used to specify a search request:
=================== =========== ==========================================================================
Making a Response
=================
.. _engine results:
.. _engine media types:
In the ``response`` function of the engine, the HTTP response (``resp``) is
parsed and a list of results is returned.
Result Types (``template``)
===========================
A engine can append result-items of different media-types and different
result-types to the result list. The list of the result items is render to HTML
by templates. For more details read section:
Each result item of an engine can be of different media-types. Currently the
following media-types are supported. To set another media-type as
:ref:`template default`, the parameter ``template`` must be set to the desired
type.
- :ref:`simple theme templates`
- :ref:`result types`
.. _template default:
``default``
-----------
.. table:: Parameter of the **default** media type:
:width: 100%
========================= =====================================================
result-parameter information
========================= =====================================================
url string, url of the result
title string, title of the result
content string, general result-text
publishedDate :py:class:`datetime.datetime`, time of publish
========================= =====================================================
.. _template images:
``images``
----------
.. table:: Parameter of the **images** media type:
:width: 100%
========================= =====================================================
result-parameter information
------------------------- -----------------------------------------------------
template is set to ``images.html``
========================= =====================================================
url string, url to the result site
title string, title of the result *(partly implemented)*
content *(partly implemented)*
publishedDate :py:class:`datetime.datetime`,
time of publish *(partly implemented)*
img\_src string, url to the result image
thumbnail\_src string, url to a small-preview image
========================= =====================================================
.. _template videos:
``videos``
----------
.. table:: Parameter of the **videos** media type:
:width: 100%
========================= =====================================================
result-parameter information
------------------------- -----------------------------------------------------
template is set to ``videos.html``
========================= =====================================================
url string, url of the result
title string, title of the result
content *(not implemented yet)*
publishedDate :py:class:`datetime.datetime`, time of publish
thumbnail string, url to a small-preview image
========================= =====================================================
.. _template torrent:
``torrent``
-----------
.. _magnetlink: https://en.wikipedia.org/wiki/Magnet_URI_scheme
.. table:: Parameter of the **torrent** media type:
:width: 100%
========================= =====================================================
result-parameter information
------------------------- -----------------------------------------------------
template is set to ``torrent.html``
========================= =====================================================
url string, url of the result
title string, title of the result
content string, general result-text
publishedDate :py:class:`datetime.datetime`,
time of publish *(not implemented yet)*
seed int, number of seeder
leech int, number of leecher
filesize int, size of file in bytes
files int, number of files
magnetlink string, magnetlink_ of the result
torrentfile string, torrentfile of the result
========================= =====================================================
.. _template map:
``map``
-------
.. table:: Parameter of the **map** media type:
:width: 100%
========================= =====================================================
result-parameter information
------------------------- -----------------------------------------------------
template is set to ``map.html``
========================= =====================================================
url string, url of the result
title string, title of the result
content string, general result-text
publishedDate :py:class:`datetime.datetime`, time of publish
latitude latitude of result (in decimal format)
longitude longitude of result (in decimal format)
boundingbox boundingbox of result (array of 4. values
``[lat-min, lat-max, lon-min, lon-max]``)
geojson geojson of result (https://geojson.org/)
osm.type type of osm-object (if OSM-Result)
osm.id id of osm-object (if OSM-Result)
address.name name of object
address.road street name of object
address.house_number house number of object
address.locality city, place of object
address.postcode postcode of object
address.country country of object
========================= =====================================================
.. _template paper:
``paper``
---------
.. _BibTeX format: https://www.bibtex.com/g/bibtex-format/
.. _BibTeX field types: https://en.wikipedia.org/wiki/BibTeX#Field_types
.. list-table:: Parameter of the **paper** media type /
see `BibTeX field types`_ and `BibTeX format`_
:header-rows: 2
:width: 100%
* - result-parameter
- Python type
- information
* - template
- :py:class:`str`
- is set to ``paper.html``
* - title
- :py:class:`str`
- title of the result
* - content
- :py:class:`str`
- abstract
* - comments
- :py:class:`str`
- free text display in italic below the content
* - tags
- :py:class:`List <list>`\ [\ :py:class:`str`\ ]
- free tag list
* - publishedDate
- :py:class:`datetime <datetime.datetime>`
- last publication date
* - type
- :py:class:`str`
- short description of medium type, e.g. *book*, *pdf* or *html* ...
* - authors
- :py:class:`List <list>`\ [\ :py:class:`str`\ ]
- list of authors of the work (authors with a "s")
* - editor
- :py:class:`str`
- list of editors of a book
* - publisher
- :py:class:`str`
- name of the publisher
* - journal
- :py:class:`str`
- name of the journal or magazine the article was
published in
* - volume
- :py:class:`str`
- volume number
* - pages
- :py:class:`str`
- page range where the article is
* - number
- :py:class:`str`
- number of the report or the issue number for a journal article
* - doi
- :py:class:`str`
- DOI number (like ``10.1038/d41586-018-07848-2``)
* - issn
- :py:class:`List <list>`\ [\ :py:class:`str`\ ]
- ISSN number like ``1476-4687``
* - isbn
- :py:class:`List <list>`\ [\ :py:class:`str`\ ]
- ISBN number like ``9780201896831``
* - pdf_url
- :py:class:`str`
- URL to the full article, the PDF version
* - html_url
- :py:class:`str`
- URL to full article, HTML version

View File

@ -4,13 +4,19 @@
Engine Library
==============
.. contents::
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.enginelib
:members:
:members:
.. _searx.enginelib.traits:
Engine traits
=============
.. automodule:: searx.enginelib.traits
:members:
:members:

View File

@ -19,14 +19,6 @@ Engine Implementations
engine_overview
ResultList and engines
======================
.. autoclass:: searx.result_types.ResultList
.. autoclass:: searx.result_types.EngineResults
Engine Types
============
@ -53,7 +45,6 @@ Online Engines
demo/demo_online
xpath
mediawiki
json_engine
.. toctree::
:maxdepth: 1
@ -102,7 +93,7 @@ Online Currency
- :py:obj:`processors.online_currency <searx.search.processors.online_currency>`
*no engine of this type is documented yet / coming soon*
*no engine of this type is documented yet / comming soon*
.. _online dictionary:
@ -113,4 +104,4 @@ Online Dictionary
- :py:obj:`processors.online_dictionary <searx.search.processors.online_dictionary>`
*no engine of this type is documented yet / coming soon*
*no engine of this type is documented yet / comming soon*

View File

@ -1,13 +0,0 @@
.. _json_engine engine:
============
JSON Engine
============
.. contents::
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.engines.json_engine
:members:

View File

@ -25,7 +25,7 @@ Relational Database Management System (RDBMS) are supported:
- :ref:`engine sqlite`
- :ref:`engine postgresql`
- :ref:`engine mysql_server` & :ref:`engine mariadb_server`
- :ref:`engine mysql_server`
All of the engines above are just commented out in the :origin:`settings.yml
<searx/settings.yml>`, as you have to set the required attributes for the
@ -119,16 +119,3 @@ MySQL
.. automodule:: searx.engines.mysql_server
:members:
.. _engine mariadb_server:
MariaDB
--------
.. sidebar:: info
- :origin:`mariadb_server.py <searx/engines/mariadb_server.py>`
- ``pip install`` :pypi:`mariadb <mariadb>`
.. automodule:: searx.engines.mariadb_server
:members:

View File

@ -29,7 +29,7 @@ Programming Interface
parameter. This function can be omitted, if there is no need to setup anything
in advance.
:py:func:`search(query, params) <searx.engines.demo_offline.search>`
:py:func:`search(query, params) <searx.engines.demo_offline.searc>`
Each offline engine has a function named ``search``. This function is
responsible to perform a search and return the results in a presentable
format. (Where *presentable* means presentable by the selected result

View File

@ -1,13 +0,0 @@
.. _adobe stock engine:
===========
Adobe Stock
===========
.. contents:: Contents
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.engines.adobe_stock
:members:

View File

@ -1,13 +0,0 @@
.. _alpinelinux engine:
=====================
Alpine Linux Packages
=====================
.. contents::
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.engines.alpinelinux
:members:

View File

@ -1,13 +0,0 @@
.. _bpb engine:
===
Bpb
===
.. contents:: Contents
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.engines.bpb
:members:

View File

@ -1,8 +0,0 @@
.. _chinaso engine:
=======
ChinaSo
=======
.. automodule:: searx.engines.chinaso
:members:

View File

@ -1,13 +0,0 @@
.. _core engine:
====
CORE
====
.. contents::
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.engines.core
:members:

View File

@ -1,8 +0,0 @@
.. _discourse engine:
================
Discourse Forums
================
.. automodule:: searx.engines.discourse
:members:

View File

@ -12,7 +12,7 @@ DuckDuckGo Engines
.. automodule:: searx.engines.duckduckgo
:members:
.. automodule:: searx.engines.duckduckgo_extra
.. automodule:: searx.engines.duckduckgo_images
:members:
.. automodule:: searx.engines.duckduckgo_definitions

View File

@ -1,8 +0,0 @@
.. _gitea geizhals:
========
Geizhals
========
.. automodule:: searx.engines.geizhals
:members:

View File

@ -1,8 +0,0 @@
.. _gitea engine:
=====
Gitea
=====
.. automodule:: searx.engines.gitea
:members:

View File

@ -1,8 +0,0 @@
.. _gitlab engine:
======
GitLab
======
.. automodule:: searx.engines.gitlab
:members:

View File

@ -1,8 +0,0 @@
.. _huggingface engine:
============
Hugging Face
============
.. automodule:: searx.engines.huggingface
:members:

View File

@ -1,13 +0,0 @@
.. _mastodon engine:
========
Mastodon
========
.. contents:: Contents
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.engines.mastodon
:members:

View File

@ -1,13 +0,0 @@
.. _moviepilot engine:
==========
Moviepilot
==========
.. contents:: Contents
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.engines.moviepilot
:members:

View File

@ -1,13 +0,0 @@
.. _mrs engine:
=========================
Matrix Rooms Search (MRS)
=========================
.. contents:: Contents
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.engines.mrs
:members:

View File

@ -1,8 +0,0 @@
.. _voidlinux mullvad_leta:
============
Mullvad-Leta
============
.. automodule:: searx.engines.mullvad_leta
:members:

View File

@ -1,13 +0,0 @@
.. _engine presearch:
================
Presearch Engine
================
.. contents::
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.engines.presearch
:members:

View File

@ -1,13 +0,0 @@
.. _qwant engine:
=====
Qwant
=====
.. contents:: Contents
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.engines.qwant
:members:

View File

@ -1,13 +0,0 @@
.. _RadioBrowser engine:
============
RadioBrowser
============
.. contents::
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.engines.radio_browser
:members:

View File

@ -1,8 +0,0 @@
.. _reuters engine:
=======
Reuters
=======
.. automodule:: searx.engines.reuters
:members:

View File

@ -1,13 +0,0 @@
.. _soundcloud engine:
==========
Soundcloud
==========
.. contents::
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.engines.soundcloud
:members:

View File

@ -1,13 +0,0 @@
.. _voidlinux engine:
==========================
Void Linux binary packages
==========================
.. contents:: Contents
:depth: 2
:local:
:backlinks: entry
.. automodule:: searx.engines.voidlinux
:members:

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