logo

searx

Unnamed repository; edit this file 'description' to name the repository.
commit: 41dd4d9ba3429b387bf32a65ce4b1bfe4f82444c
parent: 20504a0e834a99fb1274ad907c0b62fb90eb96d3
Author: Adam Tauber <asciimoo@gmail.com>
Date:   Sat, 29 Mar 2014 16:29:19 +0100

[enh] autocompleter server side part

Diffstat:

searx/settings.yml | 3---
searx/static/js/searx.js | 2+-
searx/templates/base.html | 4++--
searx/templates/preferences.html | 15+++++++++++++--
searx/webapp.py | 73+++++++++++++++++++++++++++++++++++++++++++++++++++++--------------------
5 files changed, 69 insertions(+), 28 deletions(-)

diff --git a/searx/settings.yml b/searx/settings.yml @@ -5,9 +5,6 @@ server: request_timeout : 2.0 # seconds base_url : False -client: - autocompleter : False # only for developers, no real results yet - engines: - name : wikipedia engine : wikipedia diff --git a/searx/static/js/searx.js b/searx/static/js/searx.js @@ -9,7 +9,7 @@ if(searx.autocompleter) { timeout: 5 // Correct option? }, 'minLength': 4, - 'selectMode': 'type-ahead', + // 'selectMode': 'type-ahead', cache: true, delay: 300 }); diff --git a/searx/templates/base.html b/searx/templates/base.html @@ -15,14 +15,14 @@ {% endblock %} <script type="text/javascript"> searx = {}; - searx.autocompleter = {% if client.autocompleter %}true{% else %}false{% endif %}; + searx.autocompleter = {% if autocomplete %}true{% else %}false{% endif %}; </script> </head> <body> <div id="container"> {% block content %} {% endblock %} -{% if client.autocompleter %} +{% if autocomplete %} <script src="{{ url_for('static', filename='js/mootools-core-1.4.5-min.js') }}" ></script> <script src="{{ url_for('static', filename='js/mootools-autocompleter-1.1.2-min.js') }}" ></script> {% endif %} diff --git a/searx/templates/preferences.html b/searx/templates/preferences.html @@ -17,7 +17,7 @@ <select name='language'> <option value="all" {% if current_language == 'all' %}selected="selected"{% endif %}>{{ _('Automatic') }}</option> {% for lang_id,lang_name,country_name in language_codes %} - <option value={{ lang_id }} {% if lang_id == current_language %}selected="selected"{% endif %}>{{ lang_name}} ({{ country_name }}) - {{ lang_id }}</option> + <option value="{{ lang_id }}" {% if lang_id == current_language %}selected="selected"{% endif %}>{{ lang_name }} ({{ country_name }}) - {{ lang_id }}</option> {% endfor %} </select> </p> @@ -27,7 +27,18 @@ <p> <select name='locale'> {% for locale_id,locale_name in locales.items() %} - <option value={{ locale_id }} {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name}}</option> + <option value="{{ locale_id }}" {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name }}</option> + {% endfor %} + </select> + </p> + </fieldset> + <fieldset> + <legend>{{ _('Autocomplete') }}</legend> + <p> + <select name="autocomplete"> + <option value=""> - </option> + {% for backend in autocomplete_backends %} + <option value="{{ backend }}" {% if backend == autocomplete %}selected="selected"{% endif %}>{{ backend }}</option> {% endfor %} </select> </p> diff --git a/searx/webapp.py b/searx/webapp.py @@ -41,6 +41,7 @@ from searx.engines import ( from searx.utils import UnicodeWriter, highlight_content, html_to_text from searx.languages import language_codes from searx.search import Search +from searx.autocomplete import backends as autocomplete_backends app = Flask( @@ -91,16 +92,25 @@ def get_base_url(): def render(template_name, **kwargs): blocked_engines = request.cookies.get('blocked_engines', '').split(',') + + autocomplete = request.cookies.get('autocomplete') + + if autocomplete not in autocomplete_backends: + autocomplete = None + nonblocked_categories = (engines[e].categories for e in engines if e not in blocked_engines) + nonblocked_categories = set(chain.from_iterable(nonblocked_categories)) + if not 'categories' in kwargs: kwargs['categories'] = ['general'] kwargs['categories'].extend(x for x in sorted(categories.keys()) if x != 'general' and x in nonblocked_categories) + if not 'selected_categories' in kwargs: kwargs['selected_categories'] = [] cookie_categories = request.cookies.get('categories', '').split(',') @@ -109,6 +119,10 @@ def render(template_name, **kwargs): kwargs['selected_categories'].append(ccateg) if not kwargs['selected_categories']: kwargs['selected_categories'] = ['general'] + + if not 'autocomplete' in kwargs: + kwargs['autocomplete'] = autocomplete + return render_template(template_name, **kwargs) @@ -122,7 +136,6 @@ def index(): if not request.args and not request.form: return render( 'index.html', - client=settings.get('client', None) ) try: @@ -130,7 +143,6 @@ def index(): except: return render( 'index.html', - client=settings.get('client', None) ) # TODO moar refactor - do_search integration into Search class @@ -212,7 +224,6 @@ def index(): return render( 'results.html', results=search.results, - client=settings.get('client', None), q=search.request_data['q'], selected_categories=search.categories, paging=search.paging, @@ -227,7 +238,6 @@ def about(): """Render about page""" return render( 'about.html', - client=settings.get('client', None) ) @@ -235,27 +245,35 @@ def about(): def autocompleter(): """Return autocompleter results""" request_data = {} - + if request.method == 'POST': request_data = request.form else: request_data = request.args - + # TODO fix XSS-vulnerability - autocompleter.querry = request_data.get('q') - autocompleter.results = [] - - if settings['client']['autocompleter']: - #TODO remove test code and add real autocompletion - if autocompleter.querry: - autocompleter.results = [autocompleter.querry + " result-1",autocompleter.querry + " result-2",autocompleter.querry + " result-3",autocompleter.querry + " result-4"] - + query = request_data.get('q') + + if not query: + return + + completer = autocomplete_backends.get(request.cookies.get('autocomplete')) + + if not completer: + return + + try: + results = completer(query) + except Exception, e: + print e + results = [] + if request_data.get('format') == 'x-suggestions': - return Response(json.dumps([autocompleter.querry,autocompleter.results]), - mimetype='application/json') + return Response(json.dumps([query, results]), + mimetype='application/json') else: - return Response(json.dumps(autocompleter.results), - mimetype='application/json') + return Response(json.dumps(results), + mimetype='application/json') @app.route('/preferences', methods=['GET', 'POST']) @@ -276,6 +294,7 @@ def preferences(): else: selected_categories = [] locale = None + autocomplete = '' for pd_name, pd in request.form.items(): if pd_name.startswith('category_'): category = pd_name[9:] @@ -284,6 +303,8 @@ def preferences(): selected_categories.append(category) elif pd_name == 'locale' and pd in settings['locales']: locale = pd + elif pd_name == 'autocomplete': + autocomplete = pd elif pd_name == 'language' and (pd == 'all' or pd in (x[0] for x in language_codes)): @@ -319,8 +340,14 @@ def preferences(): # cookie max age: 4 weeks resp.set_cookie( 'categories', ','.join(selected_categories), - max_age=60 * 60 * 24 * 7 * 4 + max_age=cookie_max_age ) + + resp.set_cookie( + 'autocomplete', autocomplete, + max_age=cookie_max_age + ) + return resp return render('preferences.html', client=settings.get('client', None), @@ -330,6 +357,7 @@ def preferences(): language_codes=language_codes, categs=categories.items(), blocked_engines=blocked_engines, + autocomplete_backends=autocomplete_backends, shortcuts={y: x for x, y in engine_shortcuts.items()}) @@ -361,7 +389,12 @@ def opensearch(): # chrome/chromium only supports HTTP GET.... if request.headers.get('User-Agent', '').lower().find('webkit') >= 0: method = 'get' - ret = render('opensearch.xml', method=method, host=get_base_url(),client=settings['client']) + + ret = render('opensearch.xml', + method=method, + host=get_base_url(), + client=settings['client']) + resp = Response(response=ret, status=200, mimetype="application/xml")