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