diff --git a/searx/query.py b/searx/query.py index aa4cb0bc9..4603a63fc 100644 --- a/searx/query.py +++ b/searx/query.py @@ -1,10 +1,10 @@ # SPDX-License-Identifier: AGPL-3.0-or-later # pylint: disable=invalid-name, missing-module-docstring, missing-class-docstring +from __future__ import annotations from __future__ import annotations from abc import abstractmethod, ABC import re - from searx import settings from searx.sxng_locales import sxng_locales from searx.engines import categories, engines, engine_shortcuts @@ -272,16 +272,19 @@ class RawTextQuery: self.specific = False self.autocomplete_list = [] # internal properties - self.query_parts = [] # use self.getFullQuery() + self.query_parts = [] # use self.getFullQuery() or self.getNewFullQuery(query) self.user_query_parts = [] # use self.getQuery() - self.autocomplete_location = None self.redirect_to_first_result = False - self._parse_query() + self.autocomplete_location = self._parse_query() def _parse_query(self): """ parse self.query, if tags are set, which change the search engine or search-language + + Returns a tuple: + [0] The query parts as a list + [1] The indexor into the above list """ # split query, including whitespaces @@ -307,28 +310,33 @@ class RawTextQuery: qlist.append(query_part) last_index_location = (qlist, len(qlist) - 1) - self.autocomplete_location = last_index_location + return last_index_location - def get_autocomplete_full_query(self, text): + def get_autocomplete_full_query(self, text: str) -> str: + assert self.autocomplete_location is not None qlist, position = self.autocomplete_location qlist[position] = text return self.getFullQuery() - def changeQuery(self, query): - self.user_query_parts = query.strip().split() - self.query = self.getFullQuery() - self.autocomplete_location = (self.user_query_parts, len(self.user_query_parts) - 1) - self.autocomplete_list = [] - return self + def getNewFullQuery(self, query: str): + """ + Generate a new FullQuery based on the input query rather than the internal + user_query_parts + """ + return RawTextQuery._getFullQuery(self.query_parts, query.strip()) - def getQuery(self): + def getQuery(self) -> str: return ' '.join(self.user_query_parts) - def getFullQuery(self): + def getFullQuery(self) -> str: """ - get full query including whitespaces + Get full query including whitespaces """ - return '{0} {1}'.format(' '.join(self.query_parts), self.getQuery()).strip() + return RawTextQuery._getFullQuery(self.query_parts, self.getQuery()) + + @staticmethod + def _getFullQuery(query_parts: list[str], query: str) -> str: + return '{0} {1}'.format(' '.join(query_parts), query).strip() def __str__(self): return self.getFullQuery() diff --git a/searx/search/processors/abstract.py b/searx/search/processors/abstract.py index f89302a92..dc247721a 100644 --- a/searx/search/processors/abstract.py +++ b/searx/search/processors/abstract.py @@ -144,6 +144,7 @@ class EngineProcessor(ABC): - A page-number > 1 when engine does not support paging. - A time range when the engine does not support time range. """ + # if paging is not supported, skip if search_query.pageno > 1 and not self.engine.paging: return None diff --git a/searx/webapp.py b/searx/webapp.py index d2d486d20..43d45e13b 100755 --- a/searx/webapp.py +++ b/searx/webapp.py @@ -753,14 +753,14 @@ def search(): # suggestions: use RawTextQuery to get the suggestion URLs with the same bang suggestion_urls = list( map( - lambda suggestion: {'url': raw_text_query.changeQuery(suggestion).getFullQuery(), 'title': suggestion}, + lambda suggestion: {'url': raw_text_query.getNewFullQuery(suggestion), 'title': suggestion}, result_container.suggestions, ) ) correction_urls = list( map( - lambda correction: {'url': raw_text_query.changeQuery(correction).getFullQuery(), 'title': correction}, + lambda correction: {'url': raw_text_query.getNewFullQuery(correction), 'title': correction}, result_container.corrections, ) ) @@ -851,10 +851,8 @@ def autocompleter(): backend_name = request.preferences.get_value('autocomplete') for result in search_autocomplete(backend_name, sug_prefix, sxng_locale): - # attention: this loop will change raw_text_query object and this is - # the reason why the sug_prefix was stored before (see above) if result != sug_prefix: - results.append(raw_text_query.changeQuery(result).getFullQuery()) + results.append(raw_text_query.getNewFullQuery(result)) if len(raw_text_query.autocomplete_list) > 0: for autocomplete_text in raw_text_query.autocomplete_list: diff --git a/tests/unit/test_query.py b/tests/unit/test_query.py index 601a6e60d..e1595c14a 100644 --- a/tests/unit/test_query.py +++ b/tests/unit/test_query.py @@ -51,12 +51,19 @@ class TestQuery(SearxTestCase): # pylint:disable=missing-class-docstring r = repr(query) self.assertTrue(r.startswith(f"