From 476a3811d451388901799eed5cec70eb5974c504 Mon Sep 17 00:00:00 2001 From: Grant Lanham Date: Sat, 15 Jun 2024 22:43:45 -0400 Subject: [PATCH] Remove changeQuery in favor of an immutable FullQuery Also includes the following: - Introduce typing in RawTextQuery - Remove an outdated description based on the change - Refactor setting the autocomplete_location, its more clear to set the variable in the construct instead of within the method - Update unit tests to reflect updated functionality --- searx/query.py | 37 ++++++++++++++--------------- searx/search/processors/abstract.py | 1 + searx/webapp.py | 8 +++---- tests/unit/test_query.py | 15 ++++++++---- 4 files changed, 33 insertions(+), 28 deletions(-) diff --git a/searx/query.py b/searx/query.py index aa4cb0bc9..ec1e72424 100644 --- a/searx/query.py +++ b/searx/query.py @@ -1,10 +1,9 @@ # SPDX-License-Identifier: AGPL-3.0-or-later # pylint: disable=invalid-name, missing-module-docstring, missing-class-docstring - 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 @@ -274,14 +273,17 @@ class RawTextQuery: # internal properties self.query_parts = [] # use self.getFullQuery() 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 +309,25 @@ 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 getQuery(self): + def getQuery(self) -> str: return ' '.join(self.user_query_parts) - def getFullQuery(self): - """ - get full query including whitespaces - """ - return '{0} {1}'.format(' '.join(self.query_parts), self.getQuery()).strip() + def getFullQuery(self, new_query: str | None = None): + def format_query(query: str) -> str: + return '{0} {1}'.format(' '.join(self.query_parts), query).strip() + + if new_query is None: + return format_query(self.getQuery()) + + return format_query(new_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 19c477794..c4fc0814e 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.getFullQuery(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.getFullQuery(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..bf90e3a0d 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"