Loading searx/templates/etheme/base.html +12 −13 Original line number Diff line number Diff line Loading @@ -8,23 +8,22 @@ <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" {% if rtl %} dir="rtl" {% endif %} class="{{ etheme_style }}"> <head> {% set version = spot_version.split('+') %} <meta charset="UTF-8" /> <meta name="description" content="spot ecloud global, powered by searx" /> <meta name="keywords" content="spot, ecloud, searx, search, search engine, metasearch, meta search" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="generator" content="searx/{{ version[0] }}"> <meta name="generator" content="searx/{{ version }}"> <meta name="referrer" content="no-referrer"> <meta name="viewport" content="width=device-width, initial-scale=1 , maximum-scale=1.0, user-scalable=1" /> {% block meta %}{% endblock %} <title>{% block title %}{% endblock %}{{ instance_name }}</title> <link rel="stylesheet" href="{{ url_for('static', filename='css/select2.min.css', v=version[0]) }}" type="text/css" /> <link rel="stylesheet" href="{{ url_for('static', filename='css/etheme.min.css', v=version[0]) }}" type="text/css" /> <link rel="stylesheet" href="{{ url_for('static', filename='css/etheme-dark.min.css', v=version[0]) }}" type="text/css" /> <link rel="stylesheet" href="{{ url_for('static', filename='css/select2.min.css', v=version) }}" type="text/css" /> <link rel="stylesheet" href="{{ url_for('static', filename='css/etheme.min.css', v=version) }}" type="text/css" /> <link rel="stylesheet" href="{{ url_for('static', filename='css/etheme-dark.min.css', v=version) }}" type="text/css" /> {% for css in styles %} <link rel="stylesheet" href="{{ url_for('static', filename=css, v=version[0]) }}" type="text/css" /> <link rel="stylesheet" href="{{ url_for('static', filename=css, v=version) }}" type="text/css" /> {% endfor %} <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> Loading Loading @@ -95,23 +94,23 @@ <a href="https://e.foundation/legal-notice-privacy">{{ _('Privacy') }}</a> </span></br> e Foundation 2018-{{ year }}, {{ _('Powered by') }} <a href="{{ repo_url }}">Spot</a> {{ version[0] }}<br/> {{ _('Powered by') }} <a href="{{ repo_url }}">Spot</a> {{ version }}<br/> An open-source metasearch engine forked from <a href="https://searx.github.io/searx/">Searx</a> </small> </p> </footer> <script src="{{ url_for('static', filename='js/jquery.min.js', v=version[0]) }}"></script> <script src="{{ url_for('static', filename='js/select2.min.js', v=version[0]) }}"></script> <script src="{{ url_for('static', filename='js/etheme.min.js', v=version[0]) }}"></script> {% if autocomplete %}<script src="{{ url_for('static', filename='js/typeahead.bundle.min.js', v=version[0]) }}"></script>{% endif %} <script src="{{ url_for('static', filename='js/searx.min.js', v=version[0]) }}" <script src="{{ url_for('static', filename='js/jquery.min.js', v=version) }}"></script> <script src="{{ url_for('static', filename='js/select2.min.js', v=version) }}"></script> <script src="{{ url_for('static', filename='js/etheme.min.js', v=version) }}"></script> {% if autocomplete %}<script src="{{ url_for('static', filename='js/typeahead.bundle.min.js', v=version) }}"></script>{% endif %} <script src="{{ url_for('static', filename='js/searx.min.js', v=version) }}" data-method="{{ method or 'POST' }}" data-autocompleter="{% if autocomplete %}true{% else %}false{% endif %}" data-translations="{{ translations }}"></script> {% for script in scripts %} <script src="{{ url_for('static', filename=script, v=version[0]) }}"></script> <script src="{{ url_for('static', filename=script, v=version) }}"></script> {% endfor %} </body> </html> searx/templates/etheme/results.html +2 −2 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ {% if pageno == 1 and 'general' in selected_categories %} <!-- Empty div for unit conversions --> <div class="result" id="unit_conversions"> <script src="{{ url_for('static', filename='js/math.min.js', v=version[0]) }}"></script> <script src="{{ url_for('static', filename='js/math.min.js', v=version) }}"></script> </div> {{ put_results(results[:3], True) }} <div class='first-page-media-results'> Loading Loading @@ -148,6 +148,6 @@ </div> <script src="{{ url_for('static', filename='js/math.init.js', v=version[0]) }}"></script> <script src="{{ url_for('static', filename='js/math.init.js', v=version) }}"></script> {% endblock %} searx/version.py +113 −23 Original line number Diff line number Diff line # -*- coding: utf-8 -*- ''' searx is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. # SPDX-License-Identifier: AGPL-3.0-or-later # lint: pylint # pylint: disable=,missing-module-docstring,missing-class-docstring searx is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. import os import shlex import subprocess import logging from importlib.metadata import version You should have received a copy of the GNU Affero General Public License along with searx. If not, see < http://www.gnu.org/licenses/ >. # fallback values # if there is searx.version_frozen module, and it is not possible to get the git tag VERSION_STRING = "1.0.0" VERSION_TAG = "1.0.0" GIT_URL = "unknow" GIT_BRANCH = "unknow" (C) 2013- by Adam Tauber, <asciimoo@gmail.com> ''' logger = logging.getLogger("searx") from pkg_resources import get_distribution, DistributionNotFound SUBPROCESS_RUN_ENV = { "PATH": os.environ["PATH"], "LC_ALL": "C", "LANGUAGE": "", } def subprocess_run(args, **kwargs): """Call :py:func:`subprocess.run` and return (striped) stdout. If returncode is non-zero, raise a :py:func:`subprocess.CalledProcessError`. """ if not isinstance(args, (list, tuple)): args = shlex.split(args) kwargs["env"] = kwargs.get("env", SUBPROCESS_RUN_ENV) kwargs["encoding"] = kwargs.get("encoding", "utf-8") kwargs["stdout"] = subprocess.PIPE kwargs["stderr"] = subprocess.PIPE # raise CalledProcessError if returncode is non-zero kwargs["check"] = True proc = subprocess.run(args, **kwargs) # pylint: disable=subprocess-run-check return proc.stdout.strip() def get_git_url_and_branch(): try: VERSION_STRING = get_distribution("spot").version except DistributionNotFound: VERSION_STRING = "0.0.0" ref = subprocess_run("git rev-parse --abbrev-ref @{upstream}") except subprocess.CalledProcessError: ref = subprocess_run("git rev-parse --abbrev-ref master@{upstream}") origin, git_branch = ref.split("/", 1) git_url = subprocess_run(["git", "remote", "get-url", origin]) # get https:// url from git@ url if git_url.startswith("git@"): git_url = git_url.replace(":", "/", 2).replace("git@", "https://", 1) if git_url.endswith(".git"): git_url = git_url.replace(".git", "", 1) return git_url, git_branch def get_git_version(): git_commit_date_hash = subprocess_run(r"git show -s --date='format:%Y.%m.%d' --format='%cd'") tag_version = git_version = git_commit_date_hash # add "-dirty" suffix if there are uncommited changes except searx/settings.yml try: SPOT_VERSION, METADATA_VERSION = VERSION_STRING.split("+") except ValueError: SPOT_VERSION = VERSION_STRING METADATA_VERSION = "" subprocess_run("git diff --quiet -- . ':!searx/settings.yml' ':!utils/brand.env'") except subprocess.CalledProcessError as e: if e.returncode == 1: git_version += "-dirty" else: logger.warning('"%s" returns an unexpected return code %i', e.returncode, e.cmd) return git_version, tag_version try: vf = version('spot') VERSION_STRING = VERSION_TAG = vf except ImportError: try: try: VERSION_STRING, VERSION_TAG = get_git_version() except subprocess.CalledProcessError as ex: logger.error("Error while getting the version: %s", ex.stderr) try: GIT_URL, GIT_BRANCH = get_git_url_and_branch() except subprocess.CalledProcessError as ex: logger.error("Error while getting the git URL & branch: %s", ex.stderr) except FileNotFoundError as ex: logger.error("%s is not found, fallback to the default version", ex.filename) logger.info("version: %s", VERSION_STRING) if __name__ == "__main__": import sys if len(sys.argv) >= 2 and sys.argv[1] == "freeze": # freeze the version (to create an archive outside a git repository) python_code = f"""# SPDX-License-Identifier: AGPL-3.0-or-later # this file is generated automatically by searx/version.py VERSION_STRING = "{VERSION_STRING}" VERSION_TAG = "{VERSION_TAG}" GIT_URL = "{GIT_URL}" GIT_BRANCH = "{GIT_BRANCH}" """ with open(os.path.join(os.path.dirname(__file__), "version_frozen.py"), "w", encoding="utf8") as f: f.write(python_code) print(f"{f.name} created") else: # output shell code to set the variables # usage: eval "$(python -m searx.version)" shell_code = f""" VERSION_STRING="{VERSION_STRING}" VERSION_TAG="{VERSION_TAG}" GIT_URL="{GIT_URL}" GIT_BRANCH="{GIT_BRANCH}" """ print(shell_code) searx/webapp.py +3 −3 Original line number Diff line number Diff line Loading @@ -70,7 +70,7 @@ from searx.webutils import ( ) from searx.webadapter import get_search_query_from_webapp, get_selected_categories from searx.utils import html_to_text, gen_useragent, dict_subset, match_language from searx.version import VERSION_STRING from searx.version import VERSION_TAG from searx.languages import language_codes as languages from searx.search import SearchWithPlugins, initialize as search_initialize from searx.search.checker import get_result as checker_get_result Loading Loading @@ -409,7 +409,7 @@ def render(template_name, override_theme=None, **kwargs): if locale in rtl_locales and 'rtl' not in kwargs: kwargs['rtl'] = True kwargs['spot_version'] = VERSION_STRING kwargs['version'] = VERSION_TAG kwargs['year'] = datetime.today().year Loading Loading @@ -1161,7 +1161,7 @@ def config(): 'autocomplete': settings['search']['autocomplete'], 'safe_search': settings['search']['safe_search'], 'default_theme': settings['ui']['default_theme'], 'version': VERSION_STRING, 'version': VERSION_TAG, 'brand': { 'CONTACT_URL': brand.CONTACT_URL, 'GIT_URL': brand.GIT_URL, Loading setup.py +10 −5 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ from setuptools import setup from setuptools import find_packages from searx.version import VERSION_STRING from searx.version import VERSION_TAG from searx import brand with open('README.md', encoding='utf-8') as f: Loading @@ -17,11 +17,11 @@ with open('requirements-dev.txt') as f: setup( name='spot', python_requires=">=3.7", version=VERSION_TAG, description="A privacy-respecting, hackable metasearch engine", long_description=long_description, url=brand.DOCS_URL, use_scm_version={"tag_regex": r"^(?:[\w-]+-)?(?P<version>[vV]?\d+(?:\.\d+){0,2}.*)$"}, setup_requires=['setuptools_scm'], project_urls={ "Code": brand.GIT_URL, "Issue tracker": brand.ISSUE_URL Loading @@ -35,8 +35,8 @@ setup( 'License :: OSI Approved :: GNU Affero General Public License v3' ], keywords='metasearch searchengine search web http', author='E FOUNDATION', author_email='dev@e.email', author='MURENA SAS', author_email='dev@murena.io', license='GNU Affero General Public License', packages=find_packages(exclude=["tests*", "searx_extra"]), zip_safe=False, Loading @@ -57,6 +57,8 @@ setup( '../requirements.txt', '../requirements-dev.txt', 'data/*', 'info/*', 'info/*/*', 'plugins/*/*', 'static/*.*', 'static/*/*.*', Loading @@ -65,6 +67,9 @@ setup( 'static/*/*/*/*/*.*', 'templates/*/*.*', 'templates/*/*/*.*', 'tests/*', 'tests/*/*', 'tests/*/*/*', 'translations/*/*/*' ], }, Loading Loading
searx/templates/etheme/base.html +12 −13 Original line number Diff line number Diff line Loading @@ -8,23 +8,22 @@ <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en" {% if rtl %} dir="rtl" {% endif %} class="{{ etheme_style }}"> <head> {% set version = spot_version.split('+') %} <meta charset="UTF-8" /> <meta name="description" content="spot ecloud global, powered by searx" /> <meta name="keywords" content="spot, ecloud, searx, search, search engine, metasearch, meta search" /> <meta http-equiv="X-UA-Compatible" content="IE=edge"> <meta name="generator" content="searx/{{ version[0] }}"> <meta name="generator" content="searx/{{ version }}"> <meta name="referrer" content="no-referrer"> <meta name="viewport" content="width=device-width, initial-scale=1 , maximum-scale=1.0, user-scalable=1" /> {% block meta %}{% endblock %} <title>{% block title %}{% endblock %}{{ instance_name }}</title> <link rel="stylesheet" href="{{ url_for('static', filename='css/select2.min.css', v=version[0]) }}" type="text/css" /> <link rel="stylesheet" href="{{ url_for('static', filename='css/etheme.min.css', v=version[0]) }}" type="text/css" /> <link rel="stylesheet" href="{{ url_for('static', filename='css/etheme-dark.min.css', v=version[0]) }}" type="text/css" /> <link rel="stylesheet" href="{{ url_for('static', filename='css/select2.min.css', v=version) }}" type="text/css" /> <link rel="stylesheet" href="{{ url_for('static', filename='css/etheme.min.css', v=version) }}" type="text/css" /> <link rel="stylesheet" href="{{ url_for('static', filename='css/etheme-dark.min.css', v=version) }}" type="text/css" /> {% for css in styles %} <link rel="stylesheet" href="{{ url_for('static', filename=css, v=version[0]) }}" type="text/css" /> <link rel="stylesheet" href="{{ url_for('static', filename=css, v=version) }}" type="text/css" /> {% endfor %} <!-- HTML5 Shim and Respond.js IE8 support of HTML5 elements and media queries --> Loading Loading @@ -95,23 +94,23 @@ <a href="https://e.foundation/legal-notice-privacy">{{ _('Privacy') }}</a> </span></br> e Foundation 2018-{{ year }}, {{ _('Powered by') }} <a href="{{ repo_url }}">Spot</a> {{ version[0] }}<br/> {{ _('Powered by') }} <a href="{{ repo_url }}">Spot</a> {{ version }}<br/> An open-source metasearch engine forked from <a href="https://searx.github.io/searx/">Searx</a> </small> </p> </footer> <script src="{{ url_for('static', filename='js/jquery.min.js', v=version[0]) }}"></script> <script src="{{ url_for('static', filename='js/select2.min.js', v=version[0]) }}"></script> <script src="{{ url_for('static', filename='js/etheme.min.js', v=version[0]) }}"></script> {% if autocomplete %}<script src="{{ url_for('static', filename='js/typeahead.bundle.min.js', v=version[0]) }}"></script>{% endif %} <script src="{{ url_for('static', filename='js/searx.min.js', v=version[0]) }}" <script src="{{ url_for('static', filename='js/jquery.min.js', v=version) }}"></script> <script src="{{ url_for('static', filename='js/select2.min.js', v=version) }}"></script> <script src="{{ url_for('static', filename='js/etheme.min.js', v=version) }}"></script> {% if autocomplete %}<script src="{{ url_for('static', filename='js/typeahead.bundle.min.js', v=version) }}"></script>{% endif %} <script src="{{ url_for('static', filename='js/searx.min.js', v=version) }}" data-method="{{ method or 'POST' }}" data-autocompleter="{% if autocomplete %}true{% else %}false{% endif %}" data-translations="{{ translations }}"></script> {% for script in scripts %} <script src="{{ url_for('static', filename=script, v=version[0]) }}"></script> <script src="{{ url_for('static', filename=script, v=version) }}"></script> {% endfor %} </body> </html>
searx/templates/etheme/results.html +2 −2 Original line number Diff line number Diff line Loading @@ -73,7 +73,7 @@ {% if pageno == 1 and 'general' in selected_categories %} <!-- Empty div for unit conversions --> <div class="result" id="unit_conversions"> <script src="{{ url_for('static', filename='js/math.min.js', v=version[0]) }}"></script> <script src="{{ url_for('static', filename='js/math.min.js', v=version) }}"></script> </div> {{ put_results(results[:3], True) }} <div class='first-page-media-results'> Loading Loading @@ -148,6 +148,6 @@ </div> <script src="{{ url_for('static', filename='js/math.init.js', v=version[0]) }}"></script> <script src="{{ url_for('static', filename='js/math.init.js', v=version) }}"></script> {% endblock %}
searx/version.py +113 −23 Original line number Diff line number Diff line # -*- coding: utf-8 -*- ''' searx is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. # SPDX-License-Identifier: AGPL-3.0-or-later # lint: pylint # pylint: disable=,missing-module-docstring,missing-class-docstring searx is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. import os import shlex import subprocess import logging from importlib.metadata import version You should have received a copy of the GNU Affero General Public License along with searx. If not, see < http://www.gnu.org/licenses/ >. # fallback values # if there is searx.version_frozen module, and it is not possible to get the git tag VERSION_STRING = "1.0.0" VERSION_TAG = "1.0.0" GIT_URL = "unknow" GIT_BRANCH = "unknow" (C) 2013- by Adam Tauber, <asciimoo@gmail.com> ''' logger = logging.getLogger("searx") from pkg_resources import get_distribution, DistributionNotFound SUBPROCESS_RUN_ENV = { "PATH": os.environ["PATH"], "LC_ALL": "C", "LANGUAGE": "", } def subprocess_run(args, **kwargs): """Call :py:func:`subprocess.run` and return (striped) stdout. If returncode is non-zero, raise a :py:func:`subprocess.CalledProcessError`. """ if not isinstance(args, (list, tuple)): args = shlex.split(args) kwargs["env"] = kwargs.get("env", SUBPROCESS_RUN_ENV) kwargs["encoding"] = kwargs.get("encoding", "utf-8") kwargs["stdout"] = subprocess.PIPE kwargs["stderr"] = subprocess.PIPE # raise CalledProcessError if returncode is non-zero kwargs["check"] = True proc = subprocess.run(args, **kwargs) # pylint: disable=subprocess-run-check return proc.stdout.strip() def get_git_url_and_branch(): try: VERSION_STRING = get_distribution("spot").version except DistributionNotFound: VERSION_STRING = "0.0.0" ref = subprocess_run("git rev-parse --abbrev-ref @{upstream}") except subprocess.CalledProcessError: ref = subprocess_run("git rev-parse --abbrev-ref master@{upstream}") origin, git_branch = ref.split("/", 1) git_url = subprocess_run(["git", "remote", "get-url", origin]) # get https:// url from git@ url if git_url.startswith("git@"): git_url = git_url.replace(":", "/", 2).replace("git@", "https://", 1) if git_url.endswith(".git"): git_url = git_url.replace(".git", "", 1) return git_url, git_branch def get_git_version(): git_commit_date_hash = subprocess_run(r"git show -s --date='format:%Y.%m.%d' --format='%cd'") tag_version = git_version = git_commit_date_hash # add "-dirty" suffix if there are uncommited changes except searx/settings.yml try: SPOT_VERSION, METADATA_VERSION = VERSION_STRING.split("+") except ValueError: SPOT_VERSION = VERSION_STRING METADATA_VERSION = "" subprocess_run("git diff --quiet -- . ':!searx/settings.yml' ':!utils/brand.env'") except subprocess.CalledProcessError as e: if e.returncode == 1: git_version += "-dirty" else: logger.warning('"%s" returns an unexpected return code %i', e.returncode, e.cmd) return git_version, tag_version try: vf = version('spot') VERSION_STRING = VERSION_TAG = vf except ImportError: try: try: VERSION_STRING, VERSION_TAG = get_git_version() except subprocess.CalledProcessError as ex: logger.error("Error while getting the version: %s", ex.stderr) try: GIT_URL, GIT_BRANCH = get_git_url_and_branch() except subprocess.CalledProcessError as ex: logger.error("Error while getting the git URL & branch: %s", ex.stderr) except FileNotFoundError as ex: logger.error("%s is not found, fallback to the default version", ex.filename) logger.info("version: %s", VERSION_STRING) if __name__ == "__main__": import sys if len(sys.argv) >= 2 and sys.argv[1] == "freeze": # freeze the version (to create an archive outside a git repository) python_code = f"""# SPDX-License-Identifier: AGPL-3.0-or-later # this file is generated automatically by searx/version.py VERSION_STRING = "{VERSION_STRING}" VERSION_TAG = "{VERSION_TAG}" GIT_URL = "{GIT_URL}" GIT_BRANCH = "{GIT_BRANCH}" """ with open(os.path.join(os.path.dirname(__file__), "version_frozen.py"), "w", encoding="utf8") as f: f.write(python_code) print(f"{f.name} created") else: # output shell code to set the variables # usage: eval "$(python -m searx.version)" shell_code = f""" VERSION_STRING="{VERSION_STRING}" VERSION_TAG="{VERSION_TAG}" GIT_URL="{GIT_URL}" GIT_BRANCH="{GIT_BRANCH}" """ print(shell_code)
searx/webapp.py +3 −3 Original line number Diff line number Diff line Loading @@ -70,7 +70,7 @@ from searx.webutils import ( ) from searx.webadapter import get_search_query_from_webapp, get_selected_categories from searx.utils import html_to_text, gen_useragent, dict_subset, match_language from searx.version import VERSION_STRING from searx.version import VERSION_TAG from searx.languages import language_codes as languages from searx.search import SearchWithPlugins, initialize as search_initialize from searx.search.checker import get_result as checker_get_result Loading Loading @@ -409,7 +409,7 @@ def render(template_name, override_theme=None, **kwargs): if locale in rtl_locales and 'rtl' not in kwargs: kwargs['rtl'] = True kwargs['spot_version'] = VERSION_STRING kwargs['version'] = VERSION_TAG kwargs['year'] = datetime.today().year Loading Loading @@ -1161,7 +1161,7 @@ def config(): 'autocomplete': settings['search']['autocomplete'], 'safe_search': settings['search']['safe_search'], 'default_theme': settings['ui']['default_theme'], 'version': VERSION_STRING, 'version': VERSION_TAG, 'brand': { 'CONTACT_URL': brand.CONTACT_URL, 'GIT_URL': brand.GIT_URL, Loading
setup.py +10 −5 Original line number Diff line number Diff line Loading @@ -3,7 +3,7 @@ from setuptools import setup from setuptools import find_packages from searx.version import VERSION_STRING from searx.version import VERSION_TAG from searx import brand with open('README.md', encoding='utf-8') as f: Loading @@ -17,11 +17,11 @@ with open('requirements-dev.txt') as f: setup( name='spot', python_requires=">=3.7", version=VERSION_TAG, description="A privacy-respecting, hackable metasearch engine", long_description=long_description, url=brand.DOCS_URL, use_scm_version={"tag_regex": r"^(?:[\w-]+-)?(?P<version>[vV]?\d+(?:\.\d+){0,2}.*)$"}, setup_requires=['setuptools_scm'], project_urls={ "Code": brand.GIT_URL, "Issue tracker": brand.ISSUE_URL Loading @@ -35,8 +35,8 @@ setup( 'License :: OSI Approved :: GNU Affero General Public License v3' ], keywords='metasearch searchengine search web http', author='E FOUNDATION', author_email='dev@e.email', author='MURENA SAS', author_email='dev@murena.io', license='GNU Affero General Public License', packages=find_packages(exclude=["tests*", "searx_extra"]), zip_safe=False, Loading @@ -57,6 +57,8 @@ setup( '../requirements.txt', '../requirements-dev.txt', 'data/*', 'info/*', 'info/*/*', 'plugins/*/*', 'static/*.*', 'static/*/*.*', Loading @@ -65,6 +67,9 @@ setup( 'static/*/*/*/*/*.*', 'templates/*/*.*', 'templates/*/*/*.*', 'tests/*', 'tests/*/*', 'tests/*/*/*', 'translations/*/*/*' ], }, Loading