forked from zaclys/searxng
Merge pull request #2326 from return42/ungrouped
[mod] clarify the difference of the default category and subgrouping
This commit is contained in:
commit
393e14965a
|
@ -311,7 +311,6 @@ Global Settings
|
||||||
``results_on_new_tab``:
|
``results_on_new_tab``:
|
||||||
Open result links in a new tab by default.
|
Open result links in a new tab by default.
|
||||||
|
|
||||||
|
|
||||||
.. _settings redis:
|
.. _settings redis:
|
||||||
|
|
||||||
``redis:``
|
``redis:``
|
||||||
|
@ -457,6 +456,9 @@ Communication with search engines.
|
||||||
``max_redirects`` :
|
``max_redirects`` :
|
||||||
30 by default. Maximum redirect before it is an error.
|
30 by default. Maximum redirect before it is an error.
|
||||||
|
|
||||||
|
|
||||||
|
.. _settings categories_as_tabs:
|
||||||
|
|
||||||
``categories_as_tabs:``
|
``categories_as_tabs:``
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
|
@ -477,6 +479,15 @@ Categories not listed here can still be searched with the :ref:`search-syntax`.
|
||||||
files:
|
files:
|
||||||
social media:
|
social media:
|
||||||
|
|
||||||
|
Engines are added to ``categories:`` (compare :ref:`engine categories`), the
|
||||||
|
categories listed in ``categories_as_tabs`` are shown as tabs in the UI. If
|
||||||
|
there are no active engines in a category, the tab is not displayed (e.g. if a
|
||||||
|
user disables all engines in a category).
|
||||||
|
|
||||||
|
On the preferences page (``/preferences``) -- under *engines* -- there is an
|
||||||
|
additional tab, called *other*. In this tab are all engines listed that are not
|
||||||
|
in one of the UI tabs (not included in ``categories_as_tabs``).
|
||||||
|
|
||||||
.. _settings engine:
|
.. _settings engine:
|
||||||
|
|
||||||
Engine settings
|
Engine settings
|
||||||
|
@ -552,10 +563,21 @@ engine is shown. Most of the options have a default value or even are optional.
|
||||||
to build and send a ``Accept-Language`` header in the request to the origin
|
to build and send a ``Accept-Language`` header in the request to the origin
|
||||||
search engine.
|
search engine.
|
||||||
|
|
||||||
|
.. _engine categories:
|
||||||
|
|
||||||
``categories`` : optional
|
``categories`` : optional
|
||||||
Define in which categories this engine will be active. Most of the time, it is
|
Specifies to which categories the engine should be added. Engines can be
|
||||||
defined in the code of the engine, but in a few cases it is useful, like when
|
assigned to multiple categories.
|
||||||
describing multiple search engine using the same code.
|
|
||||||
|
Categories can be shown as tabs (:ref:`settings categories_as_tabs`) in the
|
||||||
|
UI. A search in a tab (in the UI) will query all engines that are active in
|
||||||
|
this tab. In the preferences page (``/preferences``) -- under *engines* --
|
||||||
|
users can select what engine should be active when querying in this tab.
|
||||||
|
|
||||||
|
Alternatively, :ref:`\!bang <search-syntax>` can be used to search all engines
|
||||||
|
in a category, regardless of whether they are active or not, or whether they
|
||||||
|
are in a tab of the UI or not. For example, ``!dictionaries`` can be used to
|
||||||
|
query all search engines in that category (group).
|
||||||
|
|
||||||
``timeout`` : optional
|
``timeout`` : optional
|
||||||
Timeout of the search with the current search engine. **Be careful, it will
|
Timeout of the search with the current search engine. **Be careful, it will
|
||||||
|
|
|
@ -46,7 +46,7 @@ Engine File
|
||||||
======================= =========== ========================================================
|
======================= =========== ========================================================
|
||||||
argument type information
|
argument type information
|
||||||
======================= =========== ========================================================
|
======================= =========== ========================================================
|
||||||
categories list pages, in which the engine is working
|
categories list categories, in which the engine is working
|
||||||
paging boolean support multiple pages
|
paging boolean support multiple pages
|
||||||
time_range_support boolean support search time range
|
time_range_support boolean support search time range
|
||||||
engine_type str - ``online`` :ref:`[ref] <demo online engine>` by
|
engine_type str - ``online`` :ref:`[ref] <demo online engine>` by
|
||||||
|
|
|
@ -81,7 +81,7 @@ class Engine: # pylint: disable=too-few-public-methods
|
||||||
# settings.yml
|
# settings.yml
|
||||||
|
|
||||||
categories: List[str]
|
categories: List[str]
|
||||||
"""Tabs, in which the engine is working."""
|
"""Specifies to which :ref:`engine categories` the engine should be added."""
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
"""Name that will be used across SearXNG to define this engine. In settings, on
|
"""Name that will be used across SearXNG to define this engine. In settings, on
|
||||||
|
|
|
@ -45,7 +45,7 @@ ENGINE_DEFAULT_ARGS = {
|
||||||
"about": {},
|
"about": {},
|
||||||
}
|
}
|
||||||
# set automatically when an engine does not have any tab category
|
# set automatically when an engine does not have any tab category
|
||||||
OTHER_CATEGORY = 'other'
|
DEFAULT_CATEGORY = 'other'
|
||||||
|
|
||||||
|
|
||||||
# Defaults for the namespace of an engine module, see :py:func:`load_engine`
|
# Defaults for the namespace of an engine module, see :py:func:`load_engine`
|
||||||
|
@ -132,7 +132,7 @@ def load_engine(engine_data: dict) -> Optional[Engine]:
|
||||||
set_loggers(engine, engine_name)
|
set_loggers(engine, engine_name)
|
||||||
|
|
||||||
if not any(cat in settings['categories_as_tabs'] for cat in engine.categories):
|
if not any(cat in settings['categories_as_tabs'] for cat in engine.categories):
|
||||||
engine.categories.append(OTHER_CATEGORY)
|
engine.categories.append(DEFAULT_CATEGORY)
|
||||||
|
|
||||||
return engine
|
return engine
|
||||||
|
|
||||||
|
|
|
@ -36,7 +36,7 @@ about = {
|
||||||
send_accept_language_header = True
|
send_accept_language_header = True
|
||||||
|
|
||||||
# engine dependent config
|
# engine dependent config
|
||||||
categories = ["others"]
|
categories = ["weather"]
|
||||||
URL = "https://duckduckgo.com/js/spice/forecast/{query}/{lang}"
|
URL = "https://duckduckgo.com/js/spice/forecast/{query}/{lang}"
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -15,7 +15,7 @@ about = {
|
||||||
"results": "JSON",
|
"results": "JSON",
|
||||||
}
|
}
|
||||||
|
|
||||||
categories = ["others"]
|
categories = ["weather"]
|
||||||
|
|
||||||
url = "https://wttr.in/{query}?format=j1&lang={lang}"
|
url = "https://wttr.in/{query}?format=j1&lang={lang}"
|
||||||
|
|
||||||
|
|
|
@ -17,7 +17,7 @@ from searx.enginelib import Engine
|
||||||
from searx.plugins import Plugin
|
from searx.plugins import Plugin
|
||||||
from searx.locales import LOCALE_NAMES
|
from searx.locales import LOCALE_NAMES
|
||||||
from searx.webutils import VALID_LANGUAGE_CODE
|
from searx.webutils import VALID_LANGUAGE_CODE
|
||||||
from searx.engines import OTHER_CATEGORY
|
from searx.engines import DEFAULT_CATEGORY
|
||||||
|
|
||||||
|
|
||||||
COOKIE_MAX_AGE = 60 * 60 * 24 * 365 * 5 # 5 years
|
COOKIE_MAX_AGE = 60 * 60 * 24 * 365 * 5 # 5 years
|
||||||
|
@ -259,7 +259,7 @@ class EnginesSetting(BooleanChoices):
|
||||||
choices = {}
|
choices = {}
|
||||||
for engine in engines:
|
for engine in engines:
|
||||||
for category in engine.categories:
|
for category in engine.categories:
|
||||||
if not category in list(settings['categories_as_tabs'].keys()) + [OTHER_CATEGORY]:
|
if not category in list(settings['categories_as_tabs'].keys()) + [DEFAULT_CATEGORY]:
|
||||||
continue
|
continue
|
||||||
choices['{}__{}'.format(engine.name, category)] = not engine.disabled
|
choices['{}__{}'.format(engine.name, category)] = not engine.disabled
|
||||||
super().__init__(default_value, choices)
|
super().__init__(default_value, choices)
|
||||||
|
|
|
@ -15,8 +15,8 @@ __all__ = [
|
||||||
|
|
||||||
CONSTANT_NAMES = {
|
CONSTANT_NAMES = {
|
||||||
# Constants defined in other modules
|
# Constants defined in other modules
|
||||||
'DEFAULT_GROUP_NAME': webutils.DEFAULT_GROUP_NAME,
|
'NO_SUBGROUPING': webutils.NO_SUBGROUPING,
|
||||||
'OTHER_CATEGORY': engines.OTHER_CATEGORY,
|
'DEFAULT_CATEGORY': engines.DEFAULT_CATEGORY,
|
||||||
}
|
}
|
||||||
|
|
||||||
CATEGORY_NAMES = {
|
CATEGORY_NAMES = {
|
||||||
|
|
|
@ -298,18 +298,18 @@
|
||||||
<p>{{ _('Currently used search engines') }}</p>
|
<p>{{ _('Currently used search engines') }}</p>
|
||||||
{{ tabs_open() }}
|
{{ tabs_open() }}
|
||||||
{% set ns = namespace(checked=true) %}
|
{% set ns = namespace(checked=true) %}
|
||||||
{% for categ in categories_as_tabs + [OTHER_CATEGORY] %}
|
{% for categ in categories_as_tabs + [DEFAULT_CATEGORY] %}
|
||||||
{{ tab_header('enginetab', 'category' + categ, _(categ), ns.checked )}}
|
{{ tab_header('enginetab', 'category' + categ, _(categ), ns.checked )}}
|
||||||
{% set ns.checked = false %}
|
{% set ns.checked = false %}
|
||||||
{% if categ == OTHER_CATEGORY %}
|
{% if categ == DEFAULT_CATEGORY %}
|
||||||
<p>{{_('This tab does not show up for search results, but you can search the engines listed here via bangs.')}}</p>
|
<p>{{_('This tab dues not exists in the user interface, but you can search in these engines by its !bangs.')}} <a href="{{ url_for('info', pagename='search-syntax') }}">ⓘ</a></p>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<div class="scrollx">
|
<div class="scrollx">
|
||||||
<table class="striped table_engines">
|
<table class="striped table_engines">
|
||||||
<tr>{{- "" -}}
|
<tr>{{- "" -}}
|
||||||
<th class="engine_checkbox">{{ _("Allow") }}</th>{{- "" -}}
|
<th class="engine_checkbox">{{ _("Allow") }}</th>{{- "" -}}
|
||||||
<th class="name">{{ _("Engine name") }}</th>{{- "" -}}
|
<th class="name">{{ _("Engine name") }}</th>{{- "" -}}
|
||||||
<th class="shortcut">{{ _("Shortcut") }}</th>{{- "" -}}
|
<th class="shortcut">{{ _("!bang") }}</th>{{- "" -}}
|
||||||
<th>{{ _("Supports selected language") }}</th>{{- "" -}}
|
<th>{{ _("Supports selected language") }}</th>{{- "" -}}
|
||||||
<th>{{ _("SafeSearch") }}</th>{{- "" -}}
|
<th>{{ _("SafeSearch") }}</th>{{- "" -}}
|
||||||
<th>{{ _("Time range") }}</th>{{- "" -}}
|
<th>{{ _("Time range") }}</th>{{- "" -}}
|
||||||
|
|
|
@ -63,7 +63,7 @@ from searx.settings_defaults import OUTPUT_FORMATS
|
||||||
from searx.settings_loader import get_default_settings_path
|
from searx.settings_loader import get_default_settings_path
|
||||||
from searx.exceptions import SearxParameterException
|
from searx.exceptions import SearxParameterException
|
||||||
from searx.engines import (
|
from searx.engines import (
|
||||||
OTHER_CATEGORY,
|
DEFAULT_CATEGORY,
|
||||||
categories,
|
categories,
|
||||||
engines,
|
engines,
|
||||||
engine_shortcuts,
|
engine_shortcuts,
|
||||||
|
@ -435,7 +435,7 @@ def render(template_name: str, **kwargs):
|
||||||
kwargs['method'] = request.preferences.get_value('method')
|
kwargs['method'] = request.preferences.get_value('method')
|
||||||
kwargs['categories_as_tabs'] = list(settings['categories_as_tabs'].keys())
|
kwargs['categories_as_tabs'] = list(settings['categories_as_tabs'].keys())
|
||||||
kwargs['categories'] = _get_enable_categories(categories.keys())
|
kwargs['categories'] = _get_enable_categories(categories.keys())
|
||||||
kwargs['OTHER_CATEGORY'] = OTHER_CATEGORY
|
kwargs['DEFAULT_CATEGORY'] = DEFAULT_CATEGORY
|
||||||
|
|
||||||
# i18n
|
# i18n
|
||||||
kwargs['sxng_locales'] = [l for l in sxng_locales if l[0] in settings['search']['languages']]
|
kwargs['sxng_locales'] = [l for l in sxng_locales if l[0] in settings['search']['languages']]
|
||||||
|
|
|
@ -18,7 +18,7 @@ from codecs import getincrementalencoder
|
||||||
from flask_babel import gettext, format_date
|
from flask_babel import gettext, format_date
|
||||||
|
|
||||||
from searx import logger, settings
|
from searx import logger, settings
|
||||||
from searx.engines import OTHER_CATEGORY
|
from searx.engines import DEFAULT_CATEGORY
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from searx.enginelib import Engine
|
from searx.enginelib import Engine
|
||||||
|
@ -222,26 +222,24 @@ def is_flask_run_cmdline():
|
||||||
return frames[-2].filename.endswith('flask/cli.py')
|
return frames[-2].filename.endswith('flask/cli.py')
|
||||||
|
|
||||||
|
|
||||||
DEFAULT_GROUP_NAME = 'others'
|
NO_SUBGROUPING = 'without further subgrouping'
|
||||||
|
|
||||||
|
|
||||||
def group_engines_in_tab(engines: Iterable[Engine]) -> List[Tuple[str, Iterable[Engine]]]:
|
def group_engines_in_tab(engines: Iterable[Engine]) -> List[Tuple[str, Iterable[Engine]]]:
|
||||||
"""Groups an Iterable of engines by their first non tab category"""
|
"""Groups an Iterable of engines by their first non tab category (first subgroup)"""
|
||||||
|
|
||||||
def get_group(eng):
|
def get_subgroup(eng):
|
||||||
non_tab_categories = [
|
non_tab_categories = [c for c in eng.categories if c not in tabs + [DEFAULT_CATEGORY]]
|
||||||
c for c in eng.categories if c not in list(settings['categories_as_tabs'].keys()) + [OTHER_CATEGORY]
|
return non_tab_categories[0] if len(non_tab_categories) > 0 else NO_SUBGROUPING
|
||||||
]
|
|
||||||
return non_tab_categories[0] if len(non_tab_categories) > 0 else DEFAULT_GROUP_NAME
|
|
||||||
|
|
||||||
groups = itertools.groupby(sorted(engines, key=get_group), get_group)
|
|
||||||
|
|
||||||
def group_sort_key(group):
|
def group_sort_key(group):
|
||||||
return (group[0] == DEFAULT_GROUP_NAME, group[0].lower())
|
return (group[0] == NO_SUBGROUPING, group[0].lower())
|
||||||
|
|
||||||
sorted_groups = sorted(((name, list(engines)) for name, engines in groups), key=group_sort_key)
|
|
||||||
|
|
||||||
def engine_sort_key(engine):
|
def engine_sort_key(engine):
|
||||||
return (engine.about.get('language', ''), engine.name)
|
return (engine.about.get('language', ''), engine.name)
|
||||||
|
|
||||||
|
tabs = list(settings['categories_as_tabs'].keys())
|
||||||
|
subgroups = itertools.groupby(sorted(engines, key=get_subgroup), get_subgroup)
|
||||||
|
sorted_groups = sorted(((name, list(engines)) for name, engines in subgroups), key=group_sort_key)
|
||||||
|
|
||||||
return [(groupname, sorted(engines, key=engine_sort_key)) for groupname, engines in sorted_groups]
|
return [(groupname, sorted(engines, key=engine_sort_key)) for groupname, engines in sorted_groups]
|
||||||
|
|
Loading…
Reference in New Issue