summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarkus Heiser <markus.heiser@darmarit.de>2022-02-03 16:25:35 +0100
committerMarkus Heiser <markus.heiser@darmarit.de>2022-03-16 09:55:53 +0100
commitb9cf3c82a18a4782a3aa543c91392c6483f5d2a4 (patch)
treec072b9a295e6538b500bd93eed2109247824573a
parentcd92a7eacdd6b4c333e57111e1503b8455628067 (diff)
downloadsearxng-b9cf3c82a18a4782a3aa543c91392c6483f5d2a4.tar.gz
searxng-b9cf3c82a18a4782a3aa543c91392c6483f5d2a4.zip
[mod] add i18n infrastructure for SearXNG message files (searxng.msg)
With this patch ``searxng.msg`` files can be added to SearXNG. In ``searxng.msg`` files messages can be defined which are not captured by babel's gettext, like the generic names of the categories or messages that are stored in constants. Signed-off-by: Markus Heiser <markus.heiser@darmarit.de>
-rw-r--r--babel.cfg3
-rw-r--r--docs/dev/translation.rst1
-rw-r--r--docs/src/searx.babel_extract.rst8
-rwxr-xr-xmanage3
-rw-r--r--searx/babel_extract.py51
5 files changed, 65 insertions, 1 deletions
diff --git a/babel.cfg b/babel.cfg
index 03bde6ca5..03913c256 100644
--- a/babel.cfg
+++ b/babel.cfg
@@ -1,4 +1,7 @@
+[extractors]
+searxng_msg = searx.babel_extract.extract
[ignore: **/node_modules/**]
[python: **.py]
[jinja2: **/templates/**.html]
extensions=jinja2.ext.autoescape,jinja2.ext.with_
+[searxng_msg: **/searxng.msg]
diff --git a/docs/dev/translation.rst b/docs/dev/translation.rst
index 922c29c54..9de9ff2de 100644
--- a/docs/dev/translation.rst
+++ b/docs/dev/translation.rst
@@ -16,6 +16,7 @@ Translation
.. sidebar:: |translated|
+ - :ref:`searx.babel_extract`
- Weblate_
- SearXNG `translations branch`_
- SearXNG `Weblate repository`_
diff --git a/docs/src/searx.babel_extract.rst b/docs/src/searx.babel_extract.rst
new file mode 100644
index 000000000..741d67fc1
--- /dev/null
+++ b/docs/src/searx.babel_extract.rst
@@ -0,0 +1,8 @@
+.. _searx.babel_extract:
+
+===============================
+Custom message extractor (i18n)
+===============================
+
+.. automodule:: searx.babel_extract
+ :members:
diff --git a/manage b/manage
index e70b7f4dd..9e5b59fc7 100755
--- a/manage
+++ b/manage
@@ -30,7 +30,7 @@ GECKODRIVER_VERSION="v0.30.0"
export NODE_MINIMUM_VERSION="16.13.0"
# SPHINXOPTS=
BLACK_OPTIONS=("--target-version" "py37" "--line-length" "120" "--skip-string-normalization")
-BLACK_TARGETS=("--exclude" "searx/static,searx/languages.py" "searx" "searxng_extra" "tests")
+BLACK_TARGETS=("--exclude" "searx/static,searx/languages.py" "--include" "searxng.msg" "searx" "searxng_extra" "tests")
pylint.FILES() {
@@ -41,6 +41,7 @@ pylint.FILES() {
# These py files are linted by test.pylint()
grep -l -r --include \*.py '^#[[:blank:]]*lint:[[:blank:]]*pylint' searx searxng_extra tests
+ find . -name searxng.msg
}
YAMLLINT_FILES=()
diff --git a/searx/babel_extract.py b/searx/babel_extract.py
new file mode 100644
index 000000000..5f575f6d4
--- /dev/null
+++ b/searx/babel_extract.py
@@ -0,0 +1,51 @@
+# SPDX-License-Identifier: AGPL-3.0-or-later
+# lint: pylint
+"""This module implements the :origin:`searxng_msg <babel.cfg>` extractor to
+extract messages from:
+
+- None
+
+The ``searxng.msg`` files are selected by Babel_, see Babel's configuration in
+:origin:`babel.cfg`::
+
+ searxng_msg = searx.babel_extract.extract
+ ...
+ [searxng_msg: **/searxng.msg]
+
+A ``searxng.msg`` file is a python file that is *executed* by the
+:py:obj:`extract` function. Additional ``searxng.msg`` files can be added by:
+
+1. Adding a ``searxng.msg`` file in one of the SearXNG python packages and
+2. implement a method in :py:obj:`extract` that yields messages from this file.
+
+.. _Babel: https://babel.pocoo.org/en/latest/index.html
+
+"""
+
+from os import path
+
+SEARXNG_MSG_FILE = "searxng.msg"
+_MSG_FILES = []
+
+
+def extract(
+ # pylint: disable=unused-argument
+ fileobj,
+ keywords,
+ comment_tags,
+ options,
+):
+ """Extract messages from ``searxng.msg`` files by a custom extractor_.
+
+ .. _extractor:
+ https://babel.pocoo.org/en/latest/messages.html#writing-extraction-methods
+ """
+ if fileobj.name not in _MSG_FILES:
+ raise RuntimeError("don't know how to extract messages from %s" % fileobj.name)
+
+ namespace = {}
+ exec(fileobj.read(), {}, namespace) # pylint: disable=exec-used
+
+ for name in namespace['__all__']:
+ for k, v in namespace[name].items():
+ yield 0, '_', v, ["%s['%s']" % (name, k)]