diff --git a/searx/static/css/style.css b/searx/static/css/style.css
index a98a7af1a..a5ced9266 100644
--- a/searx/static/css/style.css
+++ b/searx/static/css/style.css
@@ -49,7 +49,7 @@ input[type="submit"] { padding: 2px 6px; margin: 2px 4px; display: inline-block;
input[type="checkbox"] { visibility: hidden; }
-fieldset { margin: 8px; }
+fieldset { margin: 8px; border: 1px solid #3498DB; }
#categories { margin: 0 10px; }
@@ -57,7 +57,7 @@ fieldset { margin: 8px; }
.checkbox_container input {
display: none;
}
-.checkbox_container label {
+.checkbox_container label, .engine_checkbox label {
cursor: pointer;
padding: 4px 10px;
margin: 0;
@@ -77,6 +77,12 @@ fieldset { margin: 8px; }
.search .checkbox_container label:hover { border-bottom: 4px solid #3498DB; }
.search .checkbox_container input[type="checkbox"]:checked + label { border-bottom: 4px solid #2980B9; }
+.engine_checkbox { padding: 4px; }
+label.allow { background: #E74C3C; color: #FFFFFF; padding: 4px 8px; display: none; }
+label.deny { background: #2ECC71; padding: 4px 8px; display: inline; }
+.engine_checkbox input[type="checkbox"]:checked + label:nth-child(2) + label { display: none; }
+.engine_checkbox input[type="checkbox"]:checked + label.allow { display: inline; }
+
a { text-decoration: none; color: #1a11be; }
a:visited { color: #7b11be; }
@@ -116,8 +122,9 @@ a:visited { color: #7b11be; }
.percentage { position: relative; width: 300px; }
.percentage div { background: #444444; }
-td { padding: 0 4px; }
-tr:hover td { background: #DDDDDD; }
+table { width: 100%; }
+td { padding: 0 4px; }
+tr:hover { background: #DDDDDD; }
#search_wrapper { position: relative; max-width: 600px; padding: 10px; }
.center #search_wrapper { margin-left: auto; margin-right: auto; }
diff --git a/searx/templates/engines.html b/searx/templates/engines.html
deleted file mode 100644
index 613023a83..000000000
--- a/searx/templates/engines.html
+++ /dev/null
@@ -1,27 +0,0 @@
-{% extends 'base.html' %}
-{% block content %}
-
-
{{ _('Currently used search engines') }}
-
-
-
- {{ _('Engine name') }}
- {{ _('Shortcut') }}
- {{ _('Category') }}
-
- {% for (categ,search_engines) in categs %}
- {% for search_engine in search_engines %}
-
- {% if not search_engine.private %}
-
- {{ search_engine.name }}
- {{ shortcuts[search_engine.name] }}
- {{ _(categ) }}
-
- {% endif %}
- {% endfor %}
- {% endfor %}
-
-
{{ _('back') }}
-
-{% endblock %}
diff --git a/searx/templates/preferences.html b/searx/templates/preferences.html
index 249cebe63..e5ef2718b 100644
--- a/searx/templates/preferences.html
+++ b/searx/templates/preferences.html
@@ -32,6 +32,35 @@
+
+ {{ _('Currently used search engines') }}
+
+
+
{{ _('These settings are stored in your cookies, this allows us not to store this data about you.') }}
{{ _("These cookies serve your sole convenience, we don't use these cookies to track you.") }}
diff --git a/searx/tests/test_webapp.py b/searx/tests/test_webapp.py
index 4e2c820d9..284dc3c75 100644
--- a/searx/tests/test_webapp.py
+++ b/searx/tests/test_webapp.py
@@ -124,11 +124,6 @@ class ViewsTestCase(SearxTestCase):
self.assertEqual(result.status_code, 200)
self.assertIn('
', result.data)
- def test_engines(self):
- result = self.app.get('/engines')
- self.assertEqual(result.status_code, 200)
- self.assertIn('Currently used search engines ', result.data)
-
def test_preferences(self):
result = self.app.get('/preferences')
self.assertEqual(result.status_code, 200)
diff --git a/searx/webapp.py b/searx/webapp.py
index 4f0fe92b3..80b5e4135 100644
--- a/searx/webapp.py
+++ b/searx/webapp.py
@@ -242,17 +242,6 @@ def about():
return render('about.html')
-@app.route('/engines', methods=['GET'])
-def list_engines():
- """Render engines page.
-
- List of all supported engines.
- """
- return render('engines.html',
- categs=categories.items(),
- shortcuts={y: x for x, y in engine_shortcuts.items()})
-
-
@app.route('/preferences', methods=['GET', 'POST'])
def preferences():
"""Render preferences page.
@@ -264,7 +253,11 @@ def preferences():
and request.cookies['language'] in (x[0] for x in language_codes):
lang = request.cookies['language']
- if request.method == 'POST':
+ blocked_engines = []
+
+ if request.method == 'GET':
+ blocked_engines = request.cookies.get('blocked_engines', '').split(',')
+ else:
selected_categories = []
locale = None
for pd_name, pd in request.form.items():
@@ -278,10 +271,24 @@ def preferences():
elif pd_name == 'language' and (pd == 'all' or
pd in (x[0] for
x in language_codes)):
+ locale = pd
lang = pd
+ elif pd_name.startswith('engine_'):
+ engine_name = pd_name.replace('engine_', '', 1)
+ if engine_name in engines:
+ blocked_engines.append(engine_name)
resp = make_response(redirect('/'))
+ user_blocked_engines = request.cookies.get('blocked_engines', '').split(',') # noqa
+
+ if sorted(blocked_engines) != sorted(user_blocked_engines):
+ # cookie max age: 4 weeks
+ resp.set_cookie(
+ 'blocked_engines', ','.join(blocked_engines),
+ max_age=60 * 60 * 24 * 7 * 4
+ )
+
if locale:
# cookie max age: 4 weeks
resp.set_cookie(
@@ -307,7 +314,10 @@ def preferences():
locales=settings['locales'],
current_locale=get_locale(),
current_language=lang or 'all',
- language_codes=language_codes)
+ language_codes=language_codes,
+ categs=categories.items(),
+ blocked_engines=blocked_engines,
+ shortcuts={y: x for x, y in engine_shortcuts.items()})
@app.route('/stats', methods=['GET'])