mirror of
				https://github.com/searxng/searxng
				synced 2024-01-01 19:24:07 +01:00 
			
		
		
		
	Merge pull request #2326 from return42/ungrouped
[mod] clarify the difference of the default category and subgrouping
This commit is contained in:
		
						commit
						393e14965a
					
				
					 11 changed files with 56 additions and 36 deletions
				
			
		| 
						 | 
				
			
			@ -311,7 +311,6 @@ Global Settings
 | 
			
		|||
``results_on_new_tab``:
 | 
			
		||||
  Open result links in a new tab by default.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. _settings redis:
 | 
			
		||||
 | 
			
		||||
``redis:``
 | 
			
		||||
| 
						 | 
				
			
			@ -451,12 +450,15 @@ Communication with search engines.
 | 
			
		|||
  see `httpx verification defaults`_.
 | 
			
		||||
 | 
			
		||||
  In addition to ``verify``, SearXNG supports the ``$SSL_CERT_FILE`` (for a file) and
 | 
			
		||||
  ``$SSL_CERT_DIR`` (for a directory) OpenSSL variables.  
 | 
			
		||||
  ``$SSL_CERT_DIR`` (for a directory) OpenSSL variables.
 | 
			
		||||
  see `httpx ssl configuration`_.
 | 
			
		||||
 | 
			
		||||
``max_redirects`` :
 | 
			
		||||
  30 by default. Maximum redirect before it is an error.
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
.. _settings categories_as_tabs:
 | 
			
		||||
 | 
			
		||||
``categories_as_tabs:``
 | 
			
		||||
-----------------------
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -477,6 +479,15 @@ Categories not listed here can still be searched with the :ref:`search-syntax`.
 | 
			
		|||
    files:
 | 
			
		||||
    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:
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
  search engine.
 | 
			
		||||
 | 
			
		||||
.. _engine categories:
 | 
			
		||||
 | 
			
		||||
``categories`` : optional
 | 
			
		||||
  Define in which categories this engine will be active.  Most of the time, it is
 | 
			
		||||
  defined in the code of the engine, but in a few cases it is useful, like when
 | 
			
		||||
  describing multiple search engine using the same code.
 | 
			
		||||
  Specifies to which categories the engine should be added.  Engines can be
 | 
			
		||||
  assigned to multiple categories.
 | 
			
		||||
 | 
			
		||||
  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 of the search with the current search engine.  **Be careful, it will
 | 
			
		||||
| 
						 | 
				
			
			@ -658,7 +680,7 @@ and can relied on the default configuration :origin:`searx/settings.yml` using:
 | 
			
		|||
``engines:``
 | 
			
		||||
  With ``use_default_settings: true``, each settings can be override in a
 | 
			
		||||
  similar way, the ``engines`` section is merged according to the engine
 | 
			
		||||
  ``name``.  In this example, SearXNG will load all the default engines, will 
 | 
			
		||||
  ``name``.  In this example, SearXNG will load all the default engines, will
 | 
			
		||||
  enable the ``bing`` engine and define a :ref:`token <private engines>` for
 | 
			
		||||
  the arch linux engine:
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -46,7 +46,7 @@ Engine File
 | 
			
		|||
   ======================= =========== ========================================================
 | 
			
		||||
   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
 | 
			
		||||
   time_range_support      boolean     support search time range
 | 
			
		||||
   engine_type             str         - ``online`` :ref:`[ref] <demo online engine>` by
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -81,7 +81,7 @@ class Engine:  # pylint: disable=too-few-public-methods
 | 
			
		|||
    # settings.yml
 | 
			
		||||
 | 
			
		||||
    categories: List[str]
 | 
			
		||||
    """Tabs, in which the engine is working."""
 | 
			
		||||
    """Specifies to which :ref:`engine categories` the engine should be added."""
 | 
			
		||||
 | 
			
		||||
    name: str
 | 
			
		||||
    """Name that will be used across SearXNG to define this engine.  In settings, on
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -45,7 +45,7 @@ ENGINE_DEFAULT_ARGS = {
 | 
			
		|||
    "about": {},
 | 
			
		||||
}
 | 
			
		||||
# 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`
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +132,7 @@ def load_engine(engine_data: dict) -> Optional[Engine]:
 | 
			
		|||
    set_loggers(engine, engine_name)
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -36,7 +36,7 @@ about = {
 | 
			
		|||
send_accept_language_header = True
 | 
			
		||||
 | 
			
		||||
# engine dependent config
 | 
			
		||||
categories = ["others"]
 | 
			
		||||
categories = ["weather"]
 | 
			
		||||
URL = "https://duckduckgo.com/js/spice/forecast/{query}/{lang}"
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,7 @@ about = {
 | 
			
		|||
    "results": "JSON",
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
categories = ["others"]
 | 
			
		||||
categories = ["weather"]
 | 
			
		||||
 | 
			
		||||
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.locales import LOCALE_NAMES
 | 
			
		||||
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
 | 
			
		||||
| 
						 | 
				
			
			@ -259,7 +259,7 @@ class EnginesSetting(BooleanChoices):
 | 
			
		|||
        choices = {}
 | 
			
		||||
        for engine in engines:
 | 
			
		||||
            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
 | 
			
		||||
                choices['{}__{}'.format(engine.name, category)] = not engine.disabled
 | 
			
		||||
        super().__init__(default_value, choices)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,8 +15,8 @@ __all__ = [
 | 
			
		|||
 | 
			
		||||
CONSTANT_NAMES = {
 | 
			
		||||
    # Constants defined in other modules
 | 
			
		||||
    'DEFAULT_GROUP_NAME': webutils.DEFAULT_GROUP_NAME,
 | 
			
		||||
    'OTHER_CATEGORY': engines.OTHER_CATEGORY,
 | 
			
		||||
    'NO_SUBGROUPING': webutils.NO_SUBGROUPING,
 | 
			
		||||
    'DEFAULT_CATEGORY': engines.DEFAULT_CATEGORY,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
CATEGORY_NAMES = {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -298,18 +298,18 @@
 | 
			
		|||
    <p>{{ _('Currently used search engines') }}</p>
 | 
			
		||||
    {{ tabs_open() }}
 | 
			
		||||
     {% 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 )}}
 | 
			
		||||
     {% set ns.checked = false %}
 | 
			
		||||
   {% if categ == OTHER_CATEGORY %}
 | 
			
		||||
      <p>{{_('This tab does not show up for search results, but you can search the engines listed here via bangs.')}}</p>
 | 
			
		||||
    {% endif %}
 | 
			
		||||
     {% if categ == DEFAULT_CATEGORY %}
 | 
			
		||||
      <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 %}
 | 
			
		||||
    <div class="scrollx">
 | 
			
		||||
    <table class="striped table_engines">
 | 
			
		||||
      <tr>{{- "" -}}
 | 
			
		||||
        <th class="engine_checkbox">{{ _("Allow") }}</th>{{- "" -}}
 | 
			
		||||
        <th class="name">{{ _("Engine name") }}</th>{{- "" -}}
 | 
			
		||||
        <th class="shortcut">{{ _("Shortcut") }}</th>{{- "" -}}
 | 
			
		||||
        <th class="shortcut">{{ _("!bang") }}</th>{{- "" -}}
 | 
			
		||||
        <th>{{ _("Supports selected language") }}</th>{{- "" -}}
 | 
			
		||||
        <th>{{ _("SafeSearch") }}</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.exceptions import SearxParameterException
 | 
			
		||||
from searx.engines import (
 | 
			
		||||
    OTHER_CATEGORY,
 | 
			
		||||
    DEFAULT_CATEGORY,
 | 
			
		||||
    categories,
 | 
			
		||||
    engines,
 | 
			
		||||
    engine_shortcuts,
 | 
			
		||||
| 
						 | 
				
			
			@ -435,7 +435,7 @@ def render(template_name: str, **kwargs):
 | 
			
		|||
    kwargs['method'] = request.preferences.get_value('method')
 | 
			
		||||
    kwargs['categories_as_tabs'] = list(settings['categories_as_tabs'].keys())
 | 
			
		||||
    kwargs['categories'] = _get_enable_categories(categories.keys())
 | 
			
		||||
    kwargs['OTHER_CATEGORY'] = OTHER_CATEGORY
 | 
			
		||||
    kwargs['DEFAULT_CATEGORY'] = DEFAULT_CATEGORY
 | 
			
		||||
 | 
			
		||||
    # i18n
 | 
			
		||||
    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 searx import logger, settings
 | 
			
		||||
from searx.engines import OTHER_CATEGORY
 | 
			
		||||
from searx.engines import DEFAULT_CATEGORY
 | 
			
		||||
 | 
			
		||||
if TYPE_CHECKING:
 | 
			
		||||
    from searx.enginelib import Engine
 | 
			
		||||
| 
						 | 
				
			
			@ -222,26 +222,24 @@ def is_flask_run_cmdline():
 | 
			
		|||
    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]]]:
 | 
			
		||||
    """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):
 | 
			
		||||
        non_tab_categories = [
 | 
			
		||||
            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 DEFAULT_GROUP_NAME
 | 
			
		||||
 | 
			
		||||
    groups = itertools.groupby(sorted(engines, key=get_group), get_group)
 | 
			
		||||
    def get_subgroup(eng):
 | 
			
		||||
        non_tab_categories = [c for c in eng.categories if c not in tabs + [DEFAULT_CATEGORY]]
 | 
			
		||||
        return non_tab_categories[0] if len(non_tab_categories) > 0 else NO_SUBGROUPING
 | 
			
		||||
 | 
			
		||||
    def group_sort_key(group):
 | 
			
		||||
        return (group[0] == DEFAULT_GROUP_NAME, group[0].lower())
 | 
			
		||||
 | 
			
		||||
    sorted_groups = sorted(((name, list(engines)) for name, engines in groups), key=group_sort_key)
 | 
			
		||||
        return (group[0] == NO_SUBGROUPING, group[0].lower())
 | 
			
		||||
 | 
			
		||||
    def engine_sort_key(engine):
 | 
			
		||||
        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]
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue