Compare commits
373 Commits
dependabot
...
bdbcf536de
| Author | SHA1 | Date | |
|---|---|---|---|
| bdbcf536de | |||
|
|
da3c640cef | ||
|
|
d16854e67a | ||
| ac3dd7b804 | |||
| 3075003825 | |||
| c6f1156bc6 | |||
| cf5dbbbc77 | |||
| 8477fb4846 | |||
| 8204f4ee72 | |||
| 9d9a0fe95e | |||
| 427a84d823 | |||
| e971a3d7ab | |||
| 89cb563793 | |||
| ac5c83b87d | |||
| 34437e8491 | |||
| 3d30ed1caa | |||
| 2ee495b383 | |||
| c27fd585ce | |||
| 89425caaa6 | |||
| 52347c1843 | |||
| c5b2bff2c5 | |||
| 61059eff9c | |||
| d159f8384f | |||
|
|
1b787ed35e | ||
|
|
8e2e7774d7 | ||
|
|
e982b9f732 | ||
|
|
48456caeb3 | ||
|
|
ef158ce1f4 | ||
|
|
cbf9ec7bf4 | ||
|
|
409ede1530 | ||
|
|
1326ec7429 | ||
|
|
50406d4b46 | ||
|
|
5ce3aa3acf | ||
|
|
76ebad0b21 | ||
|
|
d76f030cb3 | ||
|
|
b3b15ecc72 | ||
|
|
1319b250af | ||
|
|
198928de05 | ||
|
|
11d9c830b8 | ||
|
|
743f90514b | ||
|
|
48801dbc9a | ||
|
|
5451ab243a | ||
|
|
7ca24eee45 | ||
|
|
c6a70782b2 | ||
|
|
01a07f34b2 | ||
|
|
f32fcb1243 | ||
|
|
bc06b1aece | ||
|
|
ff60fe635f | ||
|
|
6e7119fa4e | ||
|
|
f52cd3f008 | ||
|
|
a2fa7de880 | ||
|
|
0315988f5a | ||
|
|
2e74d86321 | ||
|
|
19b116f1d7 | ||
|
|
fe08bb1d90 | ||
|
|
8ef5fbca4e | ||
|
|
7351c38e6c | ||
|
|
bdfe1c2a15 | ||
|
|
4cbfba9d7b | ||
|
|
4a594f1b53 | ||
|
|
590b211652 | ||
|
|
41e3a0baa7 | ||
|
|
11204459da | ||
|
|
03787b2e5a | ||
|
|
72294a9ffa | ||
|
|
d47cf9db24 | ||
|
|
705ebe64b5 | ||
|
|
b072b0f66b | ||
|
|
4beb5523f5 | ||
|
|
54e6e2a96d | ||
|
|
abcf8ca073 | ||
|
|
1a16281490 | ||
|
|
fd33559cfb | ||
|
|
60e31eacfc | ||
|
|
c45b970546 | ||
|
|
a4251be397 | ||
|
|
c20038e7c3 | ||
|
|
20e40ded6d | ||
|
|
4de0766b76 | ||
|
|
6de83ca47f | ||
|
|
a32bcd54c5 | ||
|
|
c733aa83e8 | ||
|
|
9dfc6f38d5 | ||
|
|
e1076f5c35 | ||
|
|
8489817561 | ||
|
|
38ff1e4a7d | ||
|
|
21cdb0332b | ||
|
|
30330617d9 | ||
|
|
33729439c5 | ||
|
|
20ce88a274 | ||
|
|
8595e467ce | ||
|
|
3392beb914 | ||
|
|
c6c6d3027c | ||
|
|
d19eb3903e | ||
|
|
f45d4145e6 | ||
|
|
937eb907d3 | ||
|
|
851c0e5cc0 | ||
|
|
07a94d4d2e | ||
|
|
e9157b3c1a | ||
|
|
5ae3b3f17e | ||
|
|
50ac76ce94 | ||
|
|
5aea044eb5 | ||
|
|
808dcaf1e2 | ||
|
|
777ba6ddf8 | ||
|
|
8ca57748ff | ||
|
|
30399c50e2 | ||
|
|
e6467bce7c | ||
|
|
8ca2bbc4e9 | ||
|
|
a74593419f | ||
|
|
f94802f2d2 | ||
|
|
d1c584b961 | ||
|
|
81f3d15665 | ||
|
|
99ad69450d | ||
|
|
087da66565 | ||
|
|
b84ae39978 | ||
|
|
391bb1268d | ||
|
|
2287a6826a | ||
|
|
b3971f89e2 | ||
|
|
a4e08a5c2f | ||
|
|
8ee51cc0f3 | ||
|
|
ed2953c59f | ||
|
|
e2fac7f306 | ||
|
|
8db2a15307 | ||
|
|
92b8f71780 | ||
|
|
15384e8fc5 | ||
|
|
b146b745a7 | ||
|
|
c185d07689 | ||
|
|
5a54372368 | ||
|
|
8c8aba8cf5 | ||
|
|
9424bac031 | ||
|
|
59228fb1db | ||
|
|
f630a24311 | ||
|
|
4452358e87 | ||
|
|
7546f88b1e | ||
|
|
d4c6c9401d | ||
|
|
e6308b8167 | ||
|
|
08885d0614 | ||
|
|
7b4612e862 | ||
|
|
9ffa9fb730 | ||
|
|
5daa4f0460 | ||
|
|
33661cc5c3 | ||
|
|
b231cb4b59 | ||
|
|
c8b419fcbb | ||
|
|
237267ffbe | ||
|
|
50f92779bd | ||
|
|
d36da0a6c3 | ||
|
|
d7ca257fcd | ||
|
|
98024d8518 | ||
|
|
96d0854a50 | ||
|
|
ecee73eafd | ||
|
|
1189b1906c | ||
|
|
4a0ff84a40 | ||
|
|
d02d432862 | ||
|
|
3c537f958f | ||
|
|
a2ad1bed00 | ||
|
|
f62f6194e3 | ||
|
|
68d871dea0 | ||
|
|
150b2e21fd | ||
|
|
02f5002a5f | ||
|
|
4dfc47584d | ||
|
|
c28d35c7fc | ||
|
|
2ad987c711 | ||
|
|
5986629c6b | ||
|
|
7e680d8e8e | ||
|
|
2482646323 | ||
|
|
96a6e3dcb2 | ||
|
|
ef99cc472d | ||
|
|
64b52d485b | ||
|
|
de6b027ec7 | ||
|
|
f687306a95 | ||
|
|
b75e56afe6 | ||
|
|
3668c7012e | ||
|
|
556db857aa | ||
|
|
40feede51e | ||
|
|
82b9e533b2 | ||
|
|
babbe9e1ae | ||
|
|
885d02c8c3 | ||
|
|
bbb2894b04 | ||
|
|
84636ef49a | ||
|
|
a1d5add718 | ||
|
|
38caa49540 | ||
|
|
4ce7f1accc | ||
|
|
11b5ae186b | ||
|
|
583007fd04 | ||
|
|
da7b069d6e | ||
|
|
f49b2c94a9 | ||
|
|
af5dbdf768 | ||
|
|
8769b7c6d6 | ||
|
|
d6ce29f7f0 | ||
|
|
eb1bdea865 | ||
|
|
85bdff6b0a | ||
|
|
f7ef4396b1 | ||
|
|
83f6545903 | ||
|
|
6afe0e29a7 | ||
|
|
523871ae7b | ||
|
|
505f7732d8 | ||
|
|
896cb3ab46 | ||
|
|
3fe602a468 | ||
|
|
8b1d73c5b9 | ||
|
|
a88b4d7036 | ||
|
|
73d50f5748 | ||
|
|
523d2a7683 | ||
|
|
4884747508 | ||
|
|
eb3633629a | ||
|
|
02b76c8389 | ||
|
|
67a8b66f75 | ||
|
|
08a90d46d6 | ||
|
|
e7cb18c3dd | ||
|
|
9a50f6c9a1 | ||
|
|
00bae78463 | ||
|
|
375f0c4a79 | ||
|
|
424cbf7851 | ||
|
|
860f0a35ac | ||
|
|
b8671c7a4a | ||
|
|
066aabc112 | ||
|
|
8fe4904619 | ||
|
|
08d08475fc | ||
|
|
194f222203 | ||
|
|
8984d7ae02 | ||
|
|
b0beb307ca | ||
|
|
76f52b5b45 | ||
|
|
97aa5a779b | ||
|
|
71d1504e57 | ||
|
|
80f5fad16e | ||
|
|
0c2076ca5b | ||
|
|
a51416c7c3 | ||
|
|
d0022d86d2 | ||
|
|
1d16b94279 | ||
|
|
30a820437d | ||
|
|
03419078ef | ||
|
|
01e2b3e325 | ||
|
|
ccf485c519 | ||
|
|
64810ee911 | ||
|
|
a4b120c33d | ||
|
|
73e4128970 | ||
|
|
355883f366 | ||
|
|
b4b1a61562 | ||
|
|
28b5cbf276 | ||
|
|
d9d5e9140e | ||
|
|
cd1b88e916 | ||
|
|
4e195e1000 | ||
|
|
d5ba3bf150 | ||
|
|
485f1f8eff | ||
|
|
8b864ed111 | ||
|
|
6500d73714 | ||
|
|
2bf77f5d2d | ||
|
|
1a3543d4b2 | ||
|
|
872e09d103 | ||
|
|
189dd0155d | ||
|
|
30ee34d3ea | ||
|
|
a207f5d035 | ||
|
|
d29ca7d593 | ||
|
|
a8ed79b730 | ||
|
|
b74496b192 | ||
|
|
7a6ea56565 | ||
|
|
a1132deaa4 | ||
|
|
b6487b70aa | ||
|
|
e86bfa163b | ||
|
|
333d536937 | ||
|
|
1fd4dab3b4 | ||
|
|
887594f634 | ||
|
|
bc5c8e5748 | ||
|
|
cb0a75bad9 | ||
|
|
dabe425499 | ||
|
|
f325f8a886 | ||
|
|
2e0abc9310 | ||
|
|
28d1240fce | ||
|
|
4994fbb5af | ||
|
|
caf0dd5372 | ||
|
|
c0a21789a3 | ||
|
|
0f2fc5879d | ||
|
|
feb15e3878 | ||
|
|
c2804c51e2 | ||
|
|
0a3eb24a0b | ||
|
|
16fafed6a2 | ||
|
|
44d941c93c | ||
|
|
cc9dbde2e5 | ||
|
|
1ae37728e4 | ||
|
|
d37dc30783 | ||
|
|
f92bfebe21 | ||
|
|
0eb23c490d | ||
|
|
d456f3dd9f | ||
|
|
a1e2b25467 | ||
|
|
3a59aea742 | ||
|
|
28ead13eb9 | ||
|
|
9b1f8681a1 | ||
|
|
739822f705 | ||
|
|
d45dea56c5 | ||
|
|
8c610404bd | ||
|
|
147bda894e | ||
|
|
4ab7984edd | ||
|
|
ab1e895cc0 | ||
|
|
6324a9752a | ||
|
|
d7602aa4f1 | ||
|
|
157c9267ec | ||
|
|
eea4d4fd1d | ||
|
|
738906358b | ||
|
|
fc8938c968 | ||
|
|
3b9e06fbd2 | ||
|
|
4934922156 | ||
|
|
bee39e4ec0 | ||
|
|
3f4e0b0859 | ||
|
|
a235c54f8c | ||
|
|
df3344e5d5 | ||
|
|
906b9e7d4c | ||
|
|
36a1ef1239 | ||
|
|
edfbf1e118 | ||
|
|
9079d0cac0 | ||
|
|
70f1b65008 | ||
|
|
06f6ee4e36 | ||
|
|
9beff8212b | ||
|
|
cf4e183790 | ||
|
|
c1fcee9d9f | ||
|
|
176079977d | ||
|
|
f3f13519ff | ||
|
|
04a6ab12fb | ||
|
|
edf6d96625 | ||
|
|
fa50324dae | ||
|
|
bee2677929 | ||
|
|
e7081bb2c1 | ||
|
|
1fde000499 | ||
|
|
8731e37796 | ||
|
|
e92d1bc6af | ||
|
|
f766faca3f | ||
|
|
c020a964e4 | ||
|
|
46b16e6ff1 | ||
|
|
98c66c0ae6 | ||
|
|
c06ec65b2a | ||
|
|
e581921c92 | ||
|
|
073d9549a0 | ||
|
|
601ffcb8a3 | ||
|
|
d9115b8d48 | ||
|
|
c760ad0808 | ||
|
|
2f087a3a22 | ||
|
|
3333d9f385 | ||
|
|
1a885b70ce | ||
|
|
a576f69c12 | ||
|
|
272e39893d | ||
|
|
41159fed32 | ||
|
|
b1507f188e | ||
|
|
1668ff5e64 | ||
|
|
f03ab00155 | ||
|
|
15d0e274b3 | ||
|
|
e4f8f0483f | ||
|
|
5a1a43ef74 | ||
|
|
94b6adf03d | ||
|
|
337a6db064 | ||
|
|
9d834c0722 | ||
|
|
0abad23daa | ||
|
|
943c8fb85b | ||
|
|
35c80268bf | ||
|
|
3942b311ac | ||
|
|
64d954b350 | ||
|
|
591d9c2505 | ||
|
|
09cce18518 | ||
|
|
94a0b415ef | ||
|
|
6dab7fe78b | ||
|
|
e352926187 | ||
|
|
b0391fe718 | ||
|
|
91d3d38690 | ||
|
|
c5991865c8 | ||
|
|
655e41f274 | ||
|
|
d9343b6388 | ||
|
|
0642c5434a | ||
|
|
18c3e08837 | ||
|
|
96c32549be | ||
|
|
a060c09854 | ||
|
|
c1bb0bebd4 | ||
|
|
af3f272b0b | ||
|
|
05c82d3201 | ||
|
|
f0e9c3be8c | ||
|
|
428eaea2b7 | ||
|
|
3d55008f23 |
@@ -3,7 +3,8 @@
|
|||||||
"dockerfile": "Dockerfile"
|
"dockerfile": "Dockerfile"
|
||||||
},
|
},
|
||||||
"features": {
|
"features": {
|
||||||
"ghcr.io/devcontainers/features/github-cli": {}
|
"ghcr.io/devcontainers/features/github-cli": {},
|
||||||
|
"ghcr.io/devcontainers/features/docker-in-docker": {}
|
||||||
},
|
},
|
||||||
"customizations": {
|
"customizations": {
|
||||||
"vscode": {
|
"vscode": {
|
||||||
|
|||||||
@@ -16,11 +16,17 @@ max_line_length = 119
|
|||||||
[*.html]
|
[*.html]
|
||||||
indent_size = 4
|
indent_size = 4
|
||||||
|
|
||||||
|
[*.css]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.less]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
[*.js]
|
[*.js]
|
||||||
indent_size = 2
|
indent_size = 2
|
||||||
|
|
||||||
[*.json]
|
[*.json]
|
||||||
indent_size = 4
|
indent_size = 2
|
||||||
insert_final_newline = ignore
|
insert_final_newline = ignore
|
||||||
|
|
||||||
# Minified JavaScript files shouldn't be changed
|
# Minified JavaScript files shouldn't be changed
|
||||||
|
|||||||
22
.github/dependabot.yml
vendored
@@ -12,11 +12,29 @@ updates:
|
|||||||
prefix: "[upd] pypi:"
|
prefix: "[upd] pypi:"
|
||||||
|
|
||||||
- package-ecosystem: "npm"
|
- package-ecosystem: "npm"
|
||||||
directory: "/searx/static/themes/simple"
|
directory: "/client/simple"
|
||||||
schedule:
|
schedule:
|
||||||
interval: "weekly"
|
interval: "weekly"
|
||||||
day: "friday"
|
day: "friday"
|
||||||
open-pull-requests-limit: 5
|
open-pull-requests-limit: 5
|
||||||
target-branch: "master"
|
target-branch: "master"
|
||||||
commit-message:
|
commit-message:
|
||||||
prefix: "[upd] npm:"
|
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:"
|
||||||
|
|||||||
59
.github/workflows/checker.yml
vendored
@@ -1,31 +1,46 @@
|
|||||||
name: "Checker"
|
---
|
||||||
on: # yamllint disable-line rule:truthy
|
name: Checker
|
||||||
|
|
||||||
|
# yamllint disable-line rule:truthy
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "0 4 * * 5"
|
- cron: "0 4 * * 5"
|
||||||
workflow_dispatch:
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref_name }}
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
env:
|
||||||
|
PYTHON_VERSION: "3.13"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
checker:
|
search:
|
||||||
name: Checker
|
name: Search
|
||||||
runs-on: ubuntu-22.04
|
runs-on: ubuntu-24.04-arm
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Setup Python
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install Ubuntu packages
|
|
||||||
run: |
|
|
||||||
sudo ./utils/searxng.sh install packages
|
|
||||||
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.13'
|
python-version: "${{ env.PYTHON_VERSION }}"
|
||||||
architecture: 'x64'
|
|
||||||
|
|
||||||
- name: Install Python dependencies
|
- name: Checkout
|
||||||
run: |
|
uses: actions/checkout@v4
|
||||||
make V=1 install
|
with:
|
||||||
|
persist-credentials: "false"
|
||||||
|
|
||||||
- name: Checker
|
- name: Setup cache Python
|
||||||
run: |
|
uses: actions/cache@v4
|
||||||
make search.checker
|
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
|
||||||
|
|||||||
183
.github/workflows/container.yml
vendored
Normal file
@@ -0,0 +1,183 @@
|
|||||||
|
---
|
||||||
|
name: Container
|
||||||
|
|
||||||
|
# yamllint disable-line rule:truthy
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
workflow_run:
|
||||||
|
workflows:
|
||||||
|
- Integration
|
||||||
|
types:
|
||||||
|
- completed
|
||||||
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref_name }}
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
# Organization GHCR
|
||||||
|
packages: read
|
||||||
|
|
||||||
|
env:
|
||||||
|
PYTHON_VERSION: "3.13"
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
if: github.event_name == 'workflow_dispatch' || github.event.workflow_run.conclusion == 'success'
|
||||||
|
name: Build (${{ matrix.arch }})
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- arch: amd64
|
||||||
|
os: ubuntu-24.04
|
||||||
|
emulation: false
|
||||||
|
- arch: arm64
|
||||||
|
os: ubuntu-24.04-arm
|
||||||
|
emulation: false
|
||||||
|
- arch: armv7
|
||||||
|
os: ubuntu-24.04-arm
|
||||||
|
emulation: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
# Organization GHCR
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
outputs:
|
||||||
|
version_string: ${{ steps.build.outputs.version_string }}
|
||||||
|
version_tag: ${{ steps.build.outputs.version_tag }}
|
||||||
|
docker_tag: ${{ steps.build.outputs.docker_tag }}
|
||||||
|
git_url: ${{ steps.build.outputs.git_url }}
|
||||||
|
git_branch: ${{ steps.build.outputs.git_branch }}
|
||||||
|
|
||||||
|
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 cache container mounts
|
||||||
|
uses: actions/cache@v4
|
||||||
|
with:
|
||||||
|
# yamllint disable-line rule:line-length
|
||||||
|
key: "container-mounts-${{ matrix.arch }}-${{ hashFiles('./container/Dockerfile ./container/legacy/Dockerfile') }}"
|
||||||
|
restore-keys: "container-mounts-${{ matrix.arch }}-"
|
||||||
|
path: |
|
||||||
|
/var/tmp/buildah-cache/
|
||||||
|
/var/tmp/buildah-cache-*/
|
||||||
|
|
||||||
|
- if: ${{ matrix.emulation }}
|
||||||
|
name: Setup QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Login to GHCR
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: "ghcr.io"
|
||||||
|
username: "${{ github.repository_owner }}"
|
||||||
|
password: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
id: build
|
||||||
|
env:
|
||||||
|
OVERRIDE_ARCH: "${{ matrix.arch }}"
|
||||||
|
run: make podman.build
|
||||||
|
|
||||||
|
test:
|
||||||
|
name: Test (${{ matrix.arch }})
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
needs: build
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- arch: amd64
|
||||||
|
os: ubuntu-24.04
|
||||||
|
emulation: false
|
||||||
|
- arch: arm64
|
||||||
|
os: ubuntu-24.04-arm
|
||||||
|
emulation: false
|
||||||
|
- arch: armv7
|
||||||
|
os: ubuntu-24.04-arm
|
||||||
|
emulation: true
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
# Organization GHCR
|
||||||
|
packages: write
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: "false"
|
||||||
|
|
||||||
|
- if: ${{ matrix.emulation }}
|
||||||
|
name: Setup QEMU
|
||||||
|
uses: docker/setup-qemu-action@v3
|
||||||
|
|
||||||
|
- name: Login to GHCR
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: "ghcr.io"
|
||||||
|
username: "${{ github.repository_owner }}"
|
||||||
|
password: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
env:
|
||||||
|
OVERRIDE_ARCH: "${{ matrix.arch }}"
|
||||||
|
GIT_URL: "${{ needs.build.outputs.git_url }}"
|
||||||
|
run: make container.test
|
||||||
|
|
||||||
|
release:
|
||||||
|
if: github.repository_owner == 'searxng' && github.ref_name == 'master'
|
||||||
|
name: Release
|
||||||
|
runs-on: ubuntu-24.04-arm
|
||||||
|
needs:
|
||||||
|
- build
|
||||||
|
- test
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- if: env.DOCKERHUB_USERNAME != null
|
||||||
|
name: Checkout
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: "false"
|
||||||
|
|
||||||
|
- if: env.DOCKERHUB_USERNAME != null
|
||||||
|
name: Login to GHCR
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: "ghcr.io"
|
||||||
|
username: "${{ github.repository_owner }}"
|
||||||
|
password: "${{ secrets.GITHUB_TOKEN }}"
|
||||||
|
|
||||||
|
- if: env.DOCKERHUB_USERNAME != null
|
||||||
|
name: Login to Docker Hub
|
||||||
|
uses: docker/login-action@v3
|
||||||
|
with:
|
||||||
|
registry: "docker.io"
|
||||||
|
username: "${{ env.DOCKERHUB_USERNAME }}"
|
||||||
|
password: "${{ secrets.DOCKERHUB_TOKEN }}"
|
||||||
|
|
||||||
|
- if: env.DOCKERHUB_USERNAME != null
|
||||||
|
name: Release
|
||||||
|
env:
|
||||||
|
GIT_URL: "${{ needs.build.outputs.git_url }}"
|
||||||
|
DOCKER_TAG: "${{ needs.build.outputs.docker_tag }}"
|
||||||
|
run: make container.push
|
||||||
90
.github/workflows/data-update.yml
vendored
@@ -1,14 +1,27 @@
|
|||||||
name: "Update searx.data"
|
---
|
||||||
on: # yamllint disable-line rule:truthy
|
name: Update searx.data
|
||||||
|
|
||||||
|
# yamllint disable-line rule:truthy
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "59 23 28 * *"
|
- cron: "59 23 28 * *"
|
||||||
workflow_dispatch:
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref_name }}
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
|
env:
|
||||||
|
PYTHON_VERSION: "3.13"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
updateData:
|
data:
|
||||||
name: Update data - ${{ matrix.fetch }}
|
if: github.repository_owner == 'searxng'
|
||||||
runs-on: ubuntu-24.04
|
name: ${{ matrix.fetch }}
|
||||||
if: ${{ github.repository_owner == 'searxng'}}
|
runs-on: ubuntu-24.04-arm
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
@@ -20,48 +33,51 @@ jobs:
|
|||||||
- update_engine_traits.py
|
- update_engine_traits.py
|
||||||
- update_wikidata_units.py
|
- update_wikidata_units.py
|
||||||
- update_engine_descriptions.py
|
- update_engine_descriptions.py
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
pull-requests: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Setup Python
|
||||||
uses: actions/checkout@v4
|
|
||||||
|
|
||||||
- name: Install Ubuntu packages
|
|
||||||
run: |
|
|
||||||
sudo ./utils/searxng.sh install packages
|
|
||||||
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.12'
|
python-version: "${{ env.PYTHON_VERSION }}"
|
||||||
architecture: 'x64'
|
|
||||||
|
|
||||||
- name: Install Python dependencies
|
- name: Checkout
|
||||||
run: |
|
uses: actions/checkout@v4
|
||||||
make V=1 install
|
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: Fetch data
|
- name: Fetch data
|
||||||
env:
|
run: V=1 ./manage pyenv.cmd python "./searxng_extra/update/${{ matrix.fetch }}"
|
||||||
FETCH_SCRIPT: ./searxng_extra/update/${{ matrix.fetch }}
|
|
||||||
run: |
|
|
||||||
V=1 ./manage pyenv.cmd python "$FETCH_SCRIPT"
|
|
||||||
|
|
||||||
- name: Create Pull Request
|
- name: Create PR
|
||||||
id: cpr
|
id: cpr
|
||||||
uses: peter-evans/create-pull-request@v6
|
uses: peter-evans/create-pull-request@v7
|
||||||
with:
|
with:
|
||||||
commit-message: '[data] update searx.data - ${{ matrix.fetch }}'
|
author: "${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>"
|
||||||
committer: searxng-bot <noreply@github.com>
|
committer: "searxng-bot <searxng-bot@users.noreply.github.com>"
|
||||||
author: ${{ github.actor }} <${{ github.actor }}@users.noreply.github.com>
|
title: "[data] update searx.data - ${{ matrix.fetch }}"
|
||||||
signoff: false
|
commit-message: "[data] update searx.data - ${{ matrix.fetch }}"
|
||||||
branch: update_data_${{ matrix.fetch }}
|
branch: "update_data_${{ matrix.fetch }}"
|
||||||
delete-branch: true
|
delete-branch: "true"
|
||||||
draft: false
|
draft: "false"
|
||||||
title: '[data] update searx.data - ${{ matrix.fetch }}'
|
signoff: "false"
|
||||||
body: |
|
|
||||||
update searx.data - ${{ matrix.fetch }}
|
|
||||||
labels: |
|
labels: |
|
||||||
data
|
data
|
||||||
|
|
||||||
- name: Check outputs
|
- name: Display information
|
||||||
run: |
|
run: |
|
||||||
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
|
echo "Pull Request Number - ${{ steps.cpr.outputs.pull-request-number }}"
|
||||||
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
|
echo "Pull Request URL - ${{ steps.cpr.outputs.pull-request-url }}"
|
||||||
|
|||||||
66
.github/workflows/documentation.yml
vendored
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
---
|
||||||
|
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"
|
||||||
235
.github/workflows/integration.yml
vendored
@@ -1,205 +1,96 @@
|
|||||||
|
---
|
||||||
name: Integration
|
name: Integration
|
||||||
|
|
||||||
on: # yamllint disable-line rule:truthy
|
# yamllint disable-line rule:truthy
|
||||||
|
on:
|
||||||
push:
|
push:
|
||||||
branches: ["master"]
|
branches:
|
||||||
|
- master
|
||||||
pull_request:
|
pull_request:
|
||||||
branches: ["master"]
|
branches:
|
||||||
|
- master
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref_name }}
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
permissions:
|
permissions:
|
||||||
contents: read
|
contents: read
|
||||||
|
|
||||||
|
env:
|
||||||
|
PYTHON_VERSION: "3.13"
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
python:
|
test:
|
||||||
name: Python ${{ matrix.python-version }}
|
name: Python ${{ matrix.python-version }}
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-24.04
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
os: [ubuntu-20.04]
|
python-version:
|
||||||
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
- "3.9"
|
||||||
|
- "3.10"
|
||||||
|
- "3.11"
|
||||||
|
- "3.12"
|
||||||
|
- "3.13"
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Setup Python
|
||||||
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@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: ${{ matrix.python-version }}
|
python-version: "${{ matrix.python-version }}"
|
||||||
architecture: 'x64'
|
|
||||||
- name: Cache Python dependencies
|
- name: Checkout
|
||||||
id: cache-python
|
uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
persist-credentials: "false"
|
||||||
|
|
||||||
|
- name: Setup cache Python
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
key: "python-${{ matrix.python-version }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
||||||
./local
|
restore-keys: "python-${{ matrix.python-version }}-${{ runner.arch }}-"
|
||||||
./.nvm
|
path: "./local/"
|
||||||
./node_modules
|
|
||||||
key: python-${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('requirements*.txt', 'setup.py') }}
|
- name: Setup venv
|
||||||
- name: Install Python dependencies
|
run: make V=1 install
|
||||||
if: steps.cache-python.outputs.cache-hit != 'true'
|
|
||||||
run: |
|
|
||||||
make V=1 install
|
|
||||||
make V=1 gecko.driver
|
|
||||||
- name: Run tests
|
- name: Run tests
|
||||||
run: make V=1 ci.test
|
run: make V=1 ci.test
|
||||||
|
|
||||||
themes:
|
theme:
|
||||||
name: Themes
|
name: Theme
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-24.04-arm
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Setup Python
|
||||||
uses: actions/checkout@v4
|
|
||||||
- name: Install Ubuntu packages
|
|
||||||
run: sudo ./utils/searxng.sh install buildhost
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v5
|
uses: actions/setup-python@v5
|
||||||
with:
|
with:
|
||||||
python-version: '3.12'
|
python-version: "${{ env.PYTHON_VERSION }}"
|
||||||
architecture: 'x64'
|
|
||||||
- name: Cache Python dependencies
|
|
||||||
id: cache-python
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
./local
|
|
||||||
./.nvm
|
|
||||||
./node_modules
|
|
||||||
key: python-ubuntu-20.04-3.12-${{ 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
|
|
||||||
|
|
||||||
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
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
with:
|
with:
|
||||||
fetch-depth: '0'
|
persist-credentials: "false"
|
||||||
persist-credentials: false
|
|
||||||
- name: Install Ubuntu packages
|
|
||||||
run: sudo ./utils/searxng.sh install buildhost
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.12'
|
|
||||||
architecture: 'x64'
|
|
||||||
- name: Cache Python dependencies
|
|
||||||
id: cache-python
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
./local
|
|
||||||
./.nvm
|
|
||||||
./node_modules
|
|
||||||
key: python-ubuntu-20.04-3.12-${{ 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: '[doc] build from commit ${{ github.sha }}'
|
|
||||||
|
|
||||||
babel:
|
- name: Setup Node.js
|
||||||
name: Update translations branch
|
uses: actions/setup-node@v4
|
||||||
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:
|
with:
|
||||||
fetch-depth: '0'
|
node-version-file: "./.nvmrc"
|
||||||
token: ${{ secrets.WEBLATE_GITHUB_TOKEN }}
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.12'
|
|
||||||
architecture: 'x64'
|
|
||||||
- name: Cache Python dependencies
|
|
||||||
id: cache-python
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
./local
|
|
||||||
./.nvm
|
|
||||||
./node_modules
|
|
||||||
key: python-ubuntu-20.04-3.12-${{ 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: |
|
|
||||||
make V=1 weblate.push.translations
|
|
||||||
|
|
||||||
dockers:
|
- name: Setup cache Node.js
|
||||||
name: Docker
|
|
||||||
if: github.ref == 'refs/heads/master'
|
|
||||||
needs:
|
|
||||||
- python
|
|
||||||
- themes
|
|
||||||
- documentation
|
|
||||||
env:
|
|
||||||
DOCKERHUB_USERNAME: ${{ secrets.DOCKERHUB_USERNAME }}
|
|
||||||
runs-on: ubuntu-20.04
|
|
||||||
steps:
|
|
||||||
- name: Checkout
|
|
||||||
if: env.DOCKERHUB_USERNAME != null
|
|
||||||
uses: actions/checkout@v4
|
|
||||||
with:
|
|
||||||
# make sure "make docker.push" can get the git history
|
|
||||||
fetch-depth: '0'
|
|
||||||
- name: Set up Python
|
|
||||||
uses: actions/setup-python@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.12'
|
|
||||||
architecture: 'x64'
|
|
||||||
- name: Cache Python dependencies
|
|
||||||
id: cache-python
|
|
||||||
uses: actions/cache@v4
|
uses: actions/cache@v4
|
||||||
with:
|
with:
|
||||||
path: |
|
key: "nodejs-${{ runner.arch }}-${{ hashFiles('./.nvmrc', './package.json') }}"
|
||||||
./local
|
path: "./client/simple/node_modules/"
|
||||||
./.nvm
|
|
||||||
./node_modules
|
- name: Setup cache Python
|
||||||
key: python-ubuntu-20.04-3.12-${{ hashFiles('requirements*.txt', 'setup.py','.nvmrc', 'package.json') }}
|
uses: actions/cache@v4
|
||||||
- name: Set up QEMU
|
|
||||||
if: env.DOCKERHUB_USERNAME != null
|
|
||||||
uses: docker/setup-qemu-action@v1
|
|
||||||
- name: Set up Docker Buildx
|
|
||||||
if: env.DOCKERHUB_USERNAME != null
|
|
||||||
uses: docker/setup-buildx-action@v1
|
|
||||||
- name: Login to DockerHub
|
|
||||||
if: env.DOCKERHUB_USERNAME != null
|
|
||||||
uses: docker/login-action@v1
|
|
||||||
with:
|
with:
|
||||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
key: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-${{ hashFiles('./requirements*.txt') }}"
|
||||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
restore-keys: "python-${{ env.PYTHON_VERSION }}-${{ runner.arch }}-"
|
||||||
- name: Build and push
|
path: "./local/"
|
||||||
if: env.DOCKERHUB_USERNAME != null
|
|
||||||
run: make -e GIT_URL=$(git remote get-url origin) docker.buildx
|
- name: Setup venv
|
||||||
|
run: make V=1 install
|
||||||
|
|
||||||
|
- name: Build
|
||||||
|
run: make themes.all
|
||||||
|
|||||||
136
.github/workflows/l10n.yml
vendored
Normal file
@@ -0,0 +1,136 @@
|
|||||||
|
---
|
||||||
|
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 }}"
|
||||||
51
.github/workflows/security.yml
vendored
@@ -1,28 +1,43 @@
|
|||||||
name: "Security checks"
|
---
|
||||||
on: # yamllint disable-line rule:truthy
|
name: Security
|
||||||
|
|
||||||
|
# yamllint disable-line rule:truthy
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
schedule:
|
schedule:
|
||||||
- cron: "42 05 * * *"
|
- cron: "42 05 * * *"
|
||||||
workflow_dispatch:
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.ref_name }}
|
||||||
|
cancel-in-progress: false
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
dockers:
|
container:
|
||||||
name: Trivy ${{ matrix.image }}
|
name: Container
|
||||||
runs-on: ubuntu-20.04
|
runs-on: ubuntu-24.04-arm
|
||||||
|
permissions:
|
||||||
|
security-events: write
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
- name: Run Trivy vulnerability scanner
|
|
||||||
uses: aquasecurity/trivy-action@master
|
|
||||||
with:
|
with:
|
||||||
image-ref: 'searxng/searxng:latest'
|
persist-credentials: "false"
|
||||||
ignore-unfixed: false
|
|
||||||
vuln-type: 'os,library'
|
|
||||||
severity: 'UNKNOWN,LOW,MEDIUM,HIGH,CRITICAL'
|
|
||||||
format: 'sarif'
|
|
||||||
output: 'trivy-results.sarif'
|
|
||||||
|
|
||||||
- name: Upload Trivy scan results to GitHub Security tab
|
- name: Run Trivy scanner
|
||||||
uses: github/codeql-action/upload-sarif@v2
|
uses: aquasecurity/trivy-action@0.30.0
|
||||||
with:
|
with:
|
||||||
sarif_file: 'trivy-results.sarif'
|
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"
|
||||||
|
|
||||||
|
- name: Upload SARIFs
|
||||||
|
uses: github/codeql-action/upload-sarif@v3
|
||||||
|
with:
|
||||||
|
sarif_file: "./trivy-results.sarif"
|
||||||
|
|||||||
59
.github/workflows/translations-update.yml
vendored
@@ -1,59 +0,0 @@
|
|||||||
name: "Update translations"
|
|
||||||
on: # yamllint disable-line rule:truthy
|
|
||||||
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@v5
|
|
||||||
with:
|
|
||||||
python-version: '3.12'
|
|
||||||
architecture: 'x64'
|
|
||||||
- name: Cache Python dependencies
|
|
||||||
id: cache-python
|
|
||||||
uses: actions/cache@v4
|
|
||||||
with:
|
|
||||||
path: |
|
|
||||||
./local
|
|
||||||
./.nvm
|
|
||||||
./node_modules
|
|
||||||
key: python-ubuntu-20.04-3.12-${{ 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: '[l10n] update translations from Weblate'
|
|
||||||
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: '[l10n] update translations from Weblate'
|
|
||||||
body: |
|
|
||||||
update translations from Weblate
|
|
||||||
labels: |
|
|
||||||
translation
|
|
||||||
@@ -1,2 +1,4 @@
|
|||||||
python 3.12.0
|
nodejs 23.5.0
|
||||||
shellcheck 0.9.0
|
python 3.13.1
|
||||||
|
shellcheck 0.10.0
|
||||||
|
sqlite 3.47.2
|
||||||
@@ -174,3 +174,6 @@ features or generally made searx better:
|
|||||||
- @micsthepick
|
- @micsthepick
|
||||||
- Daniel Kukula `<https://github.com/dkuku>`
|
- Daniel Kukula `<https://github.com/dkuku>`
|
||||||
- Patrick Evans `https://github.com/holysoles`
|
- Patrick Evans `https://github.com/holysoles`
|
||||||
|
- Daniel Mowitz `<https://daniel.mowitz.rocks>`
|
||||||
|
- `Bearz314 <https://github.com/bearz314>`_
|
||||||
|
- Tommaso Colella `<https://github.com/gioleppe>`
|
||||||
|
|||||||
89
Dockerfile
@@ -1,89 +0,0 @@
|
|||||||
FROM alpine:3.20
|
|
||||||
ENTRYPOINT ["/sbin/tini","--","/usr/local/searxng/dockerfiles/docker-entrypoint.sh"]
|
|
||||||
EXPOSE 8080
|
|
||||||
VOLUME /etc/searxng
|
|
||||||
|
|
||||||
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 \
|
|
||||||
UWSGI_WORKERS=%k \
|
|
||||||
UWSGI_THREADS=4
|
|
||||||
|
|
||||||
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 \
|
|
||||||
openssl-dev \
|
|
||||||
tar \
|
|
||||||
git \
|
|
||||||
&& apk add --no-cache \
|
|
||||||
ca-certificates \
|
|
||||||
python3 \
|
|
||||||
py3-pip \
|
|
||||||
libxml2 \
|
|
||||||
libxslt \
|
|
||||||
openssl \
|
|
||||||
tini \
|
|
||||||
uwsgi \
|
|
||||||
uwsgi-python3 \
|
|
||||||
brotli \
|
|
||||||
&& pip3 install --break-system-packages --no-cache -r requirements.txt \
|
|
||||||
&& apk del build-dependencies \
|
|
||||||
&& rm -rf /root/.cache
|
|
||||||
|
|
||||||
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 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 {} \+
|
|
||||||
|
|
||||||
# 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.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"
|
|
||||||
20
Makefile
@@ -50,11 +50,11 @@ search.checker.%: install
|
|||||||
$(Q)./manage pyenv.cmd searxng-checker -v "$(subst _, ,$(patsubst search.checker.%,%,$@))"
|
$(Q)./manage pyenv.cmd searxng-checker -v "$(subst _, ,$(patsubst search.checker.%,%,$@))"
|
||||||
|
|
||||||
PHONY += test ci.test test.shell
|
PHONY += test ci.test test.shell
|
||||||
ci.test: test.yamllint test.black test.pyright test.pylint test.unit test.robot test.rst test.pybabel
|
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.pyright test.pylint test.unit test.robot test.rst test.shell
|
test: test.yamllint test.black test.types.dev test.pylint test.unit test.robot test.rst test.shell
|
||||||
test.shell:
|
test.shell:
|
||||||
$(Q)shellcheck -x -s dash \
|
$(Q)shellcheck -x -s dash \
|
||||||
dockerfiles/docker-entrypoint.sh
|
container/docker-entrypoint.sh
|
||||||
$(Q)shellcheck -x -s bash \
|
$(Q)shellcheck -x -s bash \
|
||||||
utils/brand.sh \
|
utils/brand.sh \
|
||||||
$(MTOOLS) \
|
$(MTOOLS) \
|
||||||
@@ -75,16 +75,18 @@ test.shell:
|
|||||||
# wrap ./manage script
|
# wrap ./manage script
|
||||||
|
|
||||||
MANAGE += weblate.translations.commit weblate.push.translations
|
MANAGE += weblate.translations.commit weblate.push.translations
|
||||||
MANAGE += data.all data.traits data.useragents data.locales
|
MANAGE += data.all data.traits data.useragents data.locales data.currencies
|
||||||
MANAGE += docs.html docs.live docs.gh-pages docs.prebuild docs.clean
|
MANAGE += docs.html docs.live docs.gh-pages docs.prebuild docs.clean
|
||||||
MANAGE += docker.build docker.push docker.buildx
|
MANAGE += podman.build
|
||||||
|
MANAGE += docker.build docker.buildx
|
||||||
|
MANAGE += container.build container.test container.push
|
||||||
MANAGE += gecko.driver
|
MANAGE += gecko.driver
|
||||||
MANAGE += node.env node.env.dev node.clean
|
MANAGE += node.env node.env.dev node.clean
|
||||||
MANAGE += py.build py.clean
|
MANAGE += py.build py.clean
|
||||||
MANAGE += pyenv pyenv.install pyenv.uninstall
|
MANAGE += pyenv pyenv.install pyenv.uninstall
|
||||||
MANAGE += format.python
|
MANAGE += format.python
|
||||||
MANAGE += test.yamllint test.pylint test.pyright test.black test.pybabel test.unit test.coverage test.robot test.rst test.clean
|
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.simple themes.simple.test pygments.less
|
MANAGE += themes.all themes.fix themes.test
|
||||||
MANAGE += static.build.commit static.build.drop static.build.restore
|
MANAGE += static.build.commit static.build.drop static.build.restore
|
||||||
MANAGE += nvm.install nvm.clean nvm.status nvm.nodejs
|
MANAGE += nvm.install nvm.clean nvm.status nvm.nodejs
|
||||||
|
|
||||||
@@ -95,8 +97,8 @@ $(MANAGE):
|
|||||||
|
|
||||||
# short hands of selected targets
|
# short hands of selected targets
|
||||||
|
|
||||||
PHONY += docs docker themes
|
PHONY += docs container themes
|
||||||
|
|
||||||
docs: docs.html
|
docs: docs.html
|
||||||
docker: docker.build
|
container: container.build
|
||||||
themes: themes.all
|
themes: themes.all
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
----
|
----
|
||||||
|
|
||||||
.. figure:: https://raw.githubusercontent.com/searxng/searxng/master/src/brand/searxng.svg
|
.. figure:: https://raw.githubusercontent.com/searxng/searxng/master/client/simple/src/brand/searxng.svg
|
||||||
:target: https://docs.searxng.org/
|
:target: https://docs.searxng.org/
|
||||||
:alt: SearXNG
|
:alt: SearXNG
|
||||||
:width: 100%
|
:width: 100%
|
||||||
@@ -34,7 +34,7 @@ A user_, admin_ and developer_ handbook is available on the homepage_.
|
|||||||
.. _homepage: https://docs.searxng.org/
|
.. _homepage: https://docs.searxng.org/
|
||||||
.. _metasearch engine: https://en.wikipedia.org/wiki/Metasearch_engine
|
.. _metasearch engine: https://en.wikipedia.org/wiki/Metasearch_engine
|
||||||
|
|
||||||
.. |SearXNG logo| image:: https://raw.githubusercontent.com/searxng/searxng/master/src/brand/searxng-wordmark.svg
|
.. |SearXNG logo| image:: https://raw.githubusercontent.com/searxng/searxng/master/client/simple/src/brand/searxng-wordmark.svg
|
||||||
:target: https://docs.searxng.org/
|
:target: https://docs.searxng.org/
|
||||||
:width: 5%
|
:width: 5%
|
||||||
|
|
||||||
|
|||||||
3
client/simple/.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
dist
|
||||||
|
node_modules
|
||||||
|
.stylelintcache
|
||||||
17
client/simple/.stylelintrc.json
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
{
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
}
|
||||||
24
client/simple/README.rst
Normal file
@@ -0,0 +1,24 @@
|
|||||||
|
=====================
|
||||||
|
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
|
||||||
34
client/simple/eslint.config.js
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
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],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
];
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
this file is generated automatically by searxng_extra/update/update_pygments.py
|
this file is generated automatically by searxng_extra/update/update_pygments.py
|
||||||
using pygments version 2.18.0
|
using pygments version 2.19.1
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
@@ -13,9 +13,9 @@
|
|||||||
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||||
.hll { background-color: #ffffcc }
|
.hll { background-color: #ffffcc }
|
||||||
.c { color: #3D7B7B; font-style: italic } /* Comment */
|
.c { color: #3D7B7B; font-style: italic } /* Comment */
|
||||||
.err { border: 1px solid #FF0000 } /* Error */
|
.err { border: 1px solid #F00 } /* Error */
|
||||||
.k { color: #008000; font-weight: bold } /* Keyword */
|
.k { color: #008000; font-weight: bold } /* Keyword */
|
||||||
.o { color: #666666 } /* Operator */
|
.o { color: #666 } /* Operator */
|
||||||
.ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
|
.ch { color: #3D7B7B; font-style: italic } /* Comment.Hashbang */
|
||||||
.cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
|
.cm { color: #3D7B7B; font-style: italic } /* Comment.Multiline */
|
||||||
.cp { color: #9C6500 } /* Comment.Preproc */
|
.cp { color: #9C6500 } /* Comment.Preproc */
|
||||||
@@ -32,34 +32,34 @@
|
|||||||
.gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
.gp { color: #000080; font-weight: bold } /* Generic.Prompt */
|
||||||
.gs { font-weight: bold } /* Generic.Strong */
|
.gs { font-weight: bold } /* Generic.Strong */
|
||||||
.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
.gu { color: #800080; font-weight: bold } /* Generic.Subheading */
|
||||||
.gt { color: #0044DD } /* Generic.Traceback */
|
.gt { color: #04D } /* Generic.Traceback */
|
||||||
.kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
.kc { color: #008000; font-weight: bold } /* Keyword.Constant */
|
||||||
.kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
.kd { color: #008000; font-weight: bold } /* Keyword.Declaration */
|
||||||
.kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
|
.kn { color: #008000; font-weight: bold } /* Keyword.Namespace */
|
||||||
.kp { color: #008000 } /* Keyword.Pseudo */
|
.kp { color: #008000 } /* Keyword.Pseudo */
|
||||||
.kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
.kr { color: #008000; font-weight: bold } /* Keyword.Reserved */
|
||||||
.kt { color: #B00040 } /* Keyword.Type */
|
.kt { color: #B00040 } /* Keyword.Type */
|
||||||
.m { color: #666666 } /* Literal.Number */
|
.m { color: #666 } /* Literal.Number */
|
||||||
.s { color: #BA2121 } /* Literal.String */
|
.s { color: #BA2121 } /* Literal.String */
|
||||||
.na { color: #687822 } /* Name.Attribute */
|
.na { color: #687822 } /* Name.Attribute */
|
||||||
.nb { color: #008000 } /* Name.Builtin */
|
.nb { color: #008000 } /* Name.Builtin */
|
||||||
.nc { color: #0000FF; font-weight: bold } /* Name.Class */
|
.nc { color: #00F; font-weight: bold } /* Name.Class */
|
||||||
.no { color: #880000 } /* Name.Constant */
|
.no { color: #800 } /* Name.Constant */
|
||||||
.nd { color: #AA22FF } /* Name.Decorator */
|
.nd { color: #A2F } /* Name.Decorator */
|
||||||
.ni { color: #717171; font-weight: bold } /* Name.Entity */
|
.ni { color: #717171; font-weight: bold } /* Name.Entity */
|
||||||
.ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
|
.ne { color: #CB3F38; font-weight: bold } /* Name.Exception */
|
||||||
.nf { color: #0000FF } /* Name.Function */
|
.nf { color: #00F } /* Name.Function */
|
||||||
.nl { color: #767600 } /* Name.Label */
|
.nl { color: #767600 } /* Name.Label */
|
||||||
.nn { color: #0000FF; font-weight: bold } /* Name.Namespace */
|
.nn { color: #00F; font-weight: bold } /* Name.Namespace */
|
||||||
.nt { color: #008000; font-weight: bold } /* Name.Tag */
|
.nt { color: #008000; font-weight: bold } /* Name.Tag */
|
||||||
.nv { color: #19177C } /* Name.Variable */
|
.nv { color: #19177C } /* Name.Variable */
|
||||||
.ow { color: #AA22FF; font-weight: bold } /* Operator.Word */
|
.ow { color: #A2F; font-weight: bold } /* Operator.Word */
|
||||||
.w { color: #bbbbbb } /* Text.Whitespace */
|
.w { color: #BBB } /* Text.Whitespace */
|
||||||
.mb { color: #666666 } /* Literal.Number.Bin */
|
.mb { color: #666 } /* Literal.Number.Bin */
|
||||||
.mf { color: #666666 } /* Literal.Number.Float */
|
.mf { color: #666 } /* Literal.Number.Float */
|
||||||
.mh { color: #666666 } /* Literal.Number.Hex */
|
.mh { color: #666 } /* Literal.Number.Hex */
|
||||||
.mi { color: #666666 } /* Literal.Number.Integer */
|
.mi { color: #666 } /* Literal.Number.Integer */
|
||||||
.mo { color: #666666 } /* Literal.Number.Oct */
|
.mo { color: #666 } /* Literal.Number.Oct */
|
||||||
.sa { color: #BA2121 } /* Literal.String.Affix */
|
.sa { color: #BA2121 } /* Literal.String.Affix */
|
||||||
.sb { color: #BA2121 } /* Literal.String.Backtick */
|
.sb { color: #BA2121 } /* Literal.String.Backtick */
|
||||||
.sc { color: #BA2121 } /* Literal.String.Char */
|
.sc { color: #BA2121 } /* Literal.String.Char */
|
||||||
@@ -74,12 +74,12 @@
|
|||||||
.s1 { color: #BA2121 } /* Literal.String.Single */
|
.s1 { color: #BA2121 } /* Literal.String.Single */
|
||||||
.ss { color: #19177C } /* Literal.String.Symbol */
|
.ss { color: #19177C } /* Literal.String.Symbol */
|
||||||
.bp { color: #008000 } /* Name.Builtin.Pseudo */
|
.bp { color: #008000 } /* Name.Builtin.Pseudo */
|
||||||
.fm { color: #0000FF } /* Name.Function.Magic */
|
.fm { color: #00F } /* Name.Function.Magic */
|
||||||
.vc { color: #19177C } /* Name.Variable.Class */
|
.vc { color: #19177C } /* Name.Variable.Class */
|
||||||
.vg { color: #19177C } /* Name.Variable.Global */
|
.vg { color: #19177C } /* Name.Variable.Global */
|
||||||
.vi { color: #19177C } /* Name.Variable.Instance */
|
.vi { color: #19177C } /* Name.Variable.Instance */
|
||||||
.vm { color: #19177C } /* Name.Variable.Magic */
|
.vm { color: #19177C } /* Name.Variable.Magic */
|
||||||
.il { color: #666666 } /* Literal.Number.Integer.Long */
|
.il { color: #666 } /* Literal.Number.Integer.Long */
|
||||||
}
|
}
|
||||||
|
|
||||||
.code-highlight-dark(){
|
.code-highlight-dark(){
|
||||||
@@ -91,33 +91,33 @@
|
|||||||
td.linenos .special { color: #3c4354; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
td.linenos .special { color: #3c4354; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||||
span.linenos.special { color: #3c4354; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
span.linenos.special { color: #3c4354; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; }
|
||||||
.hll { background-color: #6e7681 }
|
.hll { background-color: #6e7681 }
|
||||||
.c { color: #7e8aa1 } /* Comment */
|
.c { color: #7E8AA1 } /* Comment */
|
||||||
.err { color: #f88f7f } /* Error */
|
.err { color: #F88F7F } /* Error */
|
||||||
.esc { color: #d4d2c8 } /* Escape */
|
.esc { color: #D4D2C8 } /* Escape */
|
||||||
.g { color: #d4d2c8 } /* Generic */
|
.g { color: #D4D2C8 } /* Generic */
|
||||||
.k { color: #FFAD66 } /* Keyword */
|
.k { color: #FFAD66 } /* Keyword */
|
||||||
.l { color: #D5FF80 } /* Literal */
|
.l { color: #D5FF80 } /* Literal */
|
||||||
.n { color: #d4d2c8 } /* Name */
|
.n { color: #D4D2C8 } /* Name */
|
||||||
.o { color: #FFAD66 } /* Operator */
|
.o { color: #FFAD66 } /* Operator */
|
||||||
.x { color: #d4d2c8 } /* Other */
|
.x { color: #D4D2C8 } /* Other */
|
||||||
.p { color: #d4d2c8 } /* Punctuation */
|
.p { color: #D4D2C8 } /* Punctuation */
|
||||||
.ch { color: #f88f7f; font-style: italic } /* Comment.Hashbang */
|
.ch { color: #F88F7F; font-style: italic } /* Comment.Hashbang */
|
||||||
.cm { color: #7e8aa1 } /* Comment.Multiline */
|
.cm { color: #7E8AA1 } /* Comment.Multiline */
|
||||||
.cp { color: #FFAD66; font-weight: bold } /* Comment.Preproc */
|
.cp { color: #FFAD66; font-weight: bold } /* Comment.Preproc */
|
||||||
.cpf { color: #7e8aa1 } /* Comment.PreprocFile */
|
.cpf { color: #7E8AA1 } /* Comment.PreprocFile */
|
||||||
.c1 { color: #7e8aa1 } /* Comment.Single */
|
.c1 { color: #7E8AA1 } /* Comment.Single */
|
||||||
.cs { color: #7e8aa1; font-style: italic } /* Comment.Special */
|
.cs { color: #7E8AA1; font-style: italic } /* Comment.Special */
|
||||||
.gd { color: #f88f7f; background-color: #3d1e20 } /* Generic.Deleted */
|
.gd { color: #F88F7F; background-color: #3D1E20 } /* Generic.Deleted */
|
||||||
.ge { color: #d4d2c8; font-style: italic } /* Generic.Emph */
|
.ge { color: #D4D2C8; font-style: italic } /* Generic.Emph */
|
||||||
.ges { color: #d4d2c8 } /* Generic.EmphStrong */
|
.ges { color: #D4D2C8 } /* Generic.EmphStrong */
|
||||||
.gr { color: #f88f7f } /* Generic.Error */
|
.gr { color: #F88F7F } /* Generic.Error */
|
||||||
.gh { color: #d4d2c8 } /* Generic.Heading */
|
.gh { color: #D4D2C8 } /* Generic.Heading */
|
||||||
.gi { color: #6ad4af; background-color: #19362c } /* Generic.Inserted */
|
.gi { color: #6AD4AF; background-color: #19362C } /* Generic.Inserted */
|
||||||
.go { color: #7e8aa1 } /* Generic.Output */
|
.go { color: #7E8AA1 } /* Generic.Output */
|
||||||
.gp { color: #d4d2c8 } /* Generic.Prompt */
|
.gp { color: #D4D2C8 } /* Generic.Prompt */
|
||||||
.gs { color: #d4d2c8; font-weight: bold } /* Generic.Strong */
|
.gs { color: #D4D2C8; font-weight: bold } /* Generic.Strong */
|
||||||
.gu { color: #d4d2c8 } /* Generic.Subheading */
|
.gu { color: #D4D2C8 } /* Generic.Subheading */
|
||||||
.gt { color: #f88f7f } /* Generic.Traceback */
|
.gt { color: #F88F7F } /* Generic.Traceback */
|
||||||
.kc { color: #FFAD66 } /* Keyword.Constant */
|
.kc { color: #FFAD66 } /* Keyword.Constant */
|
||||||
.kd { color: #FFAD66 } /* Keyword.Declaration */
|
.kd { color: #FFAD66 } /* Keyword.Declaration */
|
||||||
.kn { color: #FFAD66 } /* Keyword.Namespace */
|
.kn { color: #FFAD66 } /* Keyword.Namespace */
|
||||||
@@ -131,19 +131,19 @@
|
|||||||
.nb { color: #FFD173 } /* Name.Builtin */
|
.nb { color: #FFD173 } /* Name.Builtin */
|
||||||
.nc { color: #73D0FF } /* Name.Class */
|
.nc { color: #73D0FF } /* Name.Class */
|
||||||
.no { color: #FFD173 } /* Name.Constant */
|
.no { color: #FFD173 } /* Name.Constant */
|
||||||
.nd { color: #7e8aa1; font-weight: bold; font-style: italic } /* Name.Decorator */
|
.nd { color: #7E8AA1; font-weight: bold; font-style: italic } /* Name.Decorator */
|
||||||
.ni { color: #95E6CB } /* Name.Entity */
|
.ni { color: #95E6CB } /* Name.Entity */
|
||||||
.ne { color: #73D0FF } /* Name.Exception */
|
.ne { color: #73D0FF } /* Name.Exception */
|
||||||
.nf { color: #FFD173 } /* Name.Function */
|
.nf { color: #FFD173 } /* Name.Function */
|
||||||
.nl { color: #d4d2c8 } /* Name.Label */
|
.nl { color: #D4D2C8 } /* Name.Label */
|
||||||
.nn { color: #d4d2c8 } /* Name.Namespace */
|
.nn { color: #D4D2C8 } /* Name.Namespace */
|
||||||
.nx { color: #d4d2c8 } /* Name.Other */
|
.nx { color: #D4D2C8 } /* Name.Other */
|
||||||
.py { color: #FFD173 } /* Name.Property */
|
.py { color: #FFD173 } /* Name.Property */
|
||||||
.nt { color: #5CCFE6 } /* Name.Tag */
|
.nt { color: #5CCFE6 } /* Name.Tag */
|
||||||
.nv { color: #d4d2c8 } /* Name.Variable */
|
.nv { color: #D4D2C8 } /* Name.Variable */
|
||||||
.ow { color: #FFAD66 } /* Operator.Word */
|
.ow { color: #FFAD66 } /* Operator.Word */
|
||||||
.pm { color: #d4d2c8 } /* Punctuation.Marker */
|
.pm { color: #D4D2C8 } /* Punctuation.Marker */
|
||||||
.w { color: #d4d2c8 } /* Text.Whitespace */
|
.w { color: #D4D2C8 } /* Text.Whitespace */
|
||||||
.mb { color: #DFBFFF } /* Literal.Number.Bin */
|
.mb { color: #DFBFFF } /* Literal.Number.Bin */
|
||||||
.mf { color: #DFBFFF } /* Literal.Number.Float */
|
.mf { color: #DFBFFF } /* Literal.Number.Float */
|
||||||
.mh { color: #DFBFFF } /* Literal.Number.Hex */
|
.mh { color: #DFBFFF } /* Literal.Number.Hex */
|
||||||
@@ -153,7 +153,7 @@
|
|||||||
.sb { color: #D5FF80 } /* Literal.String.Backtick */
|
.sb { color: #D5FF80 } /* Literal.String.Backtick */
|
||||||
.sc { color: #D5FF80 } /* Literal.String.Char */
|
.sc { color: #D5FF80 } /* Literal.String.Char */
|
||||||
.dl { color: #D5FF80 } /* Literal.String.Delimiter */
|
.dl { color: #D5FF80 } /* Literal.String.Delimiter */
|
||||||
.sd { color: #7e8aa1 } /* Literal.String.Doc */
|
.sd { color: #7E8AA1 } /* Literal.String.Doc */
|
||||||
.s2 { color: #D5FF80 } /* Literal.String.Double */
|
.s2 { color: #D5FF80 } /* Literal.String.Double */
|
||||||
.se { color: #95E6CB } /* Literal.String.Escape */
|
.se { color: #95E6CB } /* Literal.String.Escape */
|
||||||
.sh { color: #D5FF80 } /* Literal.String.Heredoc */
|
.sh { color: #D5FF80 } /* Literal.String.Heredoc */
|
||||||
@@ -164,10 +164,10 @@
|
|||||||
.ss { color: #DFBFFF } /* Literal.String.Symbol */
|
.ss { color: #DFBFFF } /* Literal.String.Symbol */
|
||||||
.bp { color: #5CCFE6 } /* Name.Builtin.Pseudo */
|
.bp { color: #5CCFE6 } /* Name.Builtin.Pseudo */
|
||||||
.fm { color: #FFD173 } /* Name.Function.Magic */
|
.fm { color: #FFD173 } /* Name.Function.Magic */
|
||||||
.vc { color: #d4d2c8 } /* Name.Variable.Class */
|
.vc { color: #D4D2C8 } /* Name.Variable.Class */
|
||||||
.vg { color: #d4d2c8 } /* Name.Variable.Global */
|
.vg { color: #D4D2C8 } /* Name.Variable.Global */
|
||||||
.vi { color: #d4d2c8 } /* Name.Variable.Instance */
|
.vi { color: #D4D2C8 } /* Name.Variable.Instance */
|
||||||
.vm { color: #d4d2c8 } /* Name.Variable.Magic */
|
.vm { color: #D4D2C8 } /* Name.Variable.Magic */
|
||||||
.il { color: #DFBFFF } /* Literal.Number.Integer.Long */
|
.il { color: #DFBFFF } /* Literal.Number.Integer.Long */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
7383
client/simple/package-lock.json
generated
Normal file
41
client/simple/package.json
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
{
|
||||||
|
"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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Before Width: | Height: | Size: 3.0 KiB After Width: | Height: | Size: 3.0 KiB |
26
client/simple/src/brand/searxng-wordmark.svg
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<?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>
|
||||||
|
After Width: | Height: | Size: 980 B |
1
client/simple/src/brand/searxng.svg
Normal file
|
After Width: | Height: | Size: 310 KiB |
184
client/simple/src/js/main/results.js
Normal file
@@ -0,0 +1,184 @@
|
|||||||
|
/* 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);
|
||||||
@@ -1,5 +1,8 @@
|
|||||||
/* SPDX-License-Identifier: AGPL-3.0-or-later */
|
/* SPDX-License-Identifier: AGPL-3.0-or-later */
|
||||||
/* global AutoComplete */
|
/* exported AutoComplete */
|
||||||
|
|
||||||
|
import AutoComplete from "../../../node_modules/autocomplete-js/dist/autocomplete.js";
|
||||||
|
|
||||||
(function (w, d, searxng) {
|
(function (w, d, searxng) {
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
1
client/simple/src/js/searxng.head.js
Normal file
@@ -0,0 +1 @@
|
|||||||
|
import "./head/00_init.js";
|
||||||
7
client/simple/src/js/searxng.js
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
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";
|
||||||
@@ -53,7 +53,7 @@
|
|||||||
color: var(--color-autocomplete-font);
|
color: var(--color-autocomplete-font);
|
||||||
max-height: 32rem;
|
max-height: 32rem;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
z-index: 100;
|
z-index: 5000;
|
||||||
margin-top: 3.5rem;
|
margin-top: 3.5rem;
|
||||||
border-radius: 0.8rem;
|
border-radius: 0.8rem;
|
||||||
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
@import "../generated/pygments.less";
|
@import "../../generated/pygments.less";
|
||||||
|
|
||||||
.codelines {
|
.codelines {
|
||||||
margin: @results-margin 0 0 0;
|
margin: @results-margin 0 0 0;
|
||||||
@@ -55,8 +55,12 @@
|
|||||||
--color-autocomplete-background: #fff;
|
--color-autocomplete-background: #fff;
|
||||||
--color-autocomplete-background-hover: #e3e3e3;
|
--color-autocomplete-background-hover: #e3e3e3;
|
||||||
/// Answer Colors
|
/// Answer Colors
|
||||||
--color-answer-font: #444; // same as --color-base-font
|
--color-answer-font: #444; // same as --color-base-font
|
||||||
--color-answer-background: #fff;
|
--color-answer-background: #fff;
|
||||||
|
// colors of the KeyValue result class
|
||||||
|
--color-result-keyvalue-col-table: #fdfbff;
|
||||||
|
--color-result-keyvalue-odd: #fdfbff;
|
||||||
|
--color-result-keyvalue-even: #fff;
|
||||||
/// Results Colors
|
/// Results Colors
|
||||||
--color-result-background: #fff;
|
--color-result-background: #fff;
|
||||||
--color-result-border: #ddd;
|
--color-result-border: #ddd;
|
||||||
@@ -85,8 +89,8 @@
|
|||||||
--color-result-detail-background: #242424;
|
--color-result-detail-background: #242424;
|
||||||
--color-result-detail-hr: #555;
|
--color-result-detail-hr: #555;
|
||||||
--color-result-detail-link: #8af;
|
--color-result-detail-link: #8af;
|
||||||
--color-result-detail-loader-border: rgba(255, 255, 255, 0.2);
|
--color-result-detail-loader-border: rgb(255 255 255 / 20%);
|
||||||
--color-result-detail-loader-borderleft: rgba(0, 0, 0, 0);
|
--color-result-detail-loader-borderleft: rgb(0 0 0 / 0%);
|
||||||
/// Toolkit Colors
|
/// Toolkit Colors
|
||||||
--color-toolkit-badge-font: #fff;
|
--color-toolkit-badge-font: #fff;
|
||||||
--color-toolkit-badge-background: #545454;
|
--color-toolkit-badge-background: #545454;
|
||||||
@@ -111,16 +115,16 @@
|
|||||||
--color-toolkit-checkbox-input-border: #3050ff;
|
--color-toolkit-checkbox-input-border: #3050ff;
|
||||||
--color-toolkit-engine-tooltip-border: #ddd;
|
--color-toolkit-engine-tooltip-border: #ddd;
|
||||||
--color-toolkit-engine-tooltip-background: #fff;
|
--color-toolkit-engine-tooltip-background: #fff;
|
||||||
--color-toolkit-loader-border: rgba(0, 0, 0, 0.2);
|
--color-toolkit-loader-border: rgb(0 0 0 / 20%);
|
||||||
--color-toolkit-loader-borderleft: rgba(255, 255, 255, 0);
|
--color-toolkit-loader-borderleft: rgb(255 255 255 / 0%);
|
||||||
--color-doc-code: #003;
|
--color-doc-code: #003;
|
||||||
--color-doc-code-background: #ddeaff;
|
--color-doc-code-background: #ddeaff;
|
||||||
/// Other misc colors
|
/// Other misc colors
|
||||||
--color-bar-chart-primary: #5bc0de;
|
--color-bar-chart-primary: #5bc0de;
|
||||||
--color-bar-chart-secondary: #deb15b;
|
--color-bar-chart-secondary: #deb15b;
|
||||||
--color-image-resolution-background: rgba(0, 0, 0, 50%);
|
--color-image-resolution-background: rgb(0 0 0 / 50%);
|
||||||
--color-image-resolution-font: #fff;
|
--color-image-resolution-font: #fff;
|
||||||
--color-loading-indicator: rgba(255, 255, 255, 0.2);
|
--color-loading-indicator: rgb(255 255 255 / 20%);
|
||||||
--color-loading-indicator-gap: #fff;
|
--color-loading-indicator-gap: #fff;
|
||||||
--color-line-number: #64708d;
|
--color-line-number: #64708d;
|
||||||
// Favicons Colors
|
// Favicons Colors
|
||||||
@@ -180,6 +184,10 @@
|
|||||||
/// Answer Colors
|
/// Answer Colors
|
||||||
--color-answer-font: #bbb; // same as --color-base-font
|
--color-answer-font: #bbb; // same as --color-base-font
|
||||||
--color-answer-background: #26292f;
|
--color-answer-background: #26292f;
|
||||||
|
// colors of the KeyValue result class
|
||||||
|
--color-result-keyvalue-col-table: #1e1e22;
|
||||||
|
--color-result-keyvalue-odd: #1e1e22;
|
||||||
|
--color-result-keyvalue-even: #26292f;
|
||||||
/// Results Colors
|
/// Results Colors
|
||||||
--color-result-background: #26292f;
|
--color-result-background: #26292f;
|
||||||
--color-result-border: #333;
|
--color-result-border: #333;
|
||||||
@@ -200,8 +208,8 @@
|
|||||||
--color-result-detail-background: #1a1a1c;
|
--color-result-detail-background: #1a1a1c;
|
||||||
--color-result-detail-hr: #555;
|
--color-result-detail-hr: #555;
|
||||||
--color-result-detail-link: #8af;
|
--color-result-detail-link: #8af;
|
||||||
--color-result-detail-loader-border: rgba(255, 255, 255, 0.2);
|
--color-result-detail-loader-border: rgb(255 255 255 / 20%);
|
||||||
--color-result-detail-loader-borderleft: rgba(0, 0, 0, 0);
|
--color-result-detail-loader-borderleft: rgb(0 0 0 / 0%);
|
||||||
// Images Colors
|
// Images Colors
|
||||||
--color-result-image-span-font: #bbb;
|
--color-result-image-span-font: #bbb;
|
||||||
--color-result-image-span-font-selected: #222;
|
--color-result-image-span-font-selected: #222;
|
||||||
@@ -234,8 +242,8 @@
|
|||||||
--color-toolkit-checkbox-input-border: #58f;
|
--color-toolkit-checkbox-input-border: #58f;
|
||||||
--color-toolkit-engine-tooltip-border: #333;
|
--color-toolkit-engine-tooltip-border: #333;
|
||||||
--color-toolkit-engine-tooltip-background: #222;
|
--color-toolkit-engine-tooltip-background: #222;
|
||||||
--color-toolkit-loader-border: rgba(255, 255, 255, 0.2);
|
--color-toolkit-loader-border: rgb(255 255 255 / 20%);
|
||||||
--color-toolkit-loader-borderleft: rgba(0, 0, 0, 0);
|
--color-toolkit-loader-borderleft: rgb(0 0 0 / 0%);
|
||||||
--color-doc-code: #ddd;
|
--color-doc-code: #ddd;
|
||||||
--color-doc-code-background: #4d5a6f;
|
--color-doc-code-background: #4d5a6f;
|
||||||
// Favicons Colors
|
// Favicons Colors
|
||||||
@@ -280,11 +288,11 @@
|
|||||||
@results-image-row-height-phone: 10rem;
|
@results-image-row-height-phone: 10rem;
|
||||||
@search-width: 44rem;
|
@search-width: 44rem;
|
||||||
// heigh of #search, see detail.less
|
// heigh of #search, see detail.less
|
||||||
@search-height: 7.6rem;
|
@search-height: 13rem;
|
||||||
|
|
||||||
/// Device Size
|
/// Device Size
|
||||||
/// @desktop > @tablet
|
/// @desktop > @tablet
|
||||||
@tablet: 79.75em; // see https://github.com/searxng/searxng/issues/874
|
@tablet: 79.75em; // see https://github.com/searxng/searxng/issues/874
|
||||||
@phone: 50em;
|
@phone: 50em;
|
||||||
@small-phone: 35em;
|
@small-phone: 35em;
|
||||||
@ultra-small-phone: 20rem;
|
@ultra-small-phone: 20rem;
|
||||||
@@ -293,12 +301,12 @@
|
|||||||
@stacked-bar-chart: rgb(0, 0, 0);
|
@stacked-bar-chart: rgb(0, 0, 0);
|
||||||
|
|
||||||
/// Load fonts from this directory.
|
/// Load fonts from this directory.
|
||||||
@icon-font-path: "../../../fonts/";
|
@icon-font-path: "../../../fonts/";
|
||||||
//** File name for all font files.
|
//** File name for all font files.
|
||||||
@icon-font-name: "glyphicons-halflings-regular";
|
@icon-font-name: "glyphicons-halflings-regular";
|
||||||
//** Element ID within SVG icon file.
|
//** Element ID within SVG icon file.
|
||||||
@icon-font-svg-id: "glyphicons_halflingsregular";
|
@icon-font-svg-id: "glyphicons_halflingsregular";
|
||||||
|
|
||||||
// decoration of the select HTML elements
|
// decoration of the select HTML elements
|
||||||
@select-light-svg-path: "../svg/select-light.svg";
|
@select-light-svg-path: "../svg/select-light.svg";
|
||||||
@select-dark-svg-path: "../svg/select-dark.svg";
|
@select-dark-svg-path: "../svg/select-dark.svg";
|
||||||
@@ -22,8 +22,9 @@ article.result-images .detail {
|
|||||||
bottom: 0;
|
bottom: 0;
|
||||||
background: var(--color-result-detail-background);
|
background: var(--color-result-detail-background);
|
||||||
border: 1px solid var(--color-result-detail-background);
|
border: 1px solid var(--color-result-detail-background);
|
||||||
z-index: 10000;
|
z-index: 1000;
|
||||||
padding: 4rem 3rem 3rem 3rem;
|
padding: 4rem 3rem 3rem 3rem;
|
||||||
|
overflow-y: scroll;
|
||||||
|
|
||||||
a.result-images-source {
|
a.result-images-source {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -42,7 +43,7 @@ article.result-images .detail {
|
|||||||
height: inherit;
|
height: inherit;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
min-height: inherit;
|
min-height: inherit;
|
||||||
max-height: calc(100vh - 25rem - 7rem);
|
max-height: calc(100vh - 25rem - 17rem);
|
||||||
background: inherit;
|
background: inherit;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -93,8 +94,7 @@ article.result-images .detail {
|
|||||||
|
|
||||||
p.result-url {
|
p.result-url {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow-x: hidden;
|
overflow: hidden hidden;
|
||||||
overflow-y: hidden;
|
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +149,7 @@ article.result-images .detail {
|
|||||||
height: 1.5rem;
|
height: 1.5rem;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
filter: opacity(40%);
|
filter: opacity(40%);
|
||||||
z-index: 2000002;
|
z-index: 1200;
|
||||||
|
|
||||||
span {
|
span {
|
||||||
display: block;
|
display: block;
|
||||||
@@ -204,7 +204,9 @@ article.result-images .detail {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#results.image-detail-open.scrolling article.result-images[data-vim-selected] .detail {
|
#results.image-detail-open.scrolling
|
||||||
|
article.result-images[data-vim-selected]
|
||||||
|
.detail {
|
||||||
top: 0;
|
top: 0;
|
||||||
|
|
||||||
a.result-images-source img {
|
a.result-images-source img {
|
||||||
@@ -1,14 +1,17 @@
|
|||||||
iframe[src^="https://w.soundcloud.com"] {
|
iframe[src^="https://w.soundcloud.com"]
|
||||||
|
{
|
||||||
height: 120px;
|
height: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
iframe[src^="https://www.deezer.com"] {
|
iframe[src^="https://www.deezer.com"]
|
||||||
|
{
|
||||||
// The real size is 92px, but 94px are needed to avoid an inner scrollbar of
|
// The real size is 92px, but 94px are needed to avoid an inner scrollbar of
|
||||||
// the embedded HTML.
|
// the embedded HTML.
|
||||||
height: 94px;
|
height: 94px;
|
||||||
}
|
}
|
||||||
|
|
||||||
iframe[src^="https://www.mixcloud.com"] {
|
iframe[src^="https://www.mixcloud.com"]
|
||||||
|
{
|
||||||
// the embedded player from mixcloud has some quirks: initial there is an
|
// the embedded player from mixcloud has some quirks: initial there is an
|
||||||
// issue with an image URL that is blocked since it is an a Cross-Origin
|
// issue with an image URL that is blocked since it is an a Cross-Origin
|
||||||
// request. The alternative text (<img alt='Mixcloud Logo'> then cause an
|
// request. The alternative text (<img alt='Mixcloud Logo'> then cause an
|
||||||
@@ -18,16 +21,19 @@ iframe[src^="https://www.mixcloud.com"] {
|
|||||||
height: 250px;
|
height: 250px;
|
||||||
}
|
}
|
||||||
|
|
||||||
iframe[src^="https://bandcamp.com/EmbeddedPlayer"] {
|
iframe[src^="https://bandcamp.com/EmbeddedPlayer"]
|
||||||
|
{
|
||||||
// show playlist
|
// show playlist
|
||||||
height: 350px;
|
height: 350px;
|
||||||
}
|
}
|
||||||
|
|
||||||
iframe[src^="https://bandcamp.com/EmbeddedPlayer/track"] {
|
iframe[src^="https://bandcamp.com/EmbeddedPlayer/track"]
|
||||||
|
{
|
||||||
// hide playlist
|
// hide playlist
|
||||||
height: 120px;
|
height: 120px;
|
||||||
}
|
}
|
||||||
|
|
||||||
iframe[src^="https://genius.com/songs"] {
|
iframe[src^="https://genius.com/songs"]
|
||||||
|
{
|
||||||
height: 65px;
|
height: 65px;
|
||||||
}
|
}
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
.title {
|
.title {
|
||||||
background: url('../img/searxng.png') no-repeat;
|
background: url("../img/searxng.png") no-repeat;
|
||||||
min-height: 4rem;
|
min-height: 4rem;
|
||||||
margin: 4rem auto;
|
margin: 4rem auto;
|
||||||
background-position: center;
|
background-position: center;
|
||||||
@@ -9,7 +9,7 @@
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type=checked] {
|
input[type="checked"] {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,6 +48,14 @@ table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.pref-group {
|
||||||
|
width: 100%;
|
||||||
|
font-weight: normal;
|
||||||
|
padding: 1rem 0.5rem;
|
||||||
|
.ltr-text-align-left();
|
||||||
|
background: var(--color-settings-table-group-background);
|
||||||
|
}
|
||||||
|
|
||||||
.value {
|
.value {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
35
client/simple/src/less/result_types/keyvalue.less
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
/*
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -15,8 +15,7 @@
|
|||||||
background: var(--color-header-background);
|
background: var(--color-header-background);
|
||||||
border-bottom: 1px solid var(--color-header-border);
|
border-bottom: 1px solid var(--color-header-border);
|
||||||
display: grid;
|
display: grid;
|
||||||
column-gap: 1.2rem;
|
gap: 1rem 1.2rem;
|
||||||
row-gap: 1rem;
|
|
||||||
grid-template-columns: 3rem 1fr;
|
grid-template-columns: 3rem 1fr;
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"logo search"
|
"logo search"
|
||||||
@@ -84,7 +83,9 @@ button.category_button {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// only used when JavaScript is disabled
|
// only used when JavaScript is disabled
|
||||||
.no-js #categories_container:has(button.category_button:focus-within) button.category_button {
|
.no-js
|
||||||
|
#categories_container:has(button.category_button:focus-within)
|
||||||
|
button.category_button {
|
||||||
&.selected {
|
&.selected {
|
||||||
color: var(--color-base-font);
|
color: var(--color-base-font);
|
||||||
border-bottom: none;
|
border-bottom: none;
|
||||||
@@ -159,7 +160,7 @@ button.category_button {
|
|||||||
outline: none;
|
outline: none;
|
||||||
color: var(--color-search-font);
|
color: var(--color-search-font);
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
z-index: 10000;
|
z-index: 1000;
|
||||||
|
|
||||||
&:hover {
|
&:hover {
|
||||||
color: var(--color-search-background-hover);
|
color: var(--color-search-background-hover);
|
||||||
@@ -184,7 +185,7 @@ html.no-js #clear_search.hide_if_nojs {
|
|||||||
outline: none;
|
outline: none;
|
||||||
color: var(--color-search-font);
|
color: var(--color-search-font);
|
||||||
font-size: 1.1rem;
|
font-size: 1.1rem;
|
||||||
z-index: 2;
|
z-index: 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
#q {
|
#q {
|
||||||
@@ -268,8 +269,7 @@ html.no-js #clear_search.hide_if_nojs {
|
|||||||
#categories {
|
#categories {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
.ltr-text-align-left();
|
.ltr-text-align-left();
|
||||||
overflow-x: scroll;
|
overflow: scroll hidden;
|
||||||
overflow-y: hidden;
|
|
||||||
-webkit-overflow-scrolling: touch;
|
-webkit-overflow-scrolling: touch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -280,8 +280,7 @@ html.no-js #clear_search.hide_if_nojs {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0.1rem 0 0 0;
|
padding: 0.1rem 0 0 0;
|
||||||
column-gap: 0;
|
gap: 0 0;
|
||||||
row-gap: 0;
|
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"logo search"
|
"logo search"
|
||||||
"categories categories";
|
"categories categories";
|
||||||
@@ -335,7 +334,7 @@ html.no-js #clear_search.hide_if_nojs {
|
|||||||
top: 0;
|
top: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
z-index: 10000;
|
z-index: 2000;
|
||||||
|
|
||||||
.search_box {
|
.search_box {
|
||||||
border-bottom: 1px solid var(--color-search-border);
|
border-bottom: 1px solid var(--color-search-border);
|
||||||
@@ -14,7 +14,7 @@ on the /search URL and when the "center alignment" preference is enabled.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (min-width: 62rem) {
|
@media screen and (width >= 62rem) {
|
||||||
.center-alignment-yes #main_results {
|
.center-alignment-yes #main_results {
|
||||||
--center-page-width: 60rem;
|
--center-page-width: 60rem;
|
||||||
}
|
}
|
||||||
@@ -63,9 +63,11 @@ on the /search URL and when the "center alignment" preference is enabled.
|
|||||||
}
|
}
|
||||||
|
|
||||||
#search_header {
|
#search_header {
|
||||||
grid-template-columns: calc(50% - 4.5rem - var(--center-page-width) / 2) 3rem var(--center-page-width);
|
grid-template-columns:
|
||||||
|
calc(50% - 4.5rem - var(--center-page-width) / 2)
|
||||||
|
3rem var(--center-page-width);
|
||||||
grid-template-areas: "na logo search" "na spacer categories";
|
grid-template-areas: "na logo search" "na spacer categories";
|
||||||
column-gap: 1.2rem; // from search.less
|
column-gap: 1.2rem; // from search.less
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-left: 0;
|
padding-left: 0;
|
||||||
padding-right: 0;
|
padding-right: 0;
|
||||||
@@ -91,10 +93,12 @@ on the /search URL and when the "center alignment" preference is enabled.
|
|||||||
align-self: flex-start;
|
align-self: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
&:not(.only_template_images):not(.image-detail-open) {
|
&:not(.only_template_images, .image-detail-open) {
|
||||||
// the gap is set in style.less
|
// the gap is set in style.less
|
||||||
.ltr-margin-left(1.5rem);
|
.ltr-margin-left(1.5rem);
|
||||||
grid-template-columns: calc(var(--center-page-width) - @results-gap - @results-sidebar-width) @results-sidebar-width;
|
grid-template-columns:
|
||||||
|
calc(var(--center-page-width) - @results-gap - @results-sidebar-width)
|
||||||
|
@results-sidebar-width;
|
||||||
|
|
||||||
#backToTop {
|
#backToTop {
|
||||||
.ltr-left(calc(50% - @results-sidebar-width - @results-gap + 1rem + var(--center-page-width) / 2));
|
.ltr-left(calc(50% - @results-sidebar-width - @results-gap + 1rem + var(--center-page-width) / 2));
|
||||||
@@ -109,7 +109,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Image detail
|
// Image detail
|
||||||
#results.image-detail-open article.result-images[data-vim-selected] .detail .result-images-labels p {
|
#results.image-detail-open
|
||||||
|
article.result-images[data-vim-selected]
|
||||||
|
.detail
|
||||||
|
.result-images-labels
|
||||||
|
p {
|
||||||
direction: rtl;
|
direction: rtl;
|
||||||
|
|
||||||
&.result-url {
|
&.result-url {
|
||||||
@@ -125,7 +129,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
// select HTML element
|
// select HTML element
|
||||||
@supports ((background-position-x: 100%) and ((appearance: none) or (-webkit-appearance: none) or (-moz-appearance: none))) {
|
@supports (
|
||||||
|
(background-position-x: 100%) and
|
||||||
|
(
|
||||||
|
(appearance: none) or (-webkit-appearance: none) or
|
||||||
|
(-moz-appearance: none)
|
||||||
|
)
|
||||||
|
) {
|
||||||
select {
|
select {
|
||||||
border-width: 0 0 0 2rem;
|
border-width: 0 0 0 2rem;
|
||||||
background-position-x: -2rem;
|
background-position-x: -2rem;
|
||||||
@@ -32,8 +32,8 @@
|
|||||||
// to center the results
|
// to center the results
|
||||||
@import "style-center.less";
|
@import "style-center.less";
|
||||||
|
|
||||||
// ion-icon
|
// sxng-icon-set
|
||||||
.ion-icon {
|
.sxng-icon-set {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
line-height: 1;
|
line-height: 1;
|
||||||
@@ -41,16 +41,16 @@
|
|||||||
.ltr-transform();
|
.ltr-transform();
|
||||||
}
|
}
|
||||||
|
|
||||||
.ion-icon-small {
|
.sxng-icon-set-small {
|
||||||
width: 1rem;
|
width: 1rem;
|
||||||
height: 1rem;
|
height: 1rem;
|
||||||
.ion-icon;
|
.sxng-icon-set;
|
||||||
}
|
}
|
||||||
|
|
||||||
.ion-icon-big {
|
.sxng-icon-set-big {
|
||||||
width: 1.5rem;
|
width: 1.5rem;
|
||||||
height: 1.5rem;
|
height: 1.5rem;
|
||||||
.ion-icon;
|
.sxng-icon-set;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Main LESS-Code
|
// Main LESS-Code
|
||||||
@@ -80,6 +80,12 @@ body {
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@supports (height: 100dvh) {
|
||||||
|
body {
|
||||||
|
height: 100dvh;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
main {
|
main {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin-bottom: 2rem;
|
margin-bottom: 2rem;
|
||||||
@@ -244,9 +250,8 @@ article[data-vim-selected].category-social {
|
|||||||
align-items: center;
|
align-items: center;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
color: var(--color-result-url-font);
|
color: var(--color-result-url-font);
|
||||||
flex-wrap: nowrap;
|
flex-flow: row nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
flex-direction: row;
|
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
|
||||||
@@ -269,9 +274,7 @@ article[data-vim-selected].category-social {
|
|||||||
.url_o2 {
|
.url_o2 {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
flex-basis: content;
|
flex: 0 1 content;
|
||||||
flex-grow: 0;
|
|
||||||
flex-shrink: 1;
|
|
||||||
text-align: right;
|
text-align: right;
|
||||||
padding-bottom: 1px;
|
padding-bottom: 1px;
|
||||||
|
|
||||||
@@ -472,7 +475,7 @@ article[data-vim-selected].category-social {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
border: none;
|
border: none;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
width: 100%;
|
width: auto;
|
||||||
object-fit: cover;
|
object-fit: cover;
|
||||||
vertical-align: bottom;
|
vertical-align: bottom;
|
||||||
background: var(--color-result-image-background);
|
background: var(--color-result-image-background);
|
||||||
@@ -546,14 +549,13 @@ article[data-vim-selected].category-social {
|
|||||||
margin-bottom: 0;
|
margin-bottom: 0;
|
||||||
.ltr-margin-left(@results-offset);
|
.ltr-margin-left(@results-offset);
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: @results-width @results-sidebar-width;
|
grid-template:
|
||||||
grid-template-rows: min-content min-content 1fr min-content;
|
"corrections sidebar" min-content
|
||||||
|
"answers sidebar" min-content
|
||||||
|
"urls sidebar" 1fr
|
||||||
|
"pagination sidebar" min-content
|
||||||
|
/ @results-width @results-sidebar-width;
|
||||||
gap: 0 @results-gap;
|
gap: 0 @results-gap;
|
||||||
grid-template-areas:
|
|
||||||
"corrections sidebar"
|
|
||||||
"answers sidebar"
|
|
||||||
"urls sidebar"
|
|
||||||
"pagination sidebar";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#results #sidebar *:first-child {
|
#results #sidebar *:first-child {
|
||||||
@@ -676,10 +678,7 @@ summary.title {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.answer-url {
|
.answer-url {
|
||||||
margin-left: auto;
|
margin: 5px 10px 10px auto;
|
||||||
margin-top: 5px;
|
|
||||||
margin-right: 10px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -788,7 +787,7 @@ summary.title {
|
|||||||
padding: 0.4rem;
|
padding: 0.4rem;
|
||||||
margin-left: 0.5rem;
|
margin-left: 0.5rem;
|
||||||
border-radius: 0.3rem;
|
border-radius: 0.3rem;
|
||||||
display: none; // will be shown by JS.
|
display: none; // will be shown by JS.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -979,19 +978,18 @@ summary.title {
|
|||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: @results-width;
|
grid-template:
|
||||||
grid-template-rows: min-content min-content min-content 1fr min-content min-content;
|
"corrections" min-content
|
||||||
|
"answers" min-content
|
||||||
|
"sidebar" min-content
|
||||||
|
"urls" 1fr
|
||||||
|
"pagination" min-content
|
||||||
|
/ @results-width;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
grid-template-areas:
|
|
||||||
"corrections"
|
|
||||||
"answers"
|
|
||||||
"sidebar"
|
|
||||||
"urls"
|
|
||||||
"pagination";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: calc(@tablet - 0.5px)) {
|
@media screen and (width <= calc(@tablet - 0.5px)) {
|
||||||
#links_on_top {
|
#links_on_top {
|
||||||
span {
|
span {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -999,7 +997,7 @@ summary.title {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@media screen and (max-width: 52rem) {
|
@media screen and (width <= 52rem) {
|
||||||
body.results_endpoint {
|
body.results_endpoint {
|
||||||
#links_on_top {
|
#links_on_top {
|
||||||
.link_on_top_about,
|
.link_on_top_about,
|
||||||
@@ -1024,15 +1022,14 @@ summary.title {
|
|||||||
#main_results div#results.only_template_images {
|
#main_results div#results.only_template_images {
|
||||||
margin: 1rem @results-tablet-offset 0 @results-tablet-offset;
|
margin: 1rem @results-tablet-offset 0 @results-tablet-offset;
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 100%;
|
grid-template:
|
||||||
grid-template-rows: min-content min-content min-content 1fr min-content;
|
"corrections" min-content
|
||||||
|
"answers" min-content
|
||||||
|
"sidebar" min-content
|
||||||
|
"urls" 1fr
|
||||||
|
"pagination" min-content
|
||||||
|
/ 100%;
|
||||||
gap: 0;
|
gap: 0;
|
||||||
grid-template-areas:
|
|
||||||
"corrections"
|
|
||||||
"answers"
|
|
||||||
"sidebar"
|
|
||||||
"urls"
|
|
||||||
"pagination";
|
|
||||||
|
|
||||||
#sidebar {
|
#sidebar {
|
||||||
display: none;
|
display: none;
|
||||||
@@ -1167,3 +1164,6 @@ summary.title {
|
|||||||
pre code {
|
pre code {
|
||||||
white-space: pre-wrap;
|
white-space: pre-wrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// import layouts of the Result types
|
||||||
|
@import "result_types/keyvalue.less";
|
||||||
@@ -203,7 +203,7 @@ div.selectable_url {
|
|||||||
left: 50%;
|
left: 50%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
transform: translate(-50%, -50%);
|
transform: translate(-50%, -50%);
|
||||||
z-index: 10000000;
|
z-index: 5000;
|
||||||
|
|
||||||
h3 {
|
h3 {
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
@@ -217,8 +217,7 @@ div.selectable_url {
|
|||||||
|
|
||||||
//
|
//
|
||||||
.scrollx {
|
.scrollx {
|
||||||
overflow-x: auto;
|
overflow: auto hidden;
|
||||||
overflow-y: hidden;
|
|
||||||
display: block;
|
display: block;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -250,7 +249,7 @@ ul.tabs {
|
|||||||
order: 2;
|
order: 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
& > input[type=radio] {
|
& > input[type="radio"] {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -340,7 +339,7 @@ select {
|
|||||||
padding: 0.2rem !important;
|
padding: 0.2rem !important;
|
||||||
color: var(--color-search-font);
|
color: var(--color-search-font);
|
||||||
font-size: 0.9rem;
|
font-size: 0.9rem;
|
||||||
z-index: 2;
|
z-index: 100;
|
||||||
|
|
||||||
&:hover,
|
&:hover,
|
||||||
&:focus {
|
&:focus {
|
||||||
@@ -348,14 +347,21 @@ select {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@supports ((background-position-x: 100%) and ((appearance: none) or (-webkit-appearance: none) or (-moz-appearance: none))) {
|
@supports (
|
||||||
|
(background-position-x: 100%) and
|
||||||
|
(
|
||||||
|
(appearance: none) or (-webkit-appearance: none) or
|
||||||
|
(-moz-appearance: none)
|
||||||
|
)
|
||||||
|
) {
|
||||||
select {
|
select {
|
||||||
appearance: none;
|
appearance: none;
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
border-width: 0 2rem 0 0;
|
border-width: 0 2rem 0 0;
|
||||||
border-color: transparent;
|
border-color: transparent;
|
||||||
background: data-uri('image/svg+xml;charset=UTF-8', @select-light-svg-path) no-repeat;
|
background: data-uri("image/svg+xml;charset=UTF-8", @select-light-svg-path)
|
||||||
|
no-repeat;
|
||||||
background-position-x: calc(100% + 2rem);
|
background-position-x: calc(100% + 2rem);
|
||||||
background-size: 2rem;
|
background-size: 2rem;
|
||||||
background-origin: content-box;
|
background-origin: content-box;
|
||||||
@@ -377,12 +383,18 @@ select {
|
|||||||
@media (prefers-color-scheme: dark) {
|
@media (prefers-color-scheme: dark) {
|
||||||
html.theme-auto select,
|
html.theme-auto select,
|
||||||
html.theme-dark select {
|
html.theme-dark select {
|
||||||
background-image: data-uri('image/svg+xml;charset=UTF-8', @select-dark-svg-path);
|
background-image: data-uri(
|
||||||
|
"image/svg+xml;charset=UTF-8",
|
||||||
|
@select-dark-svg-path
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
html.theme-dark select {
|
html.theme-dark select {
|
||||||
background-image: data-uri('image/svg+xml;charset=UTF-8', @select-dark-svg-path);
|
background-image: data-uri(
|
||||||
|
"image/svg+xml;charset=UTF-8",
|
||||||
|
@select-dark-svg-path
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -414,7 +426,7 @@ input.checkbox-onoff[type="checkbox"] {
|
|||||||
border: 1px solid var(--color-btn-background);
|
border: 1px solid var(--color-btn-background);
|
||||||
border-radius: 12px;
|
border-radius: 12px;
|
||||||
box-shadow: var(--color-btn-background) 0 0 3px;
|
box-shadow: var(--color-btn-background) 0 0 3px;
|
||||||
z-index: 10000;
|
z-index: 1200;
|
||||||
top: -0.55em;
|
top: -0.55em;
|
||||||
left: -0.6em;
|
left: -0.6em;
|
||||||
}
|
}
|
||||||
@@ -462,7 +474,7 @@ input.checkbox-onoff.reversed-checkbox[type="checkbox"] {
|
|||||||
|
|
||||||
/* -- checkbox -- */
|
/* -- checkbox -- */
|
||||||
@supports (transform: rotate(-45deg)) {
|
@supports (transform: rotate(-45deg)) {
|
||||||
input[type=checkbox]:not(.checkbox-onoff) {
|
input[type="checkbox"]:not(.checkbox-onoff) {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
-moz-appearance: none;
|
-moz-appearance: none;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
@@ -477,7 +489,7 @@ input.checkbox-onoff.reversed-checkbox[type="checkbox"] {
|
|||||||
.rounded-corners(0.3em);
|
.rounded-corners(0.3em);
|
||||||
|
|
||||||
&::after {
|
&::after {
|
||||||
content: '';
|
content: "";
|
||||||
width: 9px;
|
width: 9px;
|
||||||
height: 5px;
|
height: 5px;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -498,14 +510,18 @@ input.checkbox-onoff.reversed-checkbox[type="checkbox"] {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// disabled : can't be focused, show only the check mark
|
// disabled : can't be focused, show only the check mark
|
||||||
input[type=checkbox][disabled]:not(.checkbox-onoff) {
|
input[type="checkbox"][disabled]:not(.checkbox-onoff) {
|
||||||
border: inherit;
|
border: inherit;
|
||||||
background-color: transparent !important;
|
background-color: transparent !important;
|
||||||
cursor: inherit;
|
cursor: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if not checked and possible to checked then display a "light" check mark on hover
|
// if not checked and possible to checked then display a "light" check mark on hover
|
||||||
input.checkbox[type=checkbox]:not(:checked):not([disabled]):not(.checkbox-onoff):hover::after {
|
input.checkbox[type="checkbox"]:not(
|
||||||
|
:checked,
|
||||||
|
[disabled],
|
||||||
|
.checkbox-onoff
|
||||||
|
):hover::after {
|
||||||
opacity: 0.5;
|
opacity: 0.5;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -574,7 +590,7 @@ input.checkbox-onoff.reversed-checkbox[type="checkbox"] {
|
|||||||
background: var(--color-toolkit-engine-tooltip-background);
|
background: var(--color-toolkit-engine-tooltip-background);
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
z-index: 1000000;
|
z-index: 5000;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
.rounded-corners;
|
.rounded-corners;
|
||||||
}
|
}
|
||||||
@@ -593,8 +609,7 @@ td:hover .engine-tooltip,
|
|||||||
width: -moz-available;
|
width: -moz-available;
|
||||||
width: -webkit-fill-available;
|
width: -webkit-fill-available;
|
||||||
width: fill;
|
width: fill;
|
||||||
flex-direction: row;
|
flex-flow: row nowrap;
|
||||||
flex-wrap: nowrap;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
}
|
}
|
||||||
@@ -14,33 +14,16 @@
|
|||||||
border-right: 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-bottom: 1.1em solid var(--color-loading-indicator);
|
||||||
border-left: 1.1em solid var(--color-loading-indicator-gap);
|
border-left: 1.1em solid var(--color-loading-indicator-gap);
|
||||||
-webkit-transform: translateZ(0);
|
|
||||||
-ms-transform: translateZ(0);
|
|
||||||
transform: translateZ(0);
|
transform: translateZ(0);
|
||||||
-webkit-animation: load8 1.1s infinite linear;
|
|
||||||
animation: load8 1.1s infinite linear;
|
animation: load8 1.1s infinite linear;
|
||||||
}
|
}
|
||||||
|
|
||||||
@-webkit-keyframes load8 {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes load8 {
|
@keyframes load8 {
|
||||||
0% {
|
0% {
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
transform: rotate(0deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
100% {
|
100% {
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
transform: rotate(360deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
4
client/simple/src/svg/empty_favicon.svg
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 989 B |
@@ -0,0 +1,6 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 648 B |
6
client/simple/src/svg/ionicons/newspaper-outline.svg
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
<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>
|
||||||
|
After Width: | Height: | Size: 787 B |
|
Before Width: | Height: | Size: 196 B After Width: | Height: | Size: 196 B |
|
Before Width: | Height: | Size: 184 B After Width: | Height: | Size: 184 B |
2
client/simple/static/.gitattributes
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
leaflet.css -diff
|
||||||
|
leaflet.js -diff
|
||||||
84
client/simple/theme_icons.js
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
/**
|
||||||
|
* 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);
|
||||||
78
client/simple/tools/img.js
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
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 };
|
||||||
26
client/simple/tools/jinja_svg_catalog.html.edge
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
{{--
|
||||||
|
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
|
||||||
132
client/simple/tools/jinja_svg_catalog.js
Normal file
@@ -0,0 +1,132 @@
|
|||||||
|
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,
|
||||||
|
};
|
||||||
41
client/simple/tools/plg.js
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
/**
|
||||||
|
* 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 };
|
||||||
185
client/simple/vite.config.js
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
/**
|
||||||
|
* 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
|
||||||
|
|
||||||
|
});
|
||||||
100
container/Dockerfile
Normal file
@@ -0,0 +1,100 @@
|
|||||||
|
FROM docker.io/library/python:3.13-slim AS builder
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
build-essential \
|
||||||
|
brotli \
|
||||||
|
# uwsgi
|
||||||
|
libpcre3-dev \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /usr/local/searxng/
|
||||||
|
|
||||||
|
COPY ./requirements.txt ./requirements.txt
|
||||||
|
|
||||||
|
RUN --mount=type=cache,id=pip,target=/root/.cache/pip python -m venv ./venv \
|
||||||
|
&& . ./venv/bin/activate \
|
||||||
|
&& pip install -r requirements.txt \
|
||||||
|
&& pip install "uwsgi~=2.0"
|
||||||
|
|
||||||
|
COPY ./searx/ ./searx/
|
||||||
|
|
||||||
|
ARG TIMESTAMP_SETTINGS=0
|
||||||
|
ARG TIMESTAMP_UWSGI=0
|
||||||
|
|
||||||
|
RUN python -m compileall -q searx \
|
||||||
|
&& touch -c --date=@$TIMESTAMP_SETTINGS ./searx/settings.yml \
|
||||||
|
&& touch -c --date=@$TIMESTAMP_UWSGI ./container/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 {} +
|
||||||
|
|
||||||
|
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 \
|
||||||
|
# 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 ./container/ ./container/
|
||||||
|
|
||||||
|
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 \
|
||||||
|
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/container/docker-entrypoint.sh"]
|
||||||
@@ -14,8 +14,6 @@ Environment variables:
|
|||||||
BASE_URL settings.yml : server.base_url
|
BASE_URL settings.yml : server.base_url
|
||||||
MORTY_URL settings.yml : result_proxy.url
|
MORTY_URL settings.yml : result_proxy.url
|
||||||
MORTY_KEY settings.yml : result_proxy.key
|
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:
|
Volume:
|
||||||
/etc/searxng the docker entry point copies settings.yml and uwsgi.ini in
|
/etc/searxng the docker entry point copies settings.yml and uwsgi.ini in
|
||||||
this directory (see the -f command line option)"
|
this directory (see the -f command line option)"
|
||||||
@@ -23,9 +21,6 @@ Volume:
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
export DEFAULT_BIND_ADDRESS="0.0.0.0:8080"
|
|
||||||
export BIND_ADDRESS="${BIND_ADDRESS:-${DEFAULT_BIND_ADDRESS}}"
|
|
||||||
|
|
||||||
# Parse command line
|
# Parse command line
|
||||||
FORCE_CONF_UPDATE=0
|
FORCE_CONF_UPDATE=0
|
||||||
DRY_RUN=0
|
DRY_RUN=0
|
||||||
@@ -48,15 +43,7 @@ do
|
|||||||
esac
|
esac
|
||||||
done
|
done
|
||||||
|
|
||||||
get_searxng_version(){
|
echo "SearXNG version $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
|
# helpers to update the configuration files
|
||||||
patch_uwsgi_settings() {
|
patch_uwsgi_settings() {
|
||||||
@@ -81,7 +68,7 @@ patch_searxng_settings() {
|
|||||||
-e "s|base_url: false|base_url: ${BASE_URL}|g" \
|
-e "s|base_url: false|base_url: ${BASE_URL}|g" \
|
||||||
-e "s/instance_name: \"SearXNG\"/instance_name: \"${INSTANCE_NAME}\"/g" \
|
-e "s/instance_name: \"SearXNG\"/instance_name: \"${INSTANCE_NAME}\"/g" \
|
||||||
-e "s/autocomplete: \"\"/autocomplete: \"${AUTOCOMPLETE}\"/g" \
|
-e "s/autocomplete: \"\"/autocomplete: \"${AUTOCOMPLETE}\"/g" \
|
||||||
-e "s/ultrasecretkey/$(openssl rand -hex 32)/g" \
|
-e "s/ultrasecretkey/$(head -c 24 /dev/urandom | base64 | tr -dc 'a-zA-Z0-9')/g" \
|
||||||
"${CONF}"
|
"${CONF}"
|
||||||
|
|
||||||
# Morty configuration
|
# Morty configuration
|
||||||
@@ -153,14 +140,14 @@ if [ "$SEARX_CONF" -eq "1" ]; then
|
|||||||
cat << EOF > /etc/searx/deprecated_volume_read_me.txt
|
cat << EOF > /etc/searx/deprecated_volume_read_me.txt
|
||||||
This Docker image uses the volume /etc/searxng
|
This Docker image uses the volume /etc/searxng
|
||||||
Update your configuration:
|
Update your configuration:
|
||||||
* remove uwsgi.ini (or very carefully update your existing uwsgi.ini using https://github.com/searxng/searxng/blob/master/dockerfiles/uwsgi.ini )
|
* remove uwsgi.ini (or very carefully update your existing uwsgi.ini using https://github.com/searxng/searxng/blob/master/container/uwsgi.ini )
|
||||||
* mount /etc/searxng instead of /etc/searx
|
* mount /etc/searxng instead of /etc/searx
|
||||||
EOF
|
EOF
|
||||||
fi
|
fi
|
||||||
# end of searx compatibility
|
# end of searx compatibility
|
||||||
|
|
||||||
# make sure there are uwsgi settings
|
# make sure there are uwsgi settings
|
||||||
update_conf "${FORCE_CONF_UPDATE}" "${UWSGI_SETTINGS_PATH}" "/usr/local/searxng/dockerfiles/uwsgi.ini" "patch_uwsgi_settings"
|
update_conf "${FORCE_CONF_UPDATE}" "${UWSGI_SETTINGS_PATH}" "/usr/local/searxng/container/uwsgi.ini" "patch_uwsgi_settings"
|
||||||
|
|
||||||
# make sure there are searxng settings
|
# make sure there are searxng settings
|
||||||
update_conf "${FORCE_CONF_UPDATE}" "${SEARXNG_SETTINGS_PATH}" "/usr/local/searxng/searx/settings.yml" "patch_searxng_settings"
|
update_conf "${FORCE_CONF_UPDATE}" "${SEARXNG_SETTINGS_PATH}" "/usr/local/searxng/searx/settings.yml" "patch_searxng_settings"
|
||||||
@@ -173,6 +160,8 @@ fi
|
|||||||
|
|
||||||
unset MORTY_KEY
|
unset MORTY_KEY
|
||||||
|
|
||||||
# Start uwsgi
|
|
||||||
printf 'Listen on %s\n' "${BIND_ADDRESS}"
|
printf 'Listen on %s\n' "${BIND_ADDRESS}"
|
||||||
exec uwsgi --master --uid searxng --gid searxng --http-socket "${BIND_ADDRESS}" "${UWSGI_SETTINGS_PATH}"
|
|
||||||
|
# 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}"
|
||||||
106
container/legacy/Dockerfile
Normal file
@@ -0,0 +1,106 @@
|
|||||||
|
# For armv7 architecture
|
||||||
|
|
||||||
|
FROM docker.io/library/python:3.13-slim AS builder
|
||||||
|
|
||||||
|
RUN apt-get update \
|
||||||
|
&& apt-get install -y --no-install-recommends \
|
||||||
|
build-essential \
|
||||||
|
brotli \
|
||||||
|
# lxml
|
||||||
|
libxml2-dev \
|
||||||
|
libxslt1-dev \
|
||||||
|
zlib1g-dev \
|
||||||
|
# uwsgi
|
||||||
|
libpcre3-dev \
|
||||||
|
&& rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
WORKDIR /usr/local/searxng/
|
||||||
|
|
||||||
|
COPY ./requirements.txt ./requirements.txt
|
||||||
|
|
||||||
|
RUN --mount=type=cache,id=pip,target=/root/.cache/pip python -m venv ./venv \
|
||||||
|
&& . ./venv/bin/activate \
|
||||||
|
&& pip install -r requirements.txt \
|
||||||
|
&& pip install "uwsgi~=2.0"
|
||||||
|
|
||||||
|
COPY ./searx/ ./searx/
|
||||||
|
|
||||||
|
ARG TIMESTAMP_SETTINGS=0
|
||||||
|
ARG TIMESTAMP_UWSGI=0
|
||||||
|
|
||||||
|
RUN python -m compileall -q searx \
|
||||||
|
&& touch -c --date=@$TIMESTAMP_SETTINGS ./searx/settings.yml \
|
||||||
|
&& touch -c --date=@$TIMESTAMP_UWSGI ./container/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 {} +
|
||||||
|
|
||||||
|
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 ./container/ ./container/
|
||||||
|
|
||||||
|
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 \
|
||||||
|
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 \
|
||||||
|
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/container/docker-entrypoint.sh"]
|
||||||
@@ -1,4 +1,8 @@
|
|||||||
[uwsgi]
|
[uwsgi]
|
||||||
|
# Listening address
|
||||||
|
# default value: [::]:8080 (see Dockerfile)
|
||||||
|
http-socket = $(BIND_ADDRESS)
|
||||||
|
|
||||||
# Who will run the code
|
# Who will run the code
|
||||||
uid = searxng
|
uid = searxng
|
||||||
gid = searxng
|
gid = searxng
|
||||||
@@ -17,7 +21,6 @@ chmod-socket = 666
|
|||||||
# Plugin to use and interpreter config
|
# Plugin to use and interpreter config
|
||||||
single-interpreter = true
|
single-interpreter = true
|
||||||
master = true
|
master = true
|
||||||
plugin = python3
|
|
||||||
lazy-apps = true
|
lazy-apps = true
|
||||||
enable-threads = true
|
enable-threads = true
|
||||||
|
|
||||||
@@ -48,7 +51,5 @@ die-on-term
|
|||||||
|
|
||||||
# uwsgi serves the static files
|
# uwsgi serves the static files
|
||||||
static-map = /static=/usr/local/searxng/searx/static
|
static-map = /static=/usr/local/searxng/searx/static
|
||||||
# expires set to one day
|
|
||||||
static-expires = /* 86400
|
|
||||||
static-gzip-all = True
|
static-gzip-all = True
|
||||||
offload-threads = %k
|
offload-threads = %k
|
||||||
7
docker-compose.yml
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
services:
|
||||||
|
nekosearch:
|
||||||
|
build: .
|
||||||
|
pull_policy: build
|
||||||
|
restart: unless-stopped
|
||||||
|
ports:
|
||||||
|
- "${NEKOSEARCH_PORT}:8080"
|
||||||
@@ -145,13 +145,6 @@ shell inside container
|
|||||||
- `How to make bash scripts work in dash <http://mywiki.wooledge.org/Bashism>`_
|
- `How to make bash scripts work in dash <http://mywiki.wooledge.org/Bashism>`_
|
||||||
- `Checking for Bashisms <https://dev.to/bowmanjd/writing-bash-scripts-that-are-not-only-bash-checking-for-bashisms-and-testing-with-dash-1bli>`_
|
- `Checking for Bashisms <https://dev.to/bowmanjd/writing-bash-scripts-that-are-not-only-bash-checking-for-bashisms-and-testing-with-dash-1bli>`_
|
||||||
|
|
||||||
Like in many other distributions, Alpine's `/bin/sh
|
|
||||||
<https://wiki.ubuntu.com/DashAsBinSh>`__ is :man:`dash`. Dash is meant to be
|
|
||||||
`POSIX-compliant <https://pubs.opengroup.org/onlinepubs/9699919799>`__.
|
|
||||||
Compared to debian, in the Alpine image :man:`bash` is not installed. The
|
|
||||||
:origin:`dockerfiles/docker-entrypoint.sh` script is checked *against dash*
|
|
||||||
(``make tests.shell``).
|
|
||||||
|
|
||||||
To open a shell inside the container:
|
To open a shell inside the container:
|
||||||
|
|
||||||
.. code:: sh
|
.. code:: sh
|
||||||
@@ -188,10 +181,10 @@ Command line
|
|||||||
<https://docs.docker.com/engine/reference/run/#foreground>`__.
|
<https://docs.docker.com/engine/reference/run/#foreground>`__.
|
||||||
|
|
||||||
In the :origin:`Dockerfile` the ENTRYPOINT_ is defined as
|
In the :origin:`Dockerfile` the ENTRYPOINT_ is defined as
|
||||||
:origin:`dockerfiles/docker-entrypoint.sh`
|
:origin:`container/docker-entrypoint.sh`
|
||||||
|
|
||||||
.. code:: sh
|
.. code:: sh
|
||||||
|
|
||||||
docker run --rm -it searxng/searxng -h
|
docker run --rm -it searxng/searxng -h
|
||||||
|
|
||||||
.. program-output:: ../dockerfiles/docker-entrypoint.sh -h
|
.. program-output:: ../container/docker-entrypoint.sh -h
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ Modify the ``/etc/searxng/settings.yml`` to your needs:
|
|||||||
|
|
||||||
.. literalinclude:: ../../utils/templates/etc/searxng/settings.yml
|
.. literalinclude:: ../../utils/templates/etc/searxng/settings.yml
|
||||||
:language: yaml
|
:language: yaml
|
||||||
:end-before: # hostnames:
|
:end-before: # preferences:
|
||||||
|
|
||||||
To see the entire file jump to :origin:`utils/templates/etc/searxng/settings.yml`
|
To see the entire file jump to :origin:`utils/templates/etc/searxng/settings.yml`
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,13 @@
|
|||||||
.. _plugins generic:
|
.. _plugins admin:
|
||||||
|
|
||||||
===============
|
===============
|
||||||
Plugins builtin
|
List of plugins
|
||||||
===============
|
===============
|
||||||
|
|
||||||
.. sidebar:: Further reading ..
|
Further reading ..
|
||||||
|
|
||||||
- :ref:`dev plugin`
|
- :ref:`SearXNG settings <settings plugins>`
|
||||||
|
- :ref:`dev plugin`
|
||||||
Configuration defaults (at built time):
|
|
||||||
|
|
||||||
:DO: Default on
|
|
||||||
|
|
||||||
.. _configured plugins:
|
.. _configured plugins:
|
||||||
|
|
||||||
@@ -22,18 +19,13 @@ Configuration defaults (at built time):
|
|||||||
:widths: 3 1 9
|
:widths: 3 1 9
|
||||||
|
|
||||||
* - Name
|
* - Name
|
||||||
- DO
|
- Active
|
||||||
- Description
|
- Description
|
||||||
|
|
||||||
JS & CSS dependencies
|
{% for plg in plugins %}
|
||||||
|
|
||||||
{% for plgin in plugins %}
|
* - {{plg.info.name}}
|
||||||
|
- {{(plg.active and "yes") or "no"}}
|
||||||
* - {{plgin.name}}
|
- {{plg.info.description}}
|
||||||
- {{(plgin.default_on and "y") or ""}}
|
|
||||||
- {{plgin.description}}
|
|
||||||
|
|
||||||
{% for dep in (plgin.js_dependencies + plgin.css_dependencies) %}
|
|
||||||
| ``{{dep}}`` {% endfor %}
|
|
||||||
|
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
|||||||
@@ -93,15 +93,13 @@ TOML_ configuration is created in the file ``/etc/searxng/favicons.toml``.
|
|||||||
:py:obj:`cache.db_url <.FaviconCacheConfig.db_url>`:
|
:py:obj:`cache.db_url <.FaviconCacheConfig.db_url>`:
|
||||||
The path to the (SQLite_) database file. The default path is in the `/tmp`_
|
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
|
folder, which is deleted on every reboot and is therefore unsuitable for a
|
||||||
production environment. The FHS_ provides the folder for the
|
production environment. The FHS_ provides the folder `/var/cache`_ for the
|
||||||
application cache
|
cache of applications, so a suitable storage location of SearXNG's caches is
|
||||||
|
folder ``/var/cache/searxng``.
|
||||||
|
|
||||||
The FHS_ provides the folder `/var/cache`_ for the cache of applications, so a
|
In a standard installation (compare :ref:`create searxng user`), the folder
|
||||||
suitable storage location of SearXNG's caches is folder ``/var/cache/searxng``.
|
must be created and the user under which the SearXNG process is running must
|
||||||
In container systems, a volume should be mounted for this folder and in a
|
be given write permission to this folder.
|
||||||
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
|
.. code:: bash
|
||||||
|
|
||||||
@@ -109,6 +107,10 @@ TOML_ configuration is created in the file ``/etc/searxng/favicons.toml``.
|
|||||||
$ sudo chown root:searxng /var/cache/searxng/
|
$ sudo chown root:searxng /var/cache/searxng/
|
||||||
$ sudo chmod g+w /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>`:
|
: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
|
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
|
at each maintenance interval after which the oldest BLOBs are deleted; the
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ Settings
|
|||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
|
|
||||||
settings
|
settings
|
||||||
settings_engine
|
settings_engines
|
||||||
settings_brand
|
settings_brand
|
||||||
settings_general
|
settings_general
|
||||||
settings_search
|
settings_search
|
||||||
@@ -22,6 +22,6 @@ Settings
|
|||||||
settings_redis
|
settings_redis
|
||||||
settings_outgoing
|
settings_outgoing
|
||||||
settings_categories_as_tabs
|
settings_categories_as_tabs
|
||||||
|
settings_plugins
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ and can relied on the default configuration :origin:`searx/settings.yml` using:
|
|||||||
use_default_settings: true
|
use_default_settings: true
|
||||||
server:
|
server:
|
||||||
secret_key: "ultrasecretkey" # change this!
|
secret_key: "ultrasecretkey" # change this!
|
||||||
bind_address: "0.0.0.0"
|
bind_address: "[::]"
|
||||||
|
|
||||||
``engines:``
|
``engines:``
|
||||||
With ``use_default_settings: true``, each settings can be override in a
|
With ``use_default_settings: true``, each settings can be override in a
|
||||||
|
|||||||
@@ -1,14 +1,30 @@
|
|||||||
.. _settings engine:
|
.. _settings engines:
|
||||||
|
|
||||||
===========
|
============
|
||||||
``engine:``
|
``engines:``
|
||||||
===========
|
============
|
||||||
|
|
||||||
.. sidebar:: Further reading ..
|
.. sidebar:: Further reading ..
|
||||||
|
|
||||||
- :ref:`configured engines`
|
- :ref:`configured engines`
|
||||||
- :ref:`engines-dev`
|
- :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
|
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.
|
engine is shown. Most of the options have a default value or even are optional.
|
||||||
|
|
||||||
@@ -19,7 +35,7 @@ engine is shown. Most of the options have a default value or even are optional.
|
|||||||
|
|
||||||
.. code:: yaml
|
.. code:: yaml
|
||||||
|
|
||||||
- name: example engine
|
- name: example
|
||||||
engine: example
|
engine: example
|
||||||
shortcut: demo
|
shortcut: demo
|
||||||
base_url: 'https://{language}.example.com/'
|
base_url: 'https://{language}.example.com/'
|
||||||
@@ -132,6 +148,8 @@ engine is shown. Most of the options have a default value or even are optional.
|
|||||||
``display_error_messages`` : default ``true``
|
``display_error_messages`` : default ``true``
|
||||||
When an engine returns an error, the message is displayed on the user interface.
|
When an engine returns an error, the message is displayed on the user interface.
|
||||||
|
|
||||||
|
.. _engine network:
|
||||||
|
|
||||||
``network`` : optional
|
``network`` : optional
|
||||||
Use the network configuration from another engine.
|
Use the network configuration from another engine.
|
||||||
In addition, there are two default networks:
|
In addition, there are two default networks:
|
||||||
@@ -241,4 +259,3 @@ Example configuration in settings.yml for a German and English speaker:
|
|||||||
|
|
||||||
When searching, the default google engine will return German results and
|
When searching, the default google engine will return German results and
|
||||||
"google english" will return English results.
|
"google english" will return English results.
|
||||||
|
|
||||||
@@ -16,8 +16,14 @@
|
|||||||
open_metrics: ''
|
open_metrics: ''
|
||||||
|
|
||||||
``debug`` : ``$SEARXNG_DEBUG``
|
``debug`` : ``$SEARXNG_DEBUG``
|
||||||
Allow a more detailed log if you run SearXNG directly. Display *detailed* error
|
In debug mode, the server provides an interactive debugger, will reload when
|
||||||
messages in the browser too, so this must be deactivated in production.
|
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.
|
||||||
|
|
||||||
``donation_url`` :
|
``donation_url`` :
|
||||||
Set value to ``true`` to use your own donation page written in the
|
Set value to ``true`` to use your own donation page written in the
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ Communication with search engines.
|
|||||||
Global timeout of the requests made to others engines in seconds. A bigger
|
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
|
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
|
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 engine`.
|
timeout to load). Can be override by ``timeout`` in the :ref:`settings engines`.
|
||||||
|
|
||||||
``useragent_suffix`` :
|
``useragent_suffix`` :
|
||||||
Suffix to the user-agent SearXNG uses to send requests to others engines. If an
|
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`` :
|
||||||
Using tor proxy (``true``) or not (``false``) for all engines. The default is
|
Using tor proxy (``true``) or not (``false``) for all engines. The default is
|
||||||
``false`` and can be overwritten in the :ref:`settings engine`
|
``false`` and can be overwritten in the :ref:`settings engines`
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
77
docs/admin/settings/settings_plugins.rst
Normal file
@@ -0,0 +1,77 @@
|
|||||||
|
.. _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`_
|
||||||
|
- ..
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
favicon_resolver: ""
|
favicon_resolver: ""
|
||||||
default_lang: ""
|
default_lang: ""
|
||||||
ban_time_on_fail: 5
|
ban_time_on_fail: 5
|
||||||
|
max_page: 0
|
||||||
max_ban_time_on_fail: 120
|
max_ban_time_on_fail: 120
|
||||||
suspended_times:
|
suspended_times:
|
||||||
SearxEngineAccessDenied: 86400
|
SearxEngineAccessDenied: 86400
|
||||||
@@ -33,14 +34,21 @@
|
|||||||
``autocomplete``:
|
``autocomplete``:
|
||||||
Existing autocomplete backends, leave blank to turn it off.
|
Existing autocomplete backends, leave blank to turn it off.
|
||||||
|
|
||||||
|
- ``360search``
|
||||||
|
- ``baidu``
|
||||||
|
- ``brave``
|
||||||
- ``dbpedia``
|
- ``dbpedia``
|
||||||
- ``duckduckgo``
|
- ``duckduckgo``
|
||||||
- ``google``
|
- ``google``
|
||||||
- ``mwmbl``
|
- ``mwmbl``
|
||||||
- ``startpage``
|
- ``quark``
|
||||||
- ``swisscows``
|
|
||||||
- ``qwant``
|
- ``qwant``
|
||||||
|
- ``seznam``
|
||||||
|
- ``sogou``
|
||||||
|
- ``stract``
|
||||||
|
- ``swisscows``
|
||||||
- ``wikipedia``
|
- ``wikipedia``
|
||||||
|
- ``yandex``
|
||||||
|
|
||||||
``favicon_resolver``:
|
``favicon_resolver``:
|
||||||
To activate favicons in SearXNG's result list select a default
|
To activate favicons in SearXNG's result list select a default
|
||||||
@@ -49,11 +57,11 @@
|
|||||||
|
|
||||||
``default_lang``:
|
``default_lang``:
|
||||||
Default search language - leave blank to detect from browser information or
|
Default search language - leave blank to detect from browser information or
|
||||||
use codes from :origin:`searx/languages.py`.
|
use codes from :origin:`searx/sxng_locales.py`.
|
||||||
|
|
||||||
``languages``:
|
``languages``:
|
||||||
List of available languages - leave unset to use all codes from
|
List of available languages - leave unset to use all codes from
|
||||||
:origin:`searx/languages.py`. Otherwise list codes of available languages.
|
:origin:`searx/sxng_locales.py`. Otherwise list codes of available languages.
|
||||||
The ``all`` value is shown as the ``Default language`` in the user interface
|
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 most cases, it is meant to send the query without a language parameter ;
|
||||||
in some cases, it means the English language) Example:
|
in some cases, it means the English language) Example:
|
||||||
@@ -69,6 +77,11 @@
|
|||||||
- fr
|
- fr
|
||||||
- fr-BE
|
- 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_on_fail``:
|
||||||
Ban time in seconds after engine errors.
|
Ban time in seconds after engine errors.
|
||||||
|
|
||||||
|
|||||||
@@ -14,13 +14,14 @@
|
|||||||
limiter: false
|
limiter: false
|
||||||
public_instance: false
|
public_instance: false
|
||||||
image_proxy: false
|
image_proxy: false
|
||||||
|
method: "POST"
|
||||||
default_http_headers:
|
default_http_headers:
|
||||||
X-Content-Type-Options : nosniff
|
X-Content-Type-Options : nosniff
|
||||||
X-Download-Options : noopen
|
X-Download-Options : noopen
|
||||||
X-Robots-Tag : noindex, nofollow
|
X-Robots-Tag : noindex, nofollow
|
||||||
Referrer-Policy : no-referrer
|
Referrer-Policy : no-referrer
|
||||||
|
|
||||||
``base_url`` : ``$SEARXNG_URL``
|
``base_url`` : ``$SEARXNG_BASE_URL``
|
||||||
The base URL where SearXNG is deployed. Used to create correct inbound links.
|
The base URL where SearXNG is deployed. Used to create correct inbound links.
|
||||||
|
|
||||||
``port`` & ``bind_address``: ``$SEARXNG_PORT`` & ``$SEARXNG_BIND_ADDRESS``
|
``port`` & ``bind_address``: ``$SEARXNG_PORT`` & ``$SEARXNG_BIND_ADDRESS``
|
||||||
@@ -28,6 +29,8 @@
|
|||||||
directly using ``python searx/webapp.py``. Doesn't apply to a SearXNG
|
directly using ``python searx/webapp.py``. Doesn't apply to a SearXNG
|
||||||
services running behind a proxy and using socket communications.
|
services running behind a proxy and using socket communications.
|
||||||
|
|
||||||
|
.. _server.secret_key:
|
||||||
|
|
||||||
``secret_key`` : ``$SEARXNG_SECRET``
|
``secret_key`` : ``$SEARXNG_SECRET``
|
||||||
Used for cryptography purpose.
|
Used for cryptography purpose.
|
||||||
|
|
||||||
@@ -50,6 +53,11 @@
|
|||||||
``image_proxy`` : ``$SEARXNG_IMAGE_PROXY``
|
``image_proxy`` : ``$SEARXNG_IMAGE_PROXY``
|
||||||
Allow your instance of SearXNG of being able to proxy images. Uses memory space.
|
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
|
.. _HTTP headers: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers
|
||||||
|
|
||||||
``default_http_headers`` :
|
``default_http_headers`` :
|
||||||
|
|||||||
@@ -44,7 +44,7 @@
|
|||||||
``center_alignment`` : default ``false``
|
``center_alignment`` : default ``false``
|
||||||
When enabled, the results are centered instead of being in the left (or RTL)
|
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*
|
side of the screen. This setting only affects the *desktop layout*
|
||||||
(:origin:`min-width: @tablet <searx/static/themes/simple/src/less/definitions.less>`)
|
(:origin:`min-width: @tablet <client/simple/src/less/definitions.less>`)
|
||||||
|
|
||||||
.. cache_url:
|
.. cache_url:
|
||||||
|
|
||||||
|
|||||||
16
docs/conf.py
@@ -54,7 +54,7 @@ searx.engines.load_engines(searx.settings['engines'])
|
|||||||
jinja_contexts = {
|
jinja_contexts = {
|
||||||
'searx': {
|
'searx': {
|
||||||
'engines': searx.engines.engines,
|
'engines': searx.engines.engines,
|
||||||
'plugins': searx.plugins.plugins,
|
'plugins': searx.plugins.STORAGE,
|
||||||
'version': {
|
'version': {
|
||||||
'node': os.getenv('NODE_MINIMUM_VERSION')
|
'node': os.getenv('NODE_MINIMUM_VERSION')
|
||||||
},
|
},
|
||||||
@@ -127,11 +127,11 @@ extensions = [
|
|||||||
"sphinx_tabs.tabs", # https://github.com/djungelorm/sphinx-tabs
|
"sphinx_tabs.tabs", # https://github.com/djungelorm/sphinx-tabs
|
||||||
'myst_parser', # https://www.sphinx-doc.org/en/master/usage/markdown.html
|
'myst_parser', # https://www.sphinx-doc.org/en/master/usage/markdown.html
|
||||||
'notfound.extension', # https://github.com/readthedocs/sphinx-notfound-page
|
'notfound.extension', # https://github.com/readthedocs/sphinx-notfound-page
|
||||||
'sphinxcontrib.autodoc_pydantic', # https://github.com/mansenfranzen/autodoc_pydantic
|
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# autodoc_typehints = "description"
|
||||||
autodoc_default_options = {
|
autodoc_default_options = {
|
||||||
'member-order': 'groupwise',
|
'member-order': 'bysource',
|
||||||
}
|
}
|
||||||
|
|
||||||
myst_enable_extensions = [
|
myst_enable_extensions = [
|
||||||
@@ -143,10 +143,10 @@ suppress_warnings = ['myst.domains']
|
|||||||
intersphinx_mapping = {
|
intersphinx_mapping = {
|
||||||
"python": ("https://docs.python.org/3/", None),
|
"python": ("https://docs.python.org/3/", None),
|
||||||
"babel" : ("https://babel.readthedocs.io/en/latest/", None),
|
"babel" : ("https://babel.readthedocs.io/en/latest/", None),
|
||||||
"flask": ("https://flask.palletsprojects.com/", None),
|
"flask": ("https://flask.palletsprojects.com/en/stable/", None),
|
||||||
"flask_babel": ("https://python-babel.github.io/flask-babel/", None),
|
"flask_babel": ("https://python-babel.github.io/flask-babel/", None),
|
||||||
# "werkzeug": ("https://werkzeug.palletsprojects.com/", None),
|
"werkzeug": ("https://werkzeug.palletsprojects.com/en/stable/", None),
|
||||||
"jinja": ("https://jinja.palletsprojects.com/", None),
|
"jinja": ("https://jinja.palletsprojects.com/en/stable/", None),
|
||||||
"linuxdoc" : ("https://return42.github.io/linuxdoc/", None),
|
"linuxdoc" : ("https://return42.github.io/linuxdoc/", None),
|
||||||
"sphinx" : ("https://www.sphinx-doc.org/en/master/", None),
|
"sphinx" : ("https://www.sphinx-doc.org/en/master/", None),
|
||||||
"redis": ('https://redis.readthedocs.io/en/stable/', None),
|
"redis": ('https://redis.readthedocs.io/en/stable/', None),
|
||||||
@@ -161,7 +161,7 @@ issues_github_path = "searxng/searxng"
|
|||||||
notfound_urls_prefix = '/'
|
notfound_urls_prefix = '/'
|
||||||
|
|
||||||
sys.path.append(os.path.abspath('_themes'))
|
sys.path.append(os.path.abspath('_themes'))
|
||||||
sys.path.insert(0, os.path.abspath("../utils/"))
|
sys.path.insert(0, os.path.abspath("../"))
|
||||||
html_theme_path = ['_themes']
|
html_theme_path = ['_themes']
|
||||||
html_theme = "searxng"
|
html_theme = "searxng"
|
||||||
|
|
||||||
@@ -197,7 +197,7 @@ html_sidebars = {
|
|||||||
],
|
],
|
||||||
}
|
}
|
||||||
singlehtml_sidebars = {"index": ["project.html", "localtoc.html"]}
|
singlehtml_sidebars = {"index": ["project.html", "localtoc.html"]}
|
||||||
html_logo = "../src/brand/searxng-wordmark.svg"
|
html_logo = "../client/simple/src/brand/searxng-wordmark.svg"
|
||||||
html_title = "SearXNG Documentation ({})".format(VERSION_STRING)
|
html_title = "SearXNG Documentation ({})".format(VERSION_STRING)
|
||||||
html_show_sourcelink = True
|
html_show_sourcelink = True
|
||||||
|
|
||||||
|
|||||||
11
docs/dev/answerers/builtins.rst
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
.. _builtin answerers:
|
||||||
|
|
||||||
|
==================
|
||||||
|
Built-in Answerers
|
||||||
|
==================
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 1
|
||||||
|
|
||||||
|
random
|
||||||
|
statistics
|
||||||
7
docs/dev/answerers/development.rst
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
.. _dev answerers:
|
||||||
|
|
||||||
|
====================
|
||||||
|
Answerer Development
|
||||||
|
====================
|
||||||
|
|
||||||
|
.. automodule:: searx.answerers
|
||||||
9
docs/dev/answerers/index.rst
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
=========
|
||||||
|
Answerers
|
||||||
|
=========
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
development
|
||||||
|
builtins
|
||||||
8
docs/dev/answerers/random.rst
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
.. _answerer.random:
|
||||||
|
|
||||||
|
======
|
||||||
|
Random
|
||||||
|
======
|
||||||
|
|
||||||
|
.. autoclass:: searx.answerers.random.SXNGAnswerer
|
||||||
|
:members:
|
||||||
8
docs/dev/answerers/statistics.rst
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
.. _answerer.statistics:
|
||||||
|
|
||||||
|
==========
|
||||||
|
Statistics
|
||||||
|
==========
|
||||||
|
|
||||||
|
.. autoclass:: searx.answerers.statistics.SXNGAnswerer
|
||||||
|
:members:
|
||||||
@@ -27,23 +27,24 @@ Privacy-by-design
|
|||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
SearXNG was born out of the need for a **privacy-respecting** search tool which
|
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.
|
capabilities.
|
||||||
|
|
||||||
A few widely used features work differently or turned off by default or not
|
Some widely used search engine features may work differently,
|
||||||
implemented at all **as a consequence of privacy-by-design**.
|
may be turned off by default, or may not be implemented at all in SearXNG
|
||||||
|
**as a consequence of a privacy-by-design approach**.
|
||||||
|
|
||||||
If a feature reduces the privacy preserving aspects of searx, it should be
|
Following this approach, features reducing the privacy preserving aspects of SearXNG should be
|
||||||
switched off by default or should not implemented at all. There are plenty of
|
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 the
|
search engines already providing such features. If a feature reduces
|
||||||
protection of searx, users must be informed about the effect of choosing to
|
SearXNG's efficacy in protecting a user's privacy, the user must be informed about
|
||||||
enable it. Features that protect privacy but differ from the expectations of
|
the effect of choosing to enable it. Features that protect privacy but differ from the
|
||||||
the user should also be explained.
|
expectations of the user should also be carefully explained to them.
|
||||||
|
|
||||||
Also, if you think that something works weird with searx, it's might be because
|
Also, if you think that something works weird with SearXNG, it might be because
|
||||||
of the tool you use is designed in a way to interfere with the privacy respect.
|
the tool you are using is designed in a way that interferes with SearXNG's privacy aspects.
|
||||||
Submitting a bugreport to the vendor of the tool that misbehaves might be a good
|
Submitting a bug report 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``
|
feedback for them to reconsider the disrespect to their customers (e.g., ``GET`` vs ``POST``
|
||||||
requests in various browsers).
|
requests in various browsers).
|
||||||
|
|
||||||
Remember the other prime directive of SearXNG is to be hackable, so if the above
|
Remember the other prime directive of SearXNG is to be hackable, so if the above
|
||||||
@@ -134,7 +135,7 @@ Here is an example which makes a complete rebuild:
|
|||||||
|
|
||||||
.. _make docs.live:
|
.. _make docs.live:
|
||||||
|
|
||||||
live build
|
Live build
|
||||||
----------
|
----------
|
||||||
|
|
||||||
.. _sphinx-autobuild:
|
.. _sphinx-autobuild:
|
||||||
@@ -145,8 +146,8 @@ live build
|
|||||||
It is recommended to assert a complete rebuild before deploying (use
|
It is recommended to assert a complete rebuild before deploying (use
|
||||||
``docs.clean``).
|
``docs.clean``).
|
||||||
|
|
||||||
Live build is like WYSIWYG. If you want to edit the documentation, its
|
Live build is like WYSIWYG. It's the recommended way to go if you want to edit the documentation.
|
||||||
recommended to use. The Makefile target ``docs.live`` builds the docs, opens
|
The Makefile target ``docs.live`` builds the docs, opens
|
||||||
URL in your favorite browser and rebuilds every time a reST file has been
|
URL in your favorite browser and rebuilds every time a reST file has been
|
||||||
changed (:ref:`make docs.clean`).
|
changed (:ref:`make docs.clean`).
|
||||||
|
|
||||||
@@ -159,9 +160,9 @@ changed (:ref:`make docs.clean`).
|
|||||||
... Start watching changes
|
... Start watching changes
|
||||||
|
|
||||||
Live builds are implemented by sphinx-autobuild_. Use environment
|
Live builds are implemented by sphinx-autobuild_. Use environment
|
||||||
``$(SPHINXOPTS)`` to pass arguments to the sphinx-autobuild_ command. Except
|
``$(SPHINXOPTS)`` to pass arguments to the sphinx-autobuild_ command. You can
|
||||||
option ``--host`` (which is always set to ``0.0.0.0``) you can pass any
|
pass any argument except for the ``--host`` option (which is always set to ``0.0.0.0``).
|
||||||
argument. E.g to find and use a free port, use:
|
E.g., to find and use a free port, use:
|
||||||
|
|
||||||
.. code:: sh
|
.. code:: sh
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ Engine Overview
|
|||||||
.. sidebar:: Further reading ..
|
.. sidebar:: Further reading ..
|
||||||
|
|
||||||
- :ref:`configured engines`
|
- :ref:`configured engines`
|
||||||
- :ref:`settings engine`
|
- :ref:`settings engines`
|
||||||
|
|
||||||
SearXNG is a metasearch-engine_, so it uses different search engines to provide
|
SearXNG is a metasearch-engine_, so it uses different search engines to provide
|
||||||
better results.
|
better results.
|
||||||
@@ -63,7 +63,7 @@ Engine File
|
|||||||
Engine ``settings.yml``
|
Engine ``settings.yml``
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
For a more detailed description, see :ref:`settings engine` in the :ref:`settings.yml`.
|
For a more detailed description, see :ref:`settings engines` in the :ref:`settings.yml`.
|
||||||
|
|
||||||
.. table:: Common options in the engine setup (``settings.yml``)
|
.. table:: Common options in the engine setup (``settings.yml``)
|
||||||
:width: 100%
|
:width: 100%
|
||||||
@@ -237,335 +237,18 @@ following parameters can be used to specify a search request:
|
|||||||
=================== =========== ==========================================================================
|
=================== =========== ==========================================================================
|
||||||
|
|
||||||
|
|
||||||
.. _engine results:
|
Making a Response
|
||||||
.. _engine media types:
|
=================
|
||||||
|
|
||||||
Result Types (``template``)
|
In the ``response`` function of the engine, the HTTP response (``resp``) is
|
||||||
===========================
|
parsed and a list of results is returned.
|
||||||
|
|
||||||
Each result item of an engine can be of different media-types. Currently the
|
A engine can append result-items of different media-types and different
|
||||||
following media-types are supported. To set another media-type as
|
result-types to the result list. The list of the result items is render to HTML
|
||||||
:ref:`template default`, the parameter ``template`` must be set to the desired
|
by templates. For more details read section:
|
||||||
type.
|
|
||||||
|
|
||||||
.. _template default:
|
- :ref:`simple theme templates`
|
||||||
|
- :ref:`result types`
|
||||||
|
|
||||||
``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``
|
|
||||||
----------
|
|
||||||
|
|
||||||
.. list-table:: Parameter of the **images** media type
|
|
||||||
:header-rows: 2
|
|
||||||
:width: 100%
|
|
||||||
|
|
||||||
* - result-parameter
|
|
||||||
- Python type
|
|
||||||
- information
|
|
||||||
|
|
||||||
* - template
|
|
||||||
- :py:class:`str`
|
|
||||||
- is set to ``images.html``
|
|
||||||
|
|
||||||
* - url
|
|
||||||
- :py:class:`str`
|
|
||||||
- url to the result site
|
|
||||||
|
|
||||||
* - title
|
|
||||||
- :py:class:`str`
|
|
||||||
- title of the result
|
|
||||||
|
|
||||||
* - content
|
|
||||||
- :py:class:`str`
|
|
||||||
- description of the image
|
|
||||||
|
|
||||||
* - publishedDate
|
|
||||||
- :py:class:`datetime <datetime.datetime>`
|
|
||||||
- time of publish
|
|
||||||
|
|
||||||
* - img_src
|
|
||||||
- :py:class:`str`
|
|
||||||
- url to the result image
|
|
||||||
|
|
||||||
* - thumbnail_src
|
|
||||||
- :py:class:`str`
|
|
||||||
- url to a small-preview image
|
|
||||||
|
|
||||||
* - resolution
|
|
||||||
- :py:class:`str`
|
|
||||||
- the resolution of the image (e.g. ``1920 x 1080`` pixel)
|
|
||||||
|
|
||||||
* - img_format
|
|
||||||
- :py:class:`str`
|
|
||||||
- the format of the image (e.g. ``png``)
|
|
||||||
|
|
||||||
* - filesize
|
|
||||||
- :py:class:`str`
|
|
||||||
- size of bytes in :py:obj:`human readable <searx.humanize_bytes>` notation
|
|
||||||
(e.g. ``MB`` for 1024 \* 1024 Bytes filesize).
|
|
||||||
|
|
||||||
|
|
||||||
.. _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
|
|
||||||
length :py:class:`datetime.timedelta`, duration of result
|
|
||||||
views string, view count in humanized number format
|
|
||||||
========================= =====================================================
|
|
||||||
|
|
||||||
|
|
||||||
.. _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
|
|
||||||
|
|
||||||
|
|
||||||
.. _template packages:
|
|
||||||
|
|
||||||
``packages``
|
|
||||||
------------
|
|
||||||
|
|
||||||
.. list-table:: Parameter of the **packages** media type
|
|
||||||
:header-rows: 2
|
|
||||||
:width: 100%
|
|
||||||
|
|
||||||
* - result-parameter
|
|
||||||
- Python type
|
|
||||||
- information
|
|
||||||
|
|
||||||
* - template
|
|
||||||
- :py:class:`str`
|
|
||||||
- is set to ``packages.html``
|
|
||||||
|
|
||||||
* - title
|
|
||||||
- :py:class:`str`
|
|
||||||
- title of the result
|
|
||||||
|
|
||||||
* - content
|
|
||||||
- :py:class:`str`
|
|
||||||
- abstract
|
|
||||||
|
|
||||||
* - package_name
|
|
||||||
- :py:class:`str`
|
|
||||||
- the name of the package
|
|
||||||
|
|
||||||
* - version
|
|
||||||
- :py:class:`str`
|
|
||||||
- the current version of the package
|
|
||||||
|
|
||||||
* - maintainer
|
|
||||||
- :py:class:`str`
|
|
||||||
- the maintainer or author of the project
|
|
||||||
|
|
||||||
* - publishedDate
|
|
||||||
- :py:class:`datetime <datetime.datetime>`
|
|
||||||
- date of latest update or release
|
|
||||||
|
|
||||||
* - tags
|
|
||||||
- :py:class:`List <list>`\ [\ :py:class:`str`\ ]
|
|
||||||
- free tag list
|
|
||||||
|
|
||||||
* - popularity
|
|
||||||
- :py:class:`str`
|
|
||||||
- the popularity of the package, e.g. rating or download count
|
|
||||||
|
|
||||||
* - license_name
|
|
||||||
- :py:class:`str`
|
|
||||||
- the name of the license
|
|
||||||
|
|
||||||
* - license_url
|
|
||||||
- :py:class:`str`
|
|
||||||
- the web location of a license copy
|
|
||||||
|
|
||||||
* - homepage
|
|
||||||
- :py:class:`str`
|
|
||||||
- the url of the project's homepage
|
|
||||||
|
|
||||||
* - source_code_url
|
|
||||||
- :py:class:`str`
|
|
||||||
- the location of the project's source code
|
|
||||||
|
|
||||||
* - links
|
|
||||||
- :py:class:`dict`
|
|
||||||
- additional links in the form of ``{'link_name': 'http://example.com'}``
|
|
||||||
|
|||||||
@@ -4,19 +4,13 @@
|
|||||||
Engine Library
|
Engine Library
|
||||||
==============
|
==============
|
||||||
|
|
||||||
.. contents::
|
|
||||||
:depth: 2
|
|
||||||
:local:
|
|
||||||
:backlinks: entry
|
|
||||||
|
|
||||||
.. automodule:: searx.enginelib
|
.. automodule:: searx.enginelib
|
||||||
:members:
|
:members:
|
||||||
|
|
||||||
.. _searx.enginelib.traits:
|
.. _searx.enginelib.traits:
|
||||||
|
|
||||||
|
|
||||||
Engine traits
|
Engine traits
|
||||||
=============
|
=============
|
||||||
|
|
||||||
.. automodule:: searx.enginelib.traits
|
.. automodule:: searx.enginelib.traits
|
||||||
:members:
|
:members:
|
||||||
|
|||||||
@@ -19,6 +19,14 @@ Engine Implementations
|
|||||||
engine_overview
|
engine_overview
|
||||||
|
|
||||||
|
|
||||||
|
ResultList and engines
|
||||||
|
======================
|
||||||
|
|
||||||
|
.. autoclass:: searx.result_types.ResultList
|
||||||
|
|
||||||
|
.. autoclass:: searx.result_types.EngineResults
|
||||||
|
|
||||||
|
|
||||||
Engine Types
|
Engine Types
|
||||||
============
|
============
|
||||||
|
|
||||||
@@ -45,6 +53,7 @@ Online Engines
|
|||||||
demo/demo_online
|
demo/demo_online
|
||||||
xpath
|
xpath
|
||||||
mediawiki
|
mediawiki
|
||||||
|
json_engine
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 1
|
:maxdepth: 1
|
||||||
|
|||||||
13
docs/dev/engines/json_engine.rst
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
.. _json_engine engine:
|
||||||
|
|
||||||
|
============
|
||||||
|
JSON Engine
|
||||||
|
============
|
||||||
|
|
||||||
|
.. contents::
|
||||||
|
:depth: 2
|
||||||
|
:local:
|
||||||
|
:backlinks: entry
|
||||||
|
|
||||||
|
.. automodule:: searx.engines.json_engine
|
||||||
|
:members:
|
||||||