@@ -40,7 +40,7 @@ except:
4040 logger.critical("cannot import dependency: pygments")
4141 from sys import exit
4242 exit(1)
43−
43+from cgi import escape
4444from datetime import datetime, timedelta
4545from urllib import urlencode
4646from urlparse import urlparse, urljoin
@@ -62,11 +62,12 @@ from searx.utils import (
6262)
6363from searx.version import VERSION_STRING
6464from searx.languages import language_codes
65−from searx.search import Search, SearchWithPlugins, get_search_query_from_webapp
66−from searx.query import RawTextQuery, SearchQuery
65+from searx.search import SearchWithPlugins, get_search_query_from_webapp
66+from searx.query import RawTextQuery
6767from searx.autocomplete import searx_bang, backends as autocomplete_backends
6868from searx.plugins import plugins
6969from searx.preferences import Preferences, ValidationException
70+from searx.answerers import answerers
7071
7172# check if the pyopenssl, ndg-httpsclient, pyasn1 packages are installed.
7273# They are needed for SSL connection without trouble, see #298
@@ -344,6 +345,8 @@ def render(template_name, override_theme=None, **kwargs):
344345
345346 kwargs['cookies'] = request.cookies
346347
348+ kwargs['errors'] = request.errors
349+
347350 kwargs['instance_name'] = settings['general']['instance_name']
348351
349352 kwargs['results_on_new_tab'] = request.preferences.get_value('results_on_new_tab')
@@ -364,15 +367,16 @@ def render(template_name, override_theme=None, **kwargs):
364367
365368@app.before_request
366369def pre_request():
367− # merge GET, POST vars
370+ request.errors = []
371+
368372 preferences = Preferences(themes, categories.keys(), engines, plugins)
373+ request.preferences = preferences
369374 try:
370375 preferences.parse_cookies(request.cookies)
371376 except:
372− # TODO throw error message to the user
373− logger.warning('Invalid config')
374− request.preferences = preferences
377+ request.errors.append(gettext('Invalid settings, please edit your preferences'))
375378
379+ # merge GET, POST vars
376380 # request.form
377381 request.form = dict(request.form.items())
378382 for k, v in request.args.items():
@@ -397,7 +401,7 @@ def index():
397401 Supported outputs: html, json, csv, rss.
398402 """
399403
400− if not request.args and not request.form:
404+ if request.form.get('q') is None:
401405 return render(
402406 'index.html',
403407 )
@@ -411,6 +415,8 @@ def index():
411415 search = SearchWithPlugins(search_query, request)
412416 result_container = search.search()
413417 except:
418+ request.errors.append(gettext('search error'))
419+ logger.exception('search error')
414420 return render(
415421 'index.html',
416422 )
@@ -427,8 +433,10 @@ def index():
427433 for result in results:
428434 if output_format == 'html':
429435 if 'content' in result and result['content']:
430− result['content'] = highlight_content(result['content'][:1024], search_query.query.encode('utf-8'))
431− result['title'] = highlight_content(result['title'], search_query.query.encode('utf-8'))
436+ result['content'] = highlight_content(escape(result['content'][:1024]),
437+ search_query.query.encode('utf-8'))
438+ result['title'] = highlight_content(escape(result['title'] or u''),
439+ search_query.query.encode('utf-8'))
432440 else:
433441 if result.get('content'):
434442 result['content'] = html_to_text(result['content']).strip()
@@ -572,7 +580,7 @@ def preferences():
572580 try:
573581 request.preferences.parse_form(request.form)
574582 except ValidationException:
575− # TODO use flash feature of flask
583+ request.errors.append(gettext('Invalid settings, please edit your preferences'))
576584 return resp
577585 return request.preferences.save(resp)
578586
@@ -609,6 +617,7 @@ def preferences():
609617 language_codes=language_codes,
610618 engines_by_category=categories,
611619 stats=stats,
620+ answerers=[{'info': a.self_info(), 'keywords': a.keywords} for a in answerers],
612621 disabled_engines=disabled_engines,
613622 autocomplete_backends=autocomplete_backends,
614623 shortcuts={y: x for x, y in engine_shortcuts.items()},