@@ -40,7 +40,7 @@ except:
40 logger.critical("cannot import dependency: pygments")
40 logger.critical("cannot import dependency: pygments")
41 from sys import exit
41 from sys import exit
43−
43+from cgi import escape
44from datetime import datetime, timedelta
44from datetime import datetime, timedelta
45from urllib import urlencode
45from urllib import urlencode
46from urlparse import urlparse, urljoin
46from urlparse import urlparse, urljoin
@@ -62,11 +62,12 @@ from searx.utils import (
63from searx.version import VERSION_STRING
63from searx.version import VERSION_STRING
64from searx.languages import language_codes
64from searx.languages import language_codes
65−from searx.search import Search, SearchWithPlugins, get_search_query_from_webapp
65+from searx.search import SearchWithPlugins, get_search_query_from_webapp
66−from searx.query import RawTextQuery, SearchQuery
66+from searx.query import RawTextQuery
67from searx.autocomplete import searx_bang, backends as autocomplete_backends
67from searx.autocomplete import searx_bang, backends as autocomplete_backends
68from searx.plugins import plugins
68from searx.plugins import plugins
69from searx.preferences import Preferences, ValidationException
69from searx.preferences import Preferences, ValidationException
70+from searx.answerers import answerers
71# check if the pyopenssl, ndg-httpsclient, pyasn1 packages are installed.
72# check if the pyopenssl, ndg-httpsclient, pyasn1 packages are installed.
72# They are needed for SSL connection without trouble, see #298
73# They are needed for SSL connection without trouble, see #298
@@ -344,6 +345,8 @@ def render(template_name, override_theme=None, **kwargs):
345 kwargs['cookies'] = request.cookies
346 kwargs['cookies'] = request.cookies
348+ kwargs['errors'] = request.errors
347 kwargs['instance_name'] = settings['general']['instance_name']
350 kwargs['instance_name'] = settings['general']['instance_name']
349 kwargs['results_on_new_tab'] = request.preferences.get_value('results_on_new_tab')
352 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):
365@app.before_request
368@app.before_request
366def pre_request():
369def pre_request():
367− # merge GET, POST vars
370+ request.errors = []
368 preferences = Preferences(themes, categories.keys(), engines, plugins)
372 preferences = Preferences(themes, categories.keys(), engines, plugins)
373+ request.preferences = preferences
370 preferences.parse_cookies(request.cookies)
375 preferences.parse_cookies(request.cookies)
372− # TODO throw error message to the user
377+ request.errors.append(gettext('Invalid settings, please edit your preferences'))
373− logger.warning('Invalid config')
374− request.preferences = preferences
379+ # merge GET, POST vars
376 # request.form
380 # request.form
377 request.form = dict(request.form.items())
381 request.form = dict(request.form.items())
378 for k, v in request.args.items():
382 for k, v in request.args.items():
@@ -397,7 +401,7 @@ def index():
397 Supported outputs: html, json, csv, rss.
401 Supported outputs: html, json, csv, rss.
400− if not request.args and not request.form:
404+ if request.form.get('q') is None:
401 return render(
405 return render(
402 'index.html',
406 'index.html',
@@ -411,6 +415,8 @@ def index():
411 search = SearchWithPlugins(search_query, request)
415 search = SearchWithPlugins(search_query, request)
412 result_container = search.search()
416 result_container = search.search()
418+ request.errors.append(gettext('search error'))
419+ logger.exception('search error')
414 return render(
420 return render(
415 'index.html',
421 'index.html',
@@ -427,8 +433,10 @@ def index():
427 for result in results:
433 for result in results:
428 if output_format == 'html':
434 if output_format == 'html':
429 if 'content' in result and result['content']:
435 if 'content' in result and result['content']:
430− result['content'] = highlight_content(result['content'][:1024], search_query.query.encode('utf-8'))
436+ result['content'] = highlight_content(escape(result['content'][:1024]),
437+ search_query.query.encode('utf-8'))
431− result['title'] = highlight_content(result['title'], search_query.query.encode('utf-8'))
438+ result['title'] = highlight_content(escape(result['title'] or u''),
439+ search_query.query.encode('utf-8'))
433 if result.get('content'):
441 if result.get('content'):
434 result['content'] = html_to_text(result['content']).strip()
442 result['content'] = html_to_text(result['content']).strip()
@@ -572,7 +580,7 @@ def preferences():
573 request.preferences.parse_form(request.form)
581 request.preferences.parse_form(request.form)
574 except ValidationException:
582 except ValidationException:
575− # TODO use flash feature of flask
583+ request.errors.append(gettext('Invalid settings, please edit your preferences'))
576 return resp
584 return resp
577 return request.preferences.save(resp)
585 return request.preferences.save(resp)
@@ -609,6 +617,7 @@ def preferences():
609 language_codes=language_codes,
617 language_codes=language_codes,
610 engines_by_category=categories,
618 engines_by_category=categories,
611 stats=stats,
619 stats=stats,
620+ answerers=[{'info': a.self_info(), 'keywords': a.keywords} for a in answerers],
612 disabled_engines=disabled_engines,
621 disabled_engines=disabled_engines,
613 autocomplete_backends=autocomplete_backends,
622 autocomplete_backends=autocomplete_backends,
614 shortcuts={y: x for x, y in engine_shortcuts.items()},
623 shortcuts={y: x for x, y in engine_shortcuts.items()},