summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.pylintrc2
-rw-r--r--docs/admin/installation-searx.rst2
-rw-r--r--docs/dev/makefile.rst2
-rw-r--r--searx/engines/qwant.py2
-rw-r--r--searx/engines/xpath.py1
-rw-r--r--searx/search.py24
-rwxr-xr-xsearx/webapp.py23
-rw-r--r--tests/unit/test_search.py14
-rw-r--r--tests/unit/test_standalone_searx.py3
-rw-r--r--tests/unit/test_webapp.py25
10 files changed, 76 insertions, 22 deletions
diff --git a/.pylintrc b/.pylintrc
index 3b4adb2ca..eb6d500b3 100644
--- a/.pylintrc
+++ b/.pylintrc
@@ -12,7 +12,7 @@
# A comma-separated list of package or module names from where C extensions may
# be loaded. Extensions are loading into the active Python interpreter and may
# run arbitrary code
-extension-pkg-whitelist=
+extension-pkg-whitelist=lxml.etree
# Add files or directories to the blacklist. They should be base names, not
# paths.
diff --git a/docs/admin/installation-searx.rst b/docs/admin/installation-searx.rst
index f1d486021..a368bfe8c 100644
--- a/docs/admin/installation-searx.rst
+++ b/docs/admin/installation-searx.rst
@@ -52,7 +52,7 @@ In the same shell create *virtualenv*:
:end-before: END create virtualenv
To install searx's dependencies, exit the searx *bash* session you opened above
-and restart a new. Before install, first check if your *virualenv* was sourced
+and restart a new. Before install, first check if your *virtualenv* was sourced
from the login (*~/.profile*):
.. kernel-include:: $DOCS_BUILD/includes/searx.rst
diff --git a/docs/dev/makefile.rst b/docs/dev/makefile.rst
index 62cd0a984..699729a28 100644
--- a/docs/dev/makefile.rst
+++ b/docs/dev/makefile.rst
@@ -68,7 +68,7 @@ Python environment
``source ./local/py3/bin/activate``
-With Makefile we do no longer need to build up the virualenv manually (as
+With Makefile we do no longer need to build up the virtualenv manually (as
described in the :ref:`devquickstart` guide). Jump into your git working tree
and release a ``make pyenv``:
diff --git a/searx/engines/qwant.py b/searx/engines/qwant.py
index 98460604c..c909ce11b 100644
--- a/searx/engines/qwant.py
+++ b/searx/engines/qwant.py
@@ -17,7 +17,7 @@ from searx.utils import html_to_text, match_language
# engine dependent config
-categories = None
+categories = []
paging = True
language_support = True
supported_languages_url = 'https://qwant.com/region'
diff --git a/searx/engines/xpath.py b/searx/engines/xpath.py
index 81c2747fb..a569d9160 100644
--- a/searx/engines/xpath.py
+++ b/searx/engines/xpath.py
@@ -7,6 +7,7 @@ url_xpath = None
content_xpath = None
title_xpath = None
thumbnail_xpath = False
+categories = []
paging = False
suggestion_xpath = ''
results_xpath = ''
diff --git a/searx/search.py b/searx/search.py
index 9a1ed1e4a..1cb2a603b 100644
--- a/searx/search.py
+++ b/searx/search.py
@@ -57,8 +57,11 @@ class EngineRef:
self.category = category
self.from_bang = from_bang
- def __str__(self):
- return "(" + self.name + "," + self.category + "," + str(self.from_bang) + ")"
+ def __repr__(self):
+ return "EngineRef({!r}, {!r}, {!r})".format(self.name, self.category, self.from_bang)
+
+ def __eq__(self, other):
+ return self.name == other.name and self.category == other.category and self.from_bang == other.from_bang
class SearchQuery:
@@ -87,8 +90,21 @@ class SearchQuery:
self.timeout_limit = timeout_limit
self.external_bang = external_bang
- def __str__(self):
- return self.query + ";" + str(self.engineref_list)
+ def __repr__(self):
+ return "SearchQuery({!r}, {!r}, {!r}, {!r}, {!r}, {!r}, {!r}, {!r}, {!r})".\
+ format(self.query, self.engineref_list, self.categories, self.lang, self.safesearch,
+ self.pageno, self.time_range, self.timeout_limit, self.external_bang)
+
+ def __eq__(self, other):
+ return self.query == other.query\
+ and self.engineref_list == other.engineref_list\
+ and self.categories == self.categories\
+ and self.lang == other.lang\
+ and self.safesearch == other.safesearch\
+ and self.pageno == other.pageno\
+ and self.time_range == other.time_range\
+ and self.timeout_limit == other.timeout_limit\
+ and self.external_bang == other.external_bang
def send_http_request(engine, request_params):
diff --git a/searx/webapp.py b/searx/webapp.py
index d68ae349a..326200cec 100755
--- a/searx/webapp.py
+++ b/searx/webapp.py
@@ -44,7 +44,7 @@ from urllib.parse import urlencode, urlparse, urljoin, urlsplit
from pygments import highlight
from pygments.lexers import get_lexer_by_name
-from pygments.formatters import HtmlFormatter
+from pygments.formatters import HtmlFormatter # pylint: disable=no-name-in-module
from werkzeug.middleware.proxy_fix import ProxyFix
from flask import (
@@ -111,7 +111,7 @@ app = Flask(
app.jinja_env.trim_blocks = True
app.jinja_env.lstrip_blocks = True
-app.jinja_env.add_extension('jinja2.ext.loopcontrols')
+app.jinja_env.add_extension('jinja2.ext.loopcontrols') # pylint: disable=no-member
app.secret_key = settings['server']['secret_key']
# see https://flask.palletsprojects.com/en/1.1.x/cli/
@@ -547,10 +547,12 @@ def index():
# redirect to search if there's a query in the request
if request.form.get('q'):
- return redirect(url_for('search'), 308)
+ query = ('?' + request.query_string.decode()) if request.query_string else ''
+ return redirect(url_for('search') + query, 308)
return render(
'index.html',
+ selected_categories=get_selected_categories(request.preferences, request.form),
)
@@ -566,8 +568,8 @@ def search():
if output_format not in ['html', 'csv', 'json', 'rss']:
output_format = 'html'
- # check if there is query
- if request.form.get('q') is None:
+ # check if there is query (not None and not an empty string)
+ if not request.form.get('q'):
if output_format == 'html':
return render(
'index.html',
@@ -587,15 +589,12 @@ def search():
result_container = search.search()
+ except SearxParameterException as e:
+ logger.exception('search error: SearxParameterException')
+ return index_error(output_format, e.message), 400
except Exception as e:
- # log exception
logger.exception('search error')
-
- # is it an invalid input parameter or something else ?
- if (issubclass(e.__class__, SearxParameterException)):
- return index_error(output_format, e.message), 400
- else:
- return index_error(output_format, gettext('search error')), 500
+ return index_error(output_format, gettext('search error')), 500
# results
results = result_container.get_ordered_results()
diff --git a/tests/unit/test_search.py b/tests/unit/test_search.py
index 36135913c..464a9b37d 100644
--- a/tests/unit/test_search.py
+++ b/tests/unit/test_search.py
@@ -21,6 +21,20 @@ TEST_ENGINES = [
]
+class SearchQueryTestCase(SearxTestCase):
+
+ def test_repr(self):
+ s = SearchQuery('test', [EngineRef('bing', 'general', False)], ['general'], 'all', 0, 1, '1', 5.0, 'g')
+ self.assertEqual(repr(s),
+ "SearchQuery('test', [EngineRef('bing', 'general', False)], ['general'], 'all', 0, 1, '1', 5.0, 'g')") # noqa
+
+ def test_eq(self):
+ s = SearchQuery('test', [EngineRef('bing', 'general', False)], ['general'], 'all', 0, 1, None, None, None)
+ t = SearchQuery('test', [EngineRef('google', 'general', False)], ['general'], 'all', 0, 1, None, None, None)
+ self.assertEqual(s, s)
+ self.assertNotEqual(s, t)
+
+
class SearchTestCase(SearxTestCase):
@classmethod
diff --git a/tests/unit/test_standalone_searx.py b/tests/unit/test_standalone_searx.py
index cd1a14f46..c00f033b6 100644
--- a/tests/unit/test_standalone_searx.py
+++ b/tests/unit/test_standalone_searx.py
@@ -7,6 +7,7 @@ import sys
from mock import Mock, patch
from nose2.tools import params
+from searx.search import SearchQuery
from searx.testing import SearxTestCase
@@ -91,7 +92,7 @@ class StandaloneSearx(SearxTestCase):
args = sas.parse_argument(['rain', ])
search_q = sas.get_search_query(args)
self.assertTrue(search_q)
- self.assertEqual(str(search_q), 'rain;[]')
+ self.assertEqual(search_q, SearchQuery('rain', [], ['general'], 'all', 0, 1, None, None, None))
def test_no_parsed_url(self):
"""test no_parsed_url func"""
diff --git a/tests/unit/test_webapp.py b/tests/unit/test_webapp.py
index 08a266931..75a968ad8 100644
--- a/tests/unit/test_webapp.py
+++ b/tests/unit/test_webapp.py
@@ -75,9 +75,32 @@ class ViewsTestCase(SearxTestCase):
self.assertEqual(result.status_code, 200)
self.assertIn(b'<div class="title"><h1>searx</h1></div>', result.data)
- def test_index_html(self):
+ def test_index_html_post(self):
result = self.app.post('/', data={'q': 'test'})
self.assertEqual(result.status_code, 308)
+ self.assertEqual(result.location, 'http://localhost/search')
+
+ def test_index_html_get(self):
+ result = self.app.post('/?q=test')
+ self.assertEqual(result.status_code, 308)
+ self.assertEqual(result.location, 'http://localhost/search?q=test')
+
+ def test_search_empty_html(self):
+ result = self.app.post('/search', data={'q': ''})
+ self.assertEqual(result.status_code, 200)
+ self.assertIn(b'<div class="title"><h1>searx</h1></div>', result.data)
+
+ def test_search_empty_json(self):
+ result = self.app.post('/search', data={'q': '', 'format': 'json'})
+ self.assertEqual(result.status_code, 400)
+
+ def test_search_empty_csv(self):
+ result = self.app.post('/search', data={'q': '', 'format': 'csv'})
+ self.assertEqual(result.status_code, 400)
+
+ def test_search_empty_rss(self):
+ result = self.app.post('/search', data={'q': '', 'format': 'rss'})
+ self.assertEqual(result.status_code, 400)
def test_search_html(self):
result = self.app.post('/search', data={'q': 'test'})