Compare commits

..

1 Commits

Author SHA1 Message Date
dependabot[bot] 74d857015a
[upd] pypi: Bump redis from 5.0.8 to 5.2.0
Bumps [redis](https://github.com/redis/redis-py) from 5.0.8 to 5.2.0.
- [Release notes](https://github.com/redis/redis-py/releases)
- [Changelog](https://github.com/redis/redis-py/blob/master/CHANGES)
- [Commits](https://github.com/redis/redis-py/compare/v5.0.8...v5.2.0)

---
updated-dependencies:
- dependency-name: redis
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-10-29 12:51:47 +00:00
35 changed files with 433 additions and 456 deletions

View File

@ -1,5 +1,5 @@
name: "Checker"
on: # yamllint disable-line rule:truthy
on:
schedule:
- cron: "0 4 * * 5"
workflow_dispatch:

View File

@ -1,5 +1,5 @@
name: "Update searx.data"
on: # yamllint disable-line rule:truthy
on:
schedule:
- cron: "59 23 28 * *"
workflow_dispatch:

View File

@ -1,6 +1,6 @@
name: Integration
on: # yamllint disable-line rule:truthy
on:
push:
branches: ["master"]
pull_request:
@ -16,62 +16,70 @@ jobs:
strategy:
matrix:
os: [ubuntu-20.04]
python-version: ["3.9", "3.10", "3.11", "3.12"]
python-version: ["3.9", "3.10", "3.11", "3.12",]
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Ubuntu packages
run: |
sudo ./utils/searxng.sh install packages
sudo apt install firefox
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
architecture: 'x64'
- name: Cache Python dependencies
id: cache-python
uses: actions/cache@v3
with:
path: |
./local
./.nvm
./node_modules
key: python-${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('requirements*.txt', 'setup.py') }}
- name: Install Python dependencies
if: steps.cache-python.outputs.cache-hit != 'true'
run: |
make V=1 install
make V=1 gecko.driver
- name: Run tests
run: make V=1 ci.test
- name: Checkout
uses: actions/checkout@v4
- name: Install Ubuntu packages
run: |
sudo ./utils/searxng.sh install packages
sudo apt install firefox
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ matrix.python-version }}
architecture: 'x64'
- name: Cache Python dependencies
id: cache-python
uses: actions/cache@v3
with:
path: |
./local
./.nvm
./node_modules
key: python-${{ matrix.os }}-${{ matrix.python-version }}-${{ hashFiles('requirements*.txt', 'setup.py') }}
- name: Install Python dependencies
if: steps.cache-python.outputs.cache-hit != 'true'
run: |
make V=1 install
make V=1 gecko.driver
- name: Run tests
run: make V=1 ci.test
- name: Test coverage
run: make V=1 test.coverage
- name: Store coverage result
uses: actions/upload-artifact@v3
with:
name: coverage-${{ matrix.python-version }}
path: coverage/
retention-days: 60
themes:
name: Themes
runs-on: ubuntu-20.04
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install Ubuntu packages
run: sudo ./utils/searxng.sh install buildhost
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
architecture: 'x64'
- name: Cache Python dependencies
id: cache-python
uses: actions/cache@v3
with:
path: |
./local
./.nvm
./node_modules
key: python-ubuntu-20.04-3.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
- name: Checkout
uses: actions/checkout@v4
- name: Install Ubuntu packages
run: sudo ./utils/searxng.sh install buildhost
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
architecture: 'x64'
- name: Cache Python dependencies
id: cache-python
uses: actions/cache@v3
with:
path: |
./local
./.nvm
./node_modules
key: python-ubuntu-20.04-3.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
@ -79,40 +87,40 @@ jobs:
permissions:
contents: write # for JamesIves/github-pages-deploy-action to push changes in repo
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: '0'
persist-credentials: false
- name: Install Ubuntu packages
run: sudo ./utils/searxng.sh install buildhost
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
architecture: 'x64'
- name: Cache Python dependencies
id: cache-python
uses: actions/cache@v3
with:
path: |
./local
./.nvm
./node_modules
key: python-ubuntu-20.04-3.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 }}'
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: '0'
persist-credentials: false
- name: Install Ubuntu packages
run: sudo ./utils/searxng.sh install buildhost
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
architecture: 'x64'
- name: Cache Python dependencies
id: cache-python
uses: actions/cache@v3
with:
path: |
./local
./.nvm
./node_modules
key: python-ubuntu-20.04-3.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: Update translations branch
@ -125,37 +133,37 @@ jobs:
permissions:
contents: write # for make V=1 weblate.push.translations
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: '0'
token: ${{ secrets.WEBLATE_GITHUB_TOKEN }}
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.12'
architecture: 'x64'
- name: Cache Python dependencies
id: cache-python
uses: actions/cache@v3
with:
path: |
./local
./.nvm
./node_modules
key: python-ubuntu-20.04-3.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
- 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@v3
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: Docker

View File

@ -1,5 +1,5 @@
name: "Security checks"
on: # yamllint disable-line rule:truthy
on:
schedule:
- cron: "42 05 * * *"
workflow_dispatch:

View File

@ -1,5 +1,5 @@
name: "Update translations"
on: # yamllint disable-line rule:truthy
on:
schedule:
- cron: "05 07 * * 5"
workflow_dispatch:
@ -10,50 +10,50 @@ jobs:
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@v3
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
- 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@v3
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

2
manage
View File

@ -57,7 +57,7 @@ while IFS= read -r line; do
if [ "$line" != "tests/unit/settings/syntaxerror_settings.yml" ]; then
YAMLLINT_FILES+=("$line")
fi
done <<< "$(git ls-files './tests/*.yml' './searx/*.yml' './utils/templates/etc/searxng/*.yml' '.github/*.yml' '.github/*/*.yml')"
done <<< "$(git ls-files './tests/*.yml' './searx/*.yml' './utils/templates/etc/searxng/*.yml')"
RST_FILES=(
'README.rst'

View File

@ -4,7 +4,7 @@ cov-core==1.15.0
black==24.3.0
pylint==3.3.1
splinter==0.21.0
selenium==4.26.1
selenium==4.25.0
Pallets-Sphinx-Themes==2.3.0
Sphinx==7.4.7
sphinx-issues==5.0.0

View File

@ -1,7 +1,7 @@
certifi==2024.8.30
babel==2.16.0
flask-babel==4.0.0
flask==3.1.0
flask==3.0.3
jinja2==3.1.4
lxml==5.3.0
pygments==2.18.0
@ -11,11 +11,11 @@ httpx[http2]==0.24.1
Brotli==1.1.0
uvloop==0.21.0
httpx-socks[asyncio]==0.7.7
setproctitle==1.3.4
setproctitle==1.3.3
redis==5.2.0
markdown-it-py==3.0.0
fasttext-predict==0.9.2.2
tomli==2.0.2; python_version < '3.11'
msgspec==0.18.6
eval_type_backport; python_version < '3.9'
typer-slim==0.13.0
typer-slim==0.12.5

View File

@ -34,10 +34,10 @@ Implementations
"""
from typing import List, Dict, Any, Optional
from urllib.parse import urlencode
from urllib.parse import quote
from lxml import html
from searx.utils import extract_text, eval_xpath, eval_xpath_getindex, eval_xpath_list
from searx.utils import extract_text, eval_xpath, eval_xpath_list
from searx.enginelib.traits import EngineTraits
from searx.data import ENGINE_TRAITS
@ -53,7 +53,7 @@ about: Dict[str, Any] = {
# engine dependent config
categories: List[str] = ["files"]
paging: bool = True
paging: bool = False
# search-url
base_url: str = "https://annas-archive.org"
@ -99,18 +99,9 @@ def init(engine_settings=None): # pylint: disable=unused-argument
def request(query, params: Dict[str, Any]) -> Dict[str, Any]:
q = quote(query)
lang = traits.get_language(params["language"], traits.all_locale) # type: ignore
args = {
'lang': lang,
'content': aa_content,
'ext': aa_ext,
'sort': aa_sort,
'q': query,
'page': params['pageno'],
}
# filter out None and empty values
filtered_args = dict((k, v) for k, v in args.items() if v)
params["url"] = f"{base_url}/search?{urlencode(filtered_args)}"
params["url"] = base_url + f"/search?lang={lang or ''}&content={aa_content}&ext={aa_ext}&sort={aa_sort}&q={q}"
return params
@ -137,12 +128,12 @@ def response(resp) -> List[Dict[str, Optional[str]]]:
def _get_result(item):
return {
'template': 'paper.html',
'url': base_url + extract_text(eval_xpath_getindex(item, './@href', 0)),
'url': base_url + item.xpath('./@href')[0],
'title': extract_text(eval_xpath(item, './/h3/text()[1]')),
'publisher': extract_text(eval_xpath(item, './/div[contains(@class, "text-sm")]')),
'authors': [extract_text(eval_xpath(item, './/div[contains(@class, "italic")]'))],
'content': extract_text(eval_xpath(item, './/div[contains(@class, "text-xs")]')),
'thumbnail': extract_text(eval_xpath_getindex(item, './/img/@src', 0, default=None), allow_none=True),
'thumbnail': item.xpath('.//img/@src')[0],
}

View File

@ -18,6 +18,7 @@ from searx import (
)
from searx.utils import (
eval_xpath,
eval_xpath_getindex,
extract_text,
)
from searx.network import get # see https://github.com/searxng/searxng/issues/762
@ -53,33 +54,31 @@ paging = True
time_range_support = True
safesearch = True # user can't select but the results are filtered
url = "https://html.duckduckgo.com/html"
url = 'https://lite.duckduckgo.com/lite/'
# url_ping = 'https://duckduckgo.com/t/sl_l'
time_range_dict = {'day': 'd', 'week': 'w', 'month': 'm', 'year': 'y'}
form_data = {'v': 'l', 'api': 'd.js', 'o': 'json'}
__CACHE = []
def _cache_key(data: dict):
return 'SearXNG_ddg_web_vqd' + redislib.secret_hash(f"{data['q']}//{data['kl']}")
def cache_vqd(data: dict, value):
def cache_vqd(query, value):
"""Caches a ``vqd`` value from a query."""
c = redisdb.client()
if c:
logger.debug("cache vqd value: %s", value)
c.set(_cache_key(data), value, ex=600)
else:
logger.debug("MEM cache vqd value: %s", value)
if len(__CACHE) > 100: # cache vqd from last 100 queries
__CACHE.pop(0)
__CACHE.append((_cache_key(data), value))
key = 'SearXNG_ddg_web_vqd' + redislib.secret_hash(query)
c.set(key, value, ex=600)
def get_vqd(data):
"""Returns the ``vqd`` that fits to the *query* (``data`` from HTTP POST).
def get_vqd(query):
"""Returns the ``vqd`` that fits to the *query*. If there is no ``vqd`` cached
(:py:obj:`cache_vqd`) the query is sent to DDG to get a vqd value from the
response.
.. hint::
If an empty string is returned there are no results for the ``query`` and
therefore no ``vqd`` value.
DDG's bot detection is sensitive to the ``vqd`` value. For some search terms
(such as extremely long search terms that are often sent by bots), no ``vqd``
@ -107,23 +106,28 @@ def get_vqd(data):
- DuckDuckGo News: ``https://duckduckgo.com/news.js??q=...&vqd=...``
"""
key = _cache_key(data)
value = None
c = redisdb.client()
if c:
key = 'SearXNG_ddg_web_vqd' + redislib.secret_hash(query)
value = c.get(key)
if value or value == b'':
value = value.decode('utf-8')
logger.debug("re-use CACHED vqd value: %s", value)
logger.debug("re-use cached vqd value: %s", value)
return value
else:
for k, value in __CACHE:
if k == key:
logger.debug("MEM re-use CACHED vqd value: %s", value)
return value
return None
query_url = 'https://duckduckgo.com/?' + urlencode({'q': query})
res = get(query_url)
doc = lxml.html.fromstring(res.text)
for script in doc.xpath("//script[@type='text/javascript']"):
script = script.text
if 'vqd="' in script:
value = extr(script, 'vqd="', '"')
break
logger.debug("new vqd value: '%s'", value)
if value is not None:
cache_vqd(query, value)
return value
def get_ddg_lang(eng_traits: EngineTraits, sxng_locale, default='en_US'):
@ -151,10 +155,9 @@ def get_ddg_lang(eng_traits: EngineTraits, sxng_locale, default='en_US'):
.. hint::
`DDG-lite <https://lite.duckduckgo.com/lite>`__ and the *no Javascript*
page https://html.duckduckgo.com/html do not offer a language selection
to the user, only a region can be selected by the user (``eng_region``
from the example above). DDG-lite and *no Javascript* store the selected
`DDG-lite <https://lite.duckduckgo.com/lite>`__ does not offer a language
selection to the user, only a region can be selected by the user
(``eng_region`` from the example above). DDG-lite stores the selected
region in a cookie::
params['cookies']['kl'] = eng_region # 'ar-es'
@ -238,27 +241,10 @@ def request(query, params):
query = quote_ddg_bangs(query)
if len(query) >= 500:
# DDG does not accept queries with more than 499 chars
params["url"] = None
return
# request needs a vqd argument
vqd = get_vqd(query)
# Advanced search syntax ends in CAPTCHA
# https://duckduckgo.com/duckduckgo-help-pages/results/syntax/
query = " ".join(
[
x.removeprefix("site:").removeprefix("intitle:").removeprefix("inurl:").removeprefix("filetype:")
for x in query.split()
]
)
eng_region = traits.get_region(params['searxng_locale'], traits.all_locale)
if eng_region == "wt-wt":
# https://html.duckduckgo.com/html sets an empty value for "all".
eng_region = ""
params['data']['kl'] = eng_region
params['cookies']['kl'] = eng_region
# eng_lang = get_ddg_lang(traits, params['searxng_locale'])
params['url'] = url
@ -266,82 +252,54 @@ def request(query, params):
params['data']['q'] = query
# The API is not documented, so we do some reverse engineering and emulate
# what https://html.duckduckgo.com/html does when you press "next Page" link
# again and again ..
# what https://lite.duckduckgo.com/lite/ does when you press "next Page"
# link again and again ..
params['headers']['Content-Type'] = 'application/x-www-form-urlencoded'
params['data']['vqd'] = vqd
params['headers']['Sec-Fetch-Dest'] = "document"
params['headers']['Sec-Fetch-Mode'] = "navigate" # at least this one is used by ddg's bot detection
params['headers']['Sec-Fetch-Site'] = "same-origin"
params['headers']['Sec-Fetch-User'] = "?1"
# Form of the initial search page does have empty values in the form
if params['pageno'] == 1:
params['data']['b'] = ""
params['data']['df'] = ''
if params['time_range'] in time_range_dict:
params['data']['df'] = time_range_dict[params['time_range']]
params['cookies']['df'] = time_range_dict[params['time_range']]
# initial page does not have an offset
if params['pageno'] == 2:
# second page does have an offset of 20
offset = (params['pageno'] - 1) * 20
params['data']['s'] = offset
params['data']['dc'] = offset + 1
elif params['pageno'] > 2:
# third and following pages do have an offset of 20 + n*50
offset = 20 + (params['pageno'] - 2) * 50
params['data']['s'] = offset
params['data']['dc'] = offset + 1
# initial page does not have additional data in the input form
if params['pageno'] > 1:
# initial page does not have these additional data in the input form
params['data']['o'] = form_data.get('o', 'json')
params['data']['api'] = form_data.get('api', 'd.js')
params['data']['nextParams'] = form_data.get('nextParams', '')
params['data']['v'] = form_data.get('v', 'l')
params['headers']['Referer'] = url
params['headers']['Referer'] = 'https://lite.duckduckgo.com/'
# from here on no more params['data'] shuld be set, since this dict is
# needed to get a vqd value from the cache ..
params['data']['kl'] = eng_region
params['cookies']['kl'] = eng_region
vqd = get_vqd(params['data'])
# Certain conditions must be met in order to call up one of the
# following pages ...
if vqd:
params['data']['vqd'] = vqd # follow up pages / requests needs a vqd argument
else:
# Don't try to call follow up pages without a vqd value. DDG
# recognizes this as a request from a bot. This lowers the
# reputation of the SearXNG IP and DDG starts to activate CAPTCHAs.
params["url"] = None
return
if params['searxng_locale'].startswith("zh"):
# Some locales (at least China) do not have a "next page" button and ddg
# will return a HTTP/2 403 Forbidden for a request of such a page.
params["url"] = None
return
params['data']['df'] = ''
if params['time_range'] in time_range_dict:
params['data']['df'] = time_range_dict[params['time_range']]
params['cookies']['df'] = time_range_dict[params['time_range']]
logger.debug("param data: %s", params['data'])
logger.debug("param cookies: %s", params['cookies'])
return params
def is_ddg_captcha(dom):
"""In case of CAPTCHA ddg response its own *not a Robot* dialog and is not
redirected to a CAPTCHA page."""
return bool(eval_xpath(dom, "//form[@id='challenge-form']"))
def detect_ddg_captcha(dom):
"""In case of CAPTCHA ddg open its own *not a Robot* dialog and is
not redirected to CAPTCHA page.
"""
if eval_xpath(dom, "//form[@id='challenge-form']"):
# set suspend time to zero is OK --> ddg does not block the IP
raise SearxEngineCaptchaException(suspended_time=0)
def response(resp):
@ -351,41 +309,40 @@ def response(resp):
results = []
doc = lxml.html.fromstring(resp.text)
detect_ddg_captcha(doc)
if is_ddg_captcha(doc):
# set suspend time to zero is OK --> ddg does not block the IP
raise SearxEngineCaptchaException(suspended_time=0, message=f"CAPTCHA ({resp.search_params['data'].get('kl')})")
result_table = eval_xpath(doc, '//html/body/form/div[@class="filters"]/table')
form = eval_xpath(doc, '//input[@name="vqd"]/..')
if len(form):
# some locales (at least China) does not have a "next page" button
form = form[0]
form_vqd = eval_xpath(form, '//input[@name="vqd"]/@value')[0]
if len(result_table) == 2:
# some locales (at least China) does not have a "next page" button and
# the layout of the HTML tables is different.
result_table = result_table[1]
elif not len(result_table) >= 3:
# no more results
return []
else:
result_table = result_table[2]
# update form data from response
form = eval_xpath(doc, '//html/body/form/div[@class="filters"]/table//input/..')
if len(form):
cache_vqd(resp.search_params["data"], form_vqd)
form = form[0]
form_data['v'] = eval_xpath(form, '//input[@name="v"]/@value')[0]
form_data['api'] = eval_xpath(form, '//input[@name="api"]/@value')[0]
form_data['o'] = eval_xpath(form, '//input[@name="o"]/@value')[0]
logger.debug('form_data: %s', form_data)
# just select "web-result" and ignore results of class "result--ad result--ad--small"
for div_result in eval_xpath(doc, '//div[@id="links"]/div[contains(@class, "web-result")]'):
tr_rows = eval_xpath(result_table, './/tr')
# In the last <tr> is the form of the 'previous/next page' links
tr_rows = tr_rows[:-1]
item = {}
title = eval_xpath(div_result, './/h2/a')
if not title:
# this is the "No results." item in the result list
continue
item["title"] = extract_text(title)
item["url"] = eval_xpath(div_result, './/h2/a/@href')[0]
item["content"] = extract_text(eval_xpath(div_result, './/a[contains(@class, "result__snippet")]')[0])
len_tr_rows = len(tr_rows)
offset = 0
results.append(item)
zero_click_info_xpath = '//div[@id="zero_click_abstract"]'
zero_click_info_xpath = '//html/body/form/div/table[2]/tr[2]/td/text()'
zero_click = extract_text(eval_xpath(doc, zero_click_info_xpath)).strip()
if zero_click and (
"Your IP address is" not in zero_click
and "Your user agent:" not in zero_click
and "URL Decoded:" not in zero_click
):
if zero_click and "Your IP address is" not in zero_click and "Your user agent:" not in zero_click:
current_query = resp.search_params["data"].get("q")
results.append(
@ -395,6 +352,33 @@ def response(resp):
}
)
while len_tr_rows >= offset + 4:
# assemble table rows we need to scrap
tr_title = tr_rows[offset]
tr_content = tr_rows[offset + 1]
offset += 4
# ignore sponsored Adds <tr class="result-sponsored">
if tr_content.get('class') == 'result-sponsored':
continue
a_tag = eval_xpath_getindex(tr_title, './/td//a[@class="result-link"]', 0, None)
if a_tag is None:
continue
td_content = eval_xpath_getindex(tr_content, './/td[@class="result-snippet"]', 0, None)
if td_content is None:
continue
results.append(
{
'title': a_tag.text_content(),
'content': extract_text(td_content),
'url': a_tag.get('href'),
}
)
return results

View File

@ -62,7 +62,7 @@ filter_mapping = {0: 'off', 1: 'medium', 2: 'high'}
results_xpath = './/div[contains(@jscontroller, "SC7lYd")]'
title_xpath = './/a/h3[1]'
href_xpath = './/a[h3]/@href'
content_xpath = './/div[contains(@data-sncf, "1")]'
content_xpath = './/div[@data-sncf="1"]'
# Suggestions are links placed in a *card-section*, we extract only the text
# from the links not the links itself.

View File

@ -20,11 +20,11 @@
from __future__ import annotations
from typing import Literal
import os
import abc
import dataclasses
import hashlib
import logging
import pathlib
import sqlite3
import tempfile
import time
@ -103,7 +103,7 @@ class FaviconCacheConfig(msgspec.Struct): # pylint: disable=too-few-public-meth
:py:obj:`.cache.FaviconCacheMEM` (not recommended)
"""
db_url: str = tempfile.gettempdir() + os.sep + "faviconcache.db"
db_url: pathlib.Path = pathlib.Path(tempfile.gettempdir()) / "faviconcache.db"
"""URL of the SQLite DB, the path to the database file."""
HOLD_TIME: int = 60 * 60 * 24 * 30 # 30 days

View File

@ -27,10 +27,10 @@ class FaviconConfig(msgspec.Struct): # pylint: disable=too-few-public-methods
By specifying a version, it is possible to ensure downward compatibility in
the event of future changes to the configuration schema"""
cache: FaviconCacheConfig = msgspec.field(default_factory=FaviconCacheConfig)
cache: FaviconCacheConfig = FaviconCacheConfig
"""Setup of the :py:obj:`.cache.FaviconCacheConfig`."""
proxy: FaviconProxyConfig = msgspec.field(default_factory=FaviconProxyConfig)
proxy: FaviconProxyConfig = FaviconCacheConfig
"""Setup of the :py:obj:`.proxy.FaviconProxyConfig`."""
@classmethod

View File

@ -20,7 +20,7 @@ if (next_call_ts == false or next_call_ts == nil) then
-- 2/ the next call is a random time between start_after_from and start_after_to
local initial_delay = math.random(start_after_from, start_after_to)
redis.call('SET', redis_key, now + initial_delay)
return { false, initial_delay }
return { false, delay }
end
-- next_call_ts is defined

View File

@ -226,12 +226,15 @@ outgoing:
# - 'Hash plugin'
# - 'Self Information'
# - 'Tracker URL remover'
# - 'Unit converter plugin'
# - 'Ahmia blacklist' # activation depends on outgoing.using_tor_proxy
# # these plugins are disabled if nothing is configured ..
# - 'Hostnames plugin' # see 'hostnames' configuration below
# - 'Open Access DOI rewrite'
# - 'Tor check plugin'
# # Read the docs before activate: auto-detection of the language could be
# # detrimental to users expectations / users can activate the plugin in the
# # preferences if they want.
# - 'Autodetect search language'
# Configuration of the "Hostnames plugin":
#

View File

@ -39,8 +39,9 @@ msgstr ""
"Project-Id-Version: searx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-10-05 06:24+0000\n"
"PO-Revision-Date: 2024-11-14 14:07+0000\n"
"Last-Translator: return42 <return42@users.noreply.translate.codeberg.org>\n"
"PO-Revision-Date: 2024-10-06 14:31+0000\n"
"Last-Translator: Atul_Eterno <Atul_Eterno@users.noreply.translate.codeberg."
"org>\n"
"Language-Team: Spanish <https://translate.codeberg.org/projects/searxng/"
"searxng/es/>\n"
"Language: es\n"
@ -48,7 +49,7 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.8.1\n"
"X-Generator: Weblate 5.7.2\n"
"Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING']
@ -154,7 +155,7 @@ msgstr "preguntas y respuestas"
#. CATEGORY_GROUPS['REPOS']
#: searx/searxng.msg
msgid "repos"
msgstr "repositorios"
msgstr "repos"
#. CATEGORY_GROUPS['SOFTWARE_WIKIS']
#: searx/searxng.msg
@ -1245,11 +1246,11 @@ msgstr "Tiempo máximo"
#: searx/templates/simple/preferences/favicon.html:2
msgid "Favicon Resolver"
msgstr "Buscador de favicon"
msgstr ""
#: searx/templates/simple/preferences/favicon.html:15
msgid "Display favicons near search results"
msgstr "Mostrar los favicons al lado de los resultados de búsqueda"
msgstr ""
#: searx/templates/simple/preferences/footer.html:2
msgid ""

View File

@ -28,14 +28,13 @@
# unoyoa <unoyoa@users.noreply.translate.codeberg.org>, 2024.
# tiziodcaio <tiziodcaio@users.noreply.translate.codeberg.org>, 2024.
# Fabio_Perri <Fabio_Perri@users.noreply.translate.codeberg.org>, 2024.
# lrnz2 <lrnz2@users.noreply.translate.codeberg.org>, 2024.
msgid ""
msgstr ""
"Project-Id-Version: searx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-10-05 06:24+0000\n"
"PO-Revision-Date: 2024-11-14 02:16+0000\n"
"Last-Translator: lrnz2 <lrnz2@users.noreply.translate.codeberg.org>\n"
"PO-Revision-Date: 2024-10-08 13:41+0000\n"
"Last-Translator: return42 <return42@users.noreply.translate.codeberg.org>\n"
"Language-Team: Italian <https://translate.codeberg.org/projects/searxng/"
"searxng/it/>\n"
"Language: it\n"
@ -43,13 +42,13 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.8.1\n"
"X-Generator: Weblate 5.7.2\n"
"Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING']
#: searx/searxng.msg
msgid "without further subgrouping"
msgstr "senza altri sottogruppamenti"
msgstr "senza altri sottogruppi"
#. CONSTANT_NAMES['DEFAULT_CATEGORY']
#: searx/searxng.msg
@ -74,7 +73,7 @@ msgstr "musica"
#. CATEGORY_NAMES['SOCIAL_MEDIA']
#: searx/searxng.msg
msgid "social media"
msgstr "social media"
msgstr "social"
#. CATEGORY_NAMES['IMAGES']
#: searx/searxng.msg
@ -114,7 +113,7 @@ msgstr "mappa"
#. CATEGORY_NAMES['ONIONS']
#: searx/searxng.msg
msgid "onions"
msgstr "cipolle"
msgstr "onion"
#. CATEGORY_NAMES['SCIENCE']
#: searx/searxng.msg
@ -134,7 +133,7 @@ msgstr "dizionari"
#. CATEGORY_GROUPS['LYRICS']
#: searx/searxng.msg
msgid "lyrics"
msgstr "testo musicale"
msgstr "testi musicali"
#. CATEGORY_GROUPS['PACKAGES']
#: searx/searxng.msg
@ -149,12 +148,12 @@ msgstr "d&r"
#. CATEGORY_GROUPS['REPOS']
#: searx/searxng.msg
msgid "repos"
msgstr "repos"
msgstr "ripostigli"
#. CATEGORY_GROUPS['SOFTWARE_WIKIS']
#: searx/searxng.msg
msgid "software wikis"
msgstr "wiki del software"
msgstr "wiki software"
#. CATEGORY_GROUPS['WEB']
#: searx/searxng.msg
@ -194,7 +193,7 @@ msgstr "Tempo di attività"
#. BRAND_CUSTOM_LINKS['ABOUT']
#: searx/searxng.msg searx/templates/simple/base.html:50
msgid "About"
msgstr "Al riguardo"
msgstr "A proposito"
#. WEATHER_TERMS['AVERAGE TEMP.']
#: searx/engines/wttr.py:32 searx/searxng.msg

View File

@ -10,23 +10,21 @@
# return42 <return42@users.noreply.translate.codeberg.org>, 2024.
# omfj <omfj@users.noreply.translate.codeberg.org>, 2024.
# combwizard <combwizard@users.noreply.translate.codeberg.org>, 2024.
# laaknor <laaknor@users.noreply.translate.codeberg.org>, 2024.
# Aadniz <Aadniz@users.noreply.translate.codeberg.org>, 2024.
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-10-05 06:24+0000\n"
"PO-Revision-Date: 2024-11-09 12:07+0000\n"
"Last-Translator: Aadniz <Aadniz@users.noreply.translate.codeberg.org>\n"
"Language-Team: Norwegian Bokmål <https://translate.codeberg.org/projects/"
"searxng/searxng/nb_NO/>\n"
"PO-Revision-Date: 2024-10-04 21:35+0000\n"
"Last-Translator: combwizard "
"<combwizard@users.noreply.translate.codeberg.org>\n"
"Language: nb_NO\n"
"Language-Team: Norwegian Bokmål "
"<https://translate.codeberg.org/projects/searxng/searxng/nb_NO/>\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.8.1\n"
"Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING']
@ -193,13 +191,13 @@ msgstr "Skydekke"
#: searx/engines/duckduckgo_weather.py:45 searx/engines/wttr.py:51
#: searx/searxng.msg
msgid "Condition"
msgstr "Betingelse"
msgstr ""
#. WEATHER_TERMS['CURRENT CONDITION']
#: searx/engines/duckduckgo_weather.py:118 searx/engines/wttr.py:104
#: searx/searxng.msg
msgid "Current condition"
msgstr "Nåværende betingelse"
msgstr ""
#. WEATHER_TERMS['EVENING']
#: searx/engines/wttr.py:100 searx/searxng.msg
@ -222,13 +220,13 @@ msgstr "Luftfuktighet"
#: searx/engines/duckduckgo_weather.py:77 searx/engines/wttr.py:34
#: searx/searxng.msg
msgid "Max temp."
msgstr "Maks temp."
msgstr ""
#. WEATHER_TERMS['MIN TEMP.']
#: searx/engines/duckduckgo_weather.py:73 searx/engines/wttr.py:33
#: searx/searxng.msg
msgid "Min temp."
msgstr "Min temp."
msgstr ""
#. WEATHER_TERMS['MORNING']
#: searx/engines/wttr.py:100 searx/searxng.msg
@ -335,17 +333,17 @@ msgstr "opphavsmann"
#. SOCIAL_MEDIA_TERMS['THREAD OPEN']
#: searx/engines/discourse.py:149 searx/searxng.msg
msgid "open"
msgstr "åpen"
msgstr ""
#. SOCIAL_MEDIA_TERMS['THREAD CLOSED']
#: searx/engines/discourse.py:149 searx/searxng.msg
msgid "closed"
msgstr "lukket"
msgstr ""
#. SOCIAL_MEDIA_TERMS['THREAD ANSWERED']
#: searx/engines/discourse.py:160 searx/searxng.msg
msgid "answered"
msgstr "svart på"
msgstr ""
#: searx/webapp.py:332
msgid "No item found"
@ -422,7 +420,7 @@ msgstr "tilgang nektet"
#: searx/webutils.py:60
msgid "server API error"
msgstr "server API feil"
msgstr "Tjener-API-feil"
#: searx/webutils.py:79
msgid "Suspended"
@ -454,7 +452,7 @@ msgstr "Regn ut {functions} av parameterne"
#: searx/engines/mozhi.py:57
msgid "Synonyms"
msgstr "Synonymer"
msgstr ""
#: searx/engines/openstreetmap.py:159
msgid "Get directions"
@ -529,7 +527,7 @@ msgstr "Filkvalitet"
#: searx/plugins/calculator.py:14
msgid "Calculate mathematical expressions via the search bar"
msgstr "Kalkuler matematiske uttrykk via søkebaren"
msgstr ""
#: searx/plugins/hash_plugin.py:10
msgid "Converts strings to different hash digests."
@ -573,7 +571,7 @@ msgstr ""
#: searx/plugins/self_info.py:28
msgid "Your IP is: "
msgstr "Din IP er "
msgstr ""
#: searx/plugins/self_info.py:31
msgid "Your user-agent is: "
@ -581,16 +579,16 @@ msgstr ""
#: searx/plugins/tor_check.py:24
msgid "Tor check plugin"
msgstr "Tor sjekking plugin"
msgstr "Tor sjekk pluggin"
#: searx/plugins/tor_check.py:27
msgid ""
"This plugin checks if the address of the request is a Tor exit-node, and "
"informs the user if it is; like check.torproject.org, but from SearXNG."
msgstr ""
"Denne plugin-en sjekker om adressen til forespørselen er en Tor utgangsnode, "
"og informerer brukeren om den er det; slik som check.torproject.org gjør, "
"men fra SearXNG."
"Denne plugin sjekker om adressen til forespørselen er en Tor utgangsnode,"
" og informerer brukeren om den er det; som check.torproject.org, men fra "
"SearXNG."
#: searx/plugins/tor_check.py:61
msgid ""
@ -622,7 +620,7 @@ msgstr "Fjern sporer-argumenter fra returnert nettadresse"
#: searx/plugins/unit_converter.py:29
msgid "Convert between units"
msgstr "Konverter mellom forskjellige enheter"
msgstr ""
#: searx/templates/simple/404.html:4
msgid "Page not found"
@ -689,7 +687,7 @@ msgstr "Lengde"
#: searx/templates/simple/macros.html:41
msgid "Views"
msgstr "Visninger"
msgstr ""
#: searx/templates/simple/macros.html:42
#: searx/templates/simple/result_templates/files.html:34
@ -947,7 +945,7 @@ msgstr "Meldinger fra søkemotorene"
#: searx/templates/simple/elements/engines_msg.html:7
msgid "seconds"
msgstr "sekunder"
msgstr ""
#: searx/templates/simple/elements/search_url.html:3
msgid "Search URL"
@ -1053,7 +1051,7 @@ msgstr "Det er ingen flere resultater. Du kan prøve å:"
#: searx/templates/simple/messages/no_results.html:19
msgid "Refresh the page."
msgstr "oppfrisk siden."
msgstr "oppfrisk siden"
#: searx/templates/simple/messages/no_results.html:20
msgid "Search for another query or select another category (above)."
@ -1069,7 +1067,7 @@ msgstr "Bytt til en annen instans:"
#: searx/templates/simple/messages/no_results.html:24
msgid "Search for another query or select another category."
msgstr "Oppgi et annet søkeord eller velg en annen kategori."
msgstr ""
#: searx/templates/simple/messages/no_results.html:25
msgid "Go back to the previous page using the previous page button."
@ -1195,11 +1193,11 @@ msgstr ""
#: searx/templates/simple/preferences/engines.html:15
msgid "Enable all"
msgstr "Aktiver alle"
msgstr ""
#: searx/templates/simple/preferences/engines.html:16
msgid "Disable all"
msgstr "Deaktiver alle"
msgstr ""
#: searx/templates/simple/preferences/engines.html:25
msgid "!bang"
@ -1884,3 +1882,4 @@ msgstr "skjul video"
#~ msgid "Engines cannot retrieve results"
#~ msgstr "Søkemotorer kan ikke motta resultater"

View File

@ -22,15 +22,13 @@
# MVDW-Java <MVDW-Java@users.noreply.translate.codeberg.org>, 2024.
# notlmutsaers <notlmutsaers@users.noreply.translate.codeberg.org>, 2024.
# return42 <return42@users.noreply.translate.codeberg.org>, 2024.
# ljansen <ljansen@users.noreply.translate.codeberg.org>, 2024.
# zarlin <zarlin@users.noreply.translate.codeberg.org>, 2024.
msgid ""
msgstr ""
"Project-Id-Version: searx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-10-05 06:24+0000\n"
"PO-Revision-Date: 2024-11-02 04:00+0000\n"
"Last-Translator: zarlin <zarlin@users.noreply.translate.codeberg.org>\n"
"PO-Revision-Date: 2024-10-15 12:18+0000\n"
"Last-Translator: return42 <return42@users.noreply.translate.codeberg.org>\n"
"Language-Team: Dutch <https://translate.codeberg.org/projects/searxng/"
"searxng/nl/>\n"
"Language: nl\n"
@ -38,7 +36,7 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n != 1;\n"
"X-Generator: Weblate 5.8.1\n"
"X-Generator: Weblate 5.7.2\n"
"Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING']
@ -466,7 +464,7 @@ msgstr "Bereken {functions} van de opties"
#: searx/engines/mozhi.py:57
msgid "Synonyms"
msgstr "Synoniemen"
msgstr ""
#: searx/engines/openstreetmap.py:159
msgid "Get directions"
@ -494,7 +492,7 @@ msgstr "stemmen"
#: searx/engines/radio_browser.py:107
msgid "clicks"
msgstr "klikken"
msgstr "clicks"
#: searx/engines/seekr.py:193 searx/engines/yummly.py:71
#: searx/engines/zlibrary.py:137
@ -663,7 +661,7 @@ msgstr "Voorkeuren"
#: searx/templates/simple/base.html:68
msgid "Powered by"
msgstr "Verzorgd door"
msgstr "Zoekmachine"
#: searx/templates/simple/base.html:68
msgid "a privacy-respecting, open metasearch engine"
@ -1070,7 +1068,7 @@ msgstr "Er zijn geen resultaten meer. U kunt proberen om:"
#: searx/templates/simple/messages/no_results.html:19
msgid "Refresh the page."
msgstr "Ververs de pagina."
msgstr "Ververs de pagina"
#: searx/templates/simple/messages/no_results.html:20
msgid "Search for another query or select another category (above)."
@ -1237,11 +1235,11 @@ msgstr "Max. duur"
#: searx/templates/simple/preferences/favicon.html:2
msgid "Favicon Resolver"
msgstr "Favicon Oplosser"
msgstr ""
#: searx/templates/simple/preferences/favicon.html:15
msgid "Display favicons near search results"
msgstr "Vertoon zoekresultaten naast favicons"
msgstr ""
#: searx/templates/simple/preferences/footer.html:2
msgid ""

View File

@ -23,8 +23,8 @@ msgstr ""
"Project-Id-Version: searx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-10-05 06:24+0000\n"
"PO-Revision-Date: 2024-10-28 21:07+0000\n"
"Last-Translator: Eryk Michalak <gnu.ewm@protonmail.com>\n"
"PO-Revision-Date: 2024-10-15 12:18+0000\n"
"Last-Translator: return42 <return42@users.noreply.translate.codeberg.org>\n"
"Language-Team: Polish <https://translate.codeberg.org/projects/searxng/"
"searxng/pl/>\n"
"Language: pl\n"
@ -34,7 +34,7 @@ msgstr ""
"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && ("
"n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && "
"n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);\n"
"X-Generator: Weblate 5.8.1\n"
"X-Generator: Weblate 5.7.2\n"
"Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING']
@ -1230,7 +1230,7 @@ msgstr "Maksymalny czas"
#: searx/templates/simple/preferences/favicon.html:2
msgid "Favicon Resolver"
msgstr "Pobieranie favikony"
msgstr ""
#: searx/templates/simple/preferences/favicon.html:15
msgid "Display favicons near search results"

View File

@ -19,14 +19,13 @@
# gvlx <gvlx@users.noreply.translate.codeberg.org>, 2024.
# ds451 <ds451@users.noreply.translate.codeberg.org>, 2024.
# Pedro_Tresp <Pedro_Tresp@users.noreply.translate.codeberg.org>, 2024.
# saltsnorter <saltsnorter@users.noreply.translate.codeberg.org>, 2024.
msgid ""
msgstr ""
"Project-Id-Version: searx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-10-05 06:24+0000\n"
"PO-Revision-Date: 2024-10-29 05:54+0000\n"
"Last-Translator: saltsnorter <saltsnorter@users.noreply.translate.codeberg."
"PO-Revision-Date: 2024-10-13 23:26+0000\n"
"Last-Translator: Pedro_Tresp <Pedro_Tresp@users.noreply.translate.codeberg."
"org>\n"
"Language-Team: Portuguese <https://translate.codeberg.org/projects/searxng/"
"searxng/pt/>\n"
@ -35,7 +34,7 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
"X-Generator: Weblate 5.8.1\n"
"X-Generator: Weblate 5.7.2\n"
"Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING']
@ -176,7 +175,7 @@ msgstr "escuro"
#. STYLE_NAMES['BLACK']
#: searx/searxng.msg
msgid "black"
msgstr "preto"
msgstr ""
#. BRAND_CUSTOM_LINKS['UPTIME']
#: searx/searxng.msg
@ -1229,11 +1228,11 @@ msgstr "Tempo máximo"
#: searx/templates/simple/preferences/favicon.html:2
msgid "Favicon Resolver"
msgstr "Solucionador do Favicon"
msgstr ""
#: searx/templates/simple/preferences/favicon.html:15
msgid "Display favicons near search results"
msgstr "Monstra os favicons nos proximos os resultados"
msgstr ""
#: searx/templates/simple/preferences/footer.html:2
msgid ""

View File

@ -30,14 +30,13 @@
# Pyrbor <Pyrbor@users.noreply.translate.codeberg.org>, 2024.
# rodgui <rodgui@users.noreply.translate.codeberg.org>, 2024.
# rafablog77 <rafablog77@users.noreply.translate.codeberg.org>, 2024.
# Juno Takano <jutty@users.noreply.translate.codeberg.org>, 2024.
msgid ""
msgstr ""
"Project-Id-Version: searx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-10-05 06:24+0000\n"
"PO-Revision-Date: 2024-10-31 12:16+0000\n"
"Last-Translator: Juno Takano <jutty@users.noreply.translate.codeberg.org>\n"
"PO-Revision-Date: 2024-10-15 12:18+0000\n"
"Last-Translator: return42 <return42@users.noreply.translate.codeberg.org>\n"
"Language-Team: Portuguese (Brazil) <https://translate.codeberg.org/projects/"
"searxng/searxng/pt_BR/>\n"
"Language: pt_BR\n"
@ -45,7 +44,7 @@ msgstr ""
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=n > 1;\n"
"X-Generator: Weblate 5.8.1\n"
"X-Generator: Weblate 5.7.2\n"
"Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING']
@ -186,7 +185,7 @@ msgstr "escuro"
#. STYLE_NAMES['BLACK']
#: searx/searxng.msg
msgid "black"
msgstr "preto"
msgstr ""
#. BRAND_CUSTOM_LINKS['UPTIME']
#: searx/searxng.msg
@ -473,7 +472,7 @@ msgstr "Computar {functions} dos argumentos"
#: searx/engines/mozhi.py:57
msgid "Synonyms"
msgstr "Sinônimos"
msgstr ""
#: searx/engines/openstreetmap.py:159
msgid "Get directions"
@ -1244,7 +1243,7 @@ msgstr "Tempo máximo"
#: searx/templates/simple/preferences/favicon.html:2
msgid "Favicon Resolver"
msgstr "Resolvedor de Favicons"
msgstr ""
#: searx/templates/simple/preferences/favicon.html:15
msgid "Display favicons near search results"

View File

@ -8,23 +8,21 @@
# return42 <return42@users.noreply.translate.codeberg.org>, 2024.
# abhabongse <abhabongse@users.noreply.translate.codeberg.org>, 2024.
# tutakrab <tutakrab@users.noreply.translate.codeberg.org>, 2024.
# sahussawud <sahussawud@users.noreply.translate.codeberg.org>, 2024.
msgid ""
msgstr ""
"Project-Id-Version: PROJECT VERSION\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-10-05 06:24+0000\n"
"PO-Revision-Date: 2024-11-06 07:26+0000\n"
"Last-Translator: sahussawud <sahussawud@users.noreply.translate.codeberg.org>"
"PO-Revision-Date: 2024-10-02 16:10+0000\n"
"Last-Translator: tutakrab <tutakrab@users.noreply.translate.codeberg.org>"
"\n"
"Language-Team: Thai <https://translate.codeberg.org/projects/searxng/searxng/"
"th/>\n"
"Language: th\n"
"Language-Team: Thai "
"<https://translate.codeberg.org/projects/searxng/searxng/th/>\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.8.1\n"
"Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING']
@ -165,7 +163,7 @@ msgstr "มืด"
#. STYLE_NAMES['BLACK']
#: searx/searxng.msg
msgid "black"
msgstr "สีดำ"
msgstr ""
#. BRAND_CUSTOM_LINKS['UPTIME']
#: searx/searxng.msg
@ -333,12 +331,12 @@ msgstr "ผู้เขียน"
#. SOCIAL_MEDIA_TERMS['THREAD OPEN']
#: searx/engines/discourse.py:149 searx/searxng.msg
msgid "open"
msgstr "สร้าง"
msgstr ""
#. SOCIAL_MEDIA_TERMS['THREAD CLOSED']
#: searx/engines/discourse.py:149 searx/searxng.msg
msgid "closed"
msgstr "ลบ"
msgstr ""
#. SOCIAL_MEDIA_TERMS['THREAD ANSWERED']
#: searx/engines/discourse.py:160 searx/searxng.msg
@ -452,7 +450,7 @@ msgstr "คำนวณ {functions} จากอาร์กิวเมนต
#: searx/engines/mozhi.py:57
msgid "Synonyms"
msgstr "คำเหมือน"
msgstr ""
#: searx/engines/openstreetmap.py:159
msgid "Get directions"
@ -540,9 +538,8 @@ msgid "hash digest"
msgstr "แฮชย่อย"
#: searx/plugins/hostnames.py:103
#, fuzzy
msgid "Hostnames plugin"
msgstr "ชื่อโฮส ปลั๊กอิน"
msgstr ""
#: searx/plugins/hostnames.py:104
msgid "Rewrite hostnames, remove results or prioritize them based on the hostname"
@ -1701,3 +1698,4 @@ msgstr "ซ่อนวิดีโอ"
#~ msgid "Engines cannot retrieve results"
#~ msgstr "เครื่องมือไม่สามารถดึงผลลัพธ์ได้"

View File

@ -10,22 +10,21 @@
# return42 <return42@users.noreply.translate.codeberg.org>, 2024.
# vducong <vducong@users.noreply.translate.codeberg.org>, 2024.
# tvminh19 <tvminh19@users.noreply.translate.codeberg.org>, 2024.
# KhietVo <KhietVo@users.noreply.translate.codeberg.org>, 2024.
msgid ""
msgstr ""
"Project-Id-Version: searx\n"
"Project-Id-Version: searx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-10-05 06:24+0000\n"
"PO-Revision-Date: 2024-11-14 14:07+0000\n"
"Last-Translator: KhietVo <KhietVo@users.noreply.translate.codeberg.org>\n"
"Language-Team: Vietnamese <https://translate.codeberg.org/projects/searxng/"
"searxng/vi/>\n"
"PO-Revision-Date: 2024-08-07 01:02+0000\n"
"Last-Translator: tvminh19 <tvminh19@users.noreply.translate.codeberg.org>"
"\n"
"Language: vi\n"
"Language-Team: Vietnamese "
"<https://translate.codeberg.org/projects/searxng/searxng/vi/>\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.8.1\n"
"Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING']
@ -167,7 +166,7 @@ msgstr "Tối"
#. STYLE_NAMES['BLACK']
#: searx/searxng.msg
msgid "black"
msgstr "màu đen"
msgstr ""
#. BRAND_CUSTOM_LINKS['UPTIME']
#: searx/searxng.msg
@ -187,7 +186,7 @@ msgstr "Nhiệt độ trung bình."
#. WEATHER_TERMS['CLOUD COVER']
#: searx/engines/open_meteo.py:91 searx/searxng.msg
msgid "Cloud cover"
msgstr "Mây che phủ"
msgstr ""
#. WEATHER_TERMS['CONDITION']
#: searx/engines/duckduckgo_weather.py:45 searx/engines/wttr.py:51
@ -199,7 +198,7 @@ msgstr "Điều kiện"
#: searx/engines/duckduckgo_weather.py:118 searx/engines/wttr.py:104
#: searx/searxng.msg
msgid "Current condition"
msgstr "tình hình hiện tại"
msgstr ""
#. WEATHER_TERMS['EVENING']
#: searx/engines/wttr.py:100 searx/searxng.msg
@ -210,25 +209,25 @@ msgstr "Buổi chiều"
#: searx/engines/duckduckgo_weather.py:53 searx/engines/open_meteo.py:81
#: searx/engines/wttr.py:59 searx/searxng.msg
msgid "Feels like"
msgstr "Cảm thấy"
msgstr ""
#. WEATHER_TERMS['HUMIDITY']
#: searx/engines/duckduckgo_weather.py:64 searx/engines/open_meteo.py:93
#: searx/engines/wttr.py:68 searx/searxng.msg
msgid "Humidity"
msgstr "Độ ẩm"
msgstr ""
#. WEATHER_TERMS['MAX TEMP.']
#: searx/engines/duckduckgo_weather.py:77 searx/engines/wttr.py:34
#: searx/searxng.msg
msgid "Max temp."
msgstr "Nhiệt độ tối đa"
msgstr ""
#. WEATHER_TERMS['MIN TEMP.']
#: searx/engines/duckduckgo_weather.py:73 searx/engines/wttr.py:33
#: searx/searxng.msg
msgid "Min temp."
msgstr "Nhiệt độ thấp nhất"
msgstr ""
#. WEATHER_TERMS['MORNING']
#: searx/engines/wttr.py:100 searx/searxng.msg
@ -248,53 +247,53 @@ msgstr "Buổi trưa"
#. WEATHER_TERMS['PRESSURE']
#: searx/engines/open_meteo.py:95 searx/searxng.msg
msgid "Pressure"
msgstr "Áp suất"
msgstr ""
#. WEATHER_TERMS['SUNRISE']
#: searx/engines/duckduckgo_weather.py:81 searx/engines/wttr.py:36
#: searx/searxng.msg
msgid "Sunrise"
msgstr "Mặt trời mọc"
msgstr ""
#. WEATHER_TERMS['SUNSET']
#: searx/engines/duckduckgo_weather.py:82 searx/engines/wttr.py:37
#: searx/searxng.msg
msgid "Sunset"
msgstr "mặt trời lặn"
msgstr ""
#. WEATHER_TERMS['TEMPERATURE']
#: searx/engines/duckduckgo_weather.py:48 searx/engines/open_meteo.py:76
#: searx/engines/wttr.py:55 searx/searxng.msg
msgid "Temperature"
msgstr "Nhiệt độ"
msgstr ""
#. WEATHER_TERMS['UV INDEX']
#: searx/engines/duckduckgo_weather.py:80 searx/engines/wttr.py:35
#: searx/searxng.msg
msgid "UV index"
msgstr "Chỉ số UV"
msgstr ""
#. WEATHER_TERMS['VISIBILITY']
#: searx/engines/duckduckgo_weather.py:62 searx/engines/wttr.py:66
#: searx/searxng.msg
msgid "Visibility"
msgstr "Tầm nhìn"
msgstr ""
#. WEATHER_TERMS['WIND']
#: searx/engines/duckduckgo_weather.py:58 searx/engines/open_meteo.py:86
#: searx/engines/wttr.py:62 searx/searxng.msg
msgid "Wind"
msgstr "Gió"
msgstr ""
#. SOCIAL_MEDIA_TERMS['SUBSCRIBERS']
#: searx/engines/lemmy.py:85 searx/searxng.msg
msgid "subscribers"
msgstr "người đăng ký"
msgstr ""
#. SOCIAL_MEDIA_TERMS['POSTS']
#: searx/engines/lemmy.py:86 searx/searxng.msg
msgid "posts"
msgstr "những bài đăng"
msgstr ""
#. SOCIAL_MEDIA_TERMS['ACTIVE USERS']
#: searx/engines/lemmy.py:87 searx/searxng.msg
@ -310,42 +309,42 @@ msgstr ""
#. SOCIAL_MEDIA_TERMS['USER']
#: searx/engines/lemmy.py:129 searx/engines/lemmy.py:164 searx/searxng.msg
msgid "user"
msgstr "người dùng"
msgstr ""
#. SOCIAL_MEDIA_TERMS['COMMUNITY']
#: searx/engines/lemmy.py:131 searx/engines/lemmy.py:165 searx/searxng.msg
msgid "community"
msgstr "cộng đồng"
msgstr ""
#. SOCIAL_MEDIA_TERMS['POINTS']
#: searx/engines/hackernews.py:78 searx/searxng.msg
msgid "points"
msgstr "điểm"
msgstr ""
#. SOCIAL_MEDIA_TERMS['TITLE']
#: searx/searxng.msg
msgid "title"
msgstr "tiêu đề"
msgstr ""
#. SOCIAL_MEDIA_TERMS['AUTHOR']
#: searx/engines/hackernews.py:81 searx/searxng.msg
msgid "author"
msgstr "tác giả"
msgstr ""
#. SOCIAL_MEDIA_TERMS['THREAD OPEN']
#: searx/engines/discourse.py:149 searx/searxng.msg
msgid "open"
msgstr "mở"
msgstr ""
#. SOCIAL_MEDIA_TERMS['THREAD CLOSED']
#: searx/engines/discourse.py:149 searx/searxng.msg
msgid "closed"
msgstr "đóng"
msgstr ""
#. SOCIAL_MEDIA_TERMS['THREAD ANSWERED']
#: searx/engines/discourse.py:160 searx/searxng.msg
msgid "answered"
msgstr "đã trả lời"
msgstr ""
#: searx/webapp.py:332
msgid "No item found"
@ -530,7 +529,7 @@ msgstr "Chất lượng tệp"
#: searx/plugins/calculator.py:14
msgid "Calculate mathematical expressions via the search bar"
msgstr "Tính toán bằng thanh tìm kiếm"
msgstr ""
#: searx/plugins/hash_plugin.py:10
msgid "Converts strings to different hash digests."
@ -541,14 +540,12 @@ msgid "hash digest"
msgstr "hash băm"
#: searx/plugins/hostnames.py:103
#, fuzzy
msgid "Hostnames plugin"
msgstr "Mấy chủ bổ trợ"
msgstr ""
#: searx/plugins/hostnames.py:104
msgid "Rewrite hostnames, remove results or prioritize them based on the hostname"
msgstr ""
"Viết lại máy chủ, xoá các kểt quả tìm kiếm hoặc sắp xếp dựa trên máy chủ"
#: searx/plugins/oa_doi_rewrite.py:12
msgid "Open Access DOI rewrite"
@ -574,7 +571,7 @@ msgstr "Hiện IP của bạn khi gõ \"ip\" và hiện user agent khi gõ \"use
#: searx/plugins/self_info.py:28
msgid "Your IP is: "
msgstr "Địa chỉ IP của bạn: "
msgstr ""
#: searx/plugins/self_info.py:31
msgid "Your user-agent is: "
@ -1993,3 +1990,4 @@ msgstr "ẩn phim"
#~ msgid "Engines cannot retrieve results"
#~ msgstr "Các trình tìm kiếm không nhận được kết quả"

View File

@ -28,19 +28,18 @@
# hugoalh <hugoalh@users.noreply.translate.codeberg.org>, 2024.
msgid ""
msgstr ""
"Project-Id-Version: searx\n"
"Project-Id-Version: searx\n"
"Report-Msgid-Bugs-To: EMAIL@ADDRESS\n"
"POT-Creation-Date: 2024-10-05 06:24+0000\n"
"PO-Revision-Date: 2024-10-26 21:13+0000\n"
"Last-Translator: return42 <return42@users.noreply.translate.codeberg.org>\n"
"Language-Team: Chinese (Traditional Han script) <https://translate.codeberg."
"org/projects/searxng/searxng/zh_Hant/>\n"
"PO-Revision-Date: 2024-08-12 04:00+0000\n"
"Last-Translator: hugoalh <hugoalh@users.noreply.translate.codeberg.org>\n"
"Language: zh_Hant_TW\n"
"Language-Team: Chinese (Traditional) "
"<https://translate.codeberg.org/projects/searxng/searxng/zh_Hant/>\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=1; plural=0;\n"
"X-Generator: Weblate 5.8.1\n"
"Generated-By: Babel 2.16.0\n"
#. CONSTANT_NAMES['NO_SUBGROUPING']
@ -181,7 +180,7 @@ msgstr "黑暗"
#. STYLE_NAMES['BLACK']
#: searx/searxng.msg
msgid "black"
msgstr "黑色"
msgstr ""
#. BRAND_CUSTOM_LINKS['UPTIME']
#: searx/searxng.msg
@ -468,7 +467,7 @@ msgstr "計算 {functions} 參數"
#: searx/engines/mozhi.py:57
msgid "Synonyms"
msgstr "同義詞"
msgstr ""
#: searx/engines/openstreetmap.py:159
msgid "Get directions"
@ -943,7 +942,7 @@ msgstr "來自搜尋引擎的訊息"
#: searx/templates/simple/elements/engines_msg.html:7
msgid "seconds"
msgstr ""
msgstr ""
#: searx/templates/simple/elements/search_url.html:3
msgid "Search URL"
@ -1207,11 +1206,11 @@ msgstr "最大時間"
#: searx/templates/simple/preferences/favicon.html:2
msgid "Favicon Resolver"
msgstr "網站圖標搜索器"
msgstr ""
#: searx/templates/simple/preferences/favicon.html:15
msgid "Display favicons near search results"
msgstr "在搜尋結果旁顯示網站圖標"
msgstr ""
#: searx/templates/simple/preferences/footer.html:2
msgid ""
@ -1912,3 +1911,4 @@ msgstr "隱藏影片"
#~ msgid "Engines cannot retrieve results"
#~ msgstr "引擎無法擷取結果"