Bläddra i källkod

[enh] autocompleter server side part

Adam Tauber 11 år sedan
förälder
incheckning
41dd4d9ba3
5 ändrade filer med 69 tillägg och 28 borttagningar
  1. 0
    3
      searx/settings.yml
  2. 1
    1
      searx/static/js/searx.js
  3. 2
    2
      searx/templates/base.html
  4. 13
    2
      searx/templates/preferences.html
  5. 53
    20
      searx/webapp.py

+ 0
- 3
searx/settings.yml Visa fil

@@ -5,9 +5,6 @@ server:
5 5
     request_timeout : 2.0 # seconds
6 6
     base_url : False
7 7
 
8
-client:
9
-    autocompleter : False # only for developers, no real results yet
10
-    
11 8
 engines:
12 9
   - name : wikipedia
13 10
     engine : wikipedia

+ 1
- 1
searx/static/js/searx.js Visa fil

@@ -9,7 +9,7 @@ if(searx.autocompleter) {
9 9
 		        timeout: 5   // Correct option?
10 10
 		    },
11 11
 		    'minLength': 4,
12
-		    'selectMode': 'type-ahead',
12
+		    // 'selectMode': 'type-ahead',
13 13
 		    cache: true,
14 14
 		    delay: 300
15 15
 	    });

+ 2
- 2
searx/templates/base.html Visa fil

@@ -15,14 +15,14 @@
15 15
     {% endblock %}
16 16
     <script type="text/javascript">
17 17
         searx = {};
18
-        searx.autocompleter = {% if client.autocompleter %}true{% else %}false{% endif %};
18
+        searx.autocompleter = {% if autocomplete %}true{% else %}false{% endif %};
19 19
     </script>
20 20
 </head>
21 21
 <body>
22 22
 <div id="container">
23 23
 {% block content %}
24 24
 {% endblock %}
25
-{% if client.autocompleter %}
25
+{% if autocomplete %}
26 26
 <script src="{{ url_for('static', filename='js/mootools-core-1.4.5-min.js') }}" ></script>
27 27
 <script src="{{ url_for('static', filename='js/mootools-autocompleter-1.1.2-min.js') }}" ></script>
28 28
 {% endif %}

+ 13
- 2
searx/templates/preferences.html Visa fil

@@ -17,7 +17,7 @@
17 17
         <select name='language'>
18 18
             <option value="all" {% if current_language == 'all' %}selected="selected"{% endif %}>{{ _('Automatic') }}</option>
19 19
             {% for lang_id,lang_name,country_name in language_codes %}
20
-            <option value={{ lang_id }} {% if lang_id == current_language %}selected="selected"{% endif %}>{{ lang_name}} ({{ country_name }}) - {{ lang_id }}</option>
20
+            <option value="{{ lang_id }}" {% if lang_id == current_language %}selected="selected"{% endif %}>{{ lang_name }} ({{ country_name }}) - {{ lang_id }}</option>
21 21
             {% endfor %}
22 22
         </select>
23 23
         </p>
@@ -27,7 +27,18 @@
27 27
         <p>
28 28
         <select name='locale'>
29 29
             {% for locale_id,locale_name in locales.items() %}
30
-            <option value={{ locale_id }} {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name}}</option>
30
+            <option value="{{ locale_id }}" {% if locale_id == current_locale %}selected="selected"{% endif %}>{{ locale_name }}</option>
31
+            {% endfor %}
32
+        </select>
33
+        </p>
34
+    </fieldset>
35
+    <fieldset>
36
+        <legend>{{ _('Autocomplete') }}</legend>
37
+        <p>
38
+        <select name="autocomplete">
39
+            <option value=""> - </option>
40
+            {% for backend in autocomplete_backends %}
41
+            <option value="{{ backend }}" {% if backend == autocomplete %}selected="selected"{% endif %}>{{ backend }}</option>
31 42
             {% endfor %}
32 43
         </select>
33 44
         </p>

+ 53
- 20
searx/webapp.py Visa fil

@@ -41,6 +41,7 @@ from searx.engines import (
41 41
 from searx.utils import UnicodeWriter, highlight_content, html_to_text
42 42
 from searx.languages import language_codes
43 43
 from searx.search import Search
44
+from searx.autocomplete import backends as autocomplete_backends
44 45
 
45 46
 
46 47
 app = Flask(
@@ -91,16 +92,25 @@ def get_base_url():
91 92
 
92 93
 def render(template_name, **kwargs):
93 94
     blocked_engines = request.cookies.get('blocked_engines', '').split(',')
95
+
96
+    autocomplete = request.cookies.get('autocomplete')
97
+
98
+    if autocomplete not in autocomplete_backends:
99
+        autocomplete = None
100
+
94 101
     nonblocked_categories = (engines[e].categories
95 102
                              for e in engines
96 103
                              if e not in blocked_engines)
104
+
97 105
     nonblocked_categories = set(chain.from_iterable(nonblocked_categories))
106
+
98 107
     if not 'categories' in kwargs:
99 108
         kwargs['categories'] = ['general']
100 109
         kwargs['categories'].extend(x for x in
101 110
                                     sorted(categories.keys())
102 111
                                     if x != 'general'
103 112
                                     and x in nonblocked_categories)
113
+
104 114
     if not 'selected_categories' in kwargs:
105 115
         kwargs['selected_categories'] = []
106 116
         cookie_categories = request.cookies.get('categories', '').split(',')
@@ -109,6 +119,10 @@ def render(template_name, **kwargs):
109 119
                 kwargs['selected_categories'].append(ccateg)
110 120
         if not kwargs['selected_categories']:
111 121
             kwargs['selected_categories'] = ['general']
122
+
123
+    if not 'autocomplete' in kwargs:
124
+        kwargs['autocomplete'] = autocomplete
125
+
112 126
     return render_template(template_name, **kwargs)
113 127
 
114 128
 
@@ -122,7 +136,6 @@ def index():
122 136
     if not request.args and not request.form:
123 137
         return render(
124 138
             'index.html',
125
-            client=settings.get('client', None)
126 139
         )
127 140
 
128 141
     try:
@@ -130,7 +143,6 @@ def index():
130 143
     except:
131 144
         return render(
132 145
             'index.html',
133
-            client=settings.get('client', None)
134 146
         )
135 147
 
136 148
     # TODO moar refactor - do_search integration into Search class
@@ -212,7 +224,6 @@ def index():
212 224
     return render(
213 225
         'results.html',
214 226
         results=search.results,
215
-        client=settings.get('client', None),
216 227
         q=search.request_data['q'],
217 228
         selected_categories=search.categories,
218 229
         paging=search.paging,
@@ -227,7 +238,6 @@ def about():
227 238
     """Render about page"""
228 239
     return render(
229 240
         'about.html',
230
-        client=settings.get('client', None)
231 241
     )
232 242
 
233 243
 
@@ -235,27 +245,35 @@ def about():
235 245
 def autocompleter():
236 246
     """Return autocompleter results"""
237 247
     request_data = {}
238
-    
248
+
239 249
     if request.method == 'POST':
240 250
         request_data = request.form
241 251
     else:
242 252
         request_data = request.args
243
-    
253
+
244 254
     # TODO fix XSS-vulnerability
245
-    autocompleter.querry = request_data.get('q')
246
-    autocompleter.results = []
247
-    
248
-    if settings['client']['autocompleter']:
249
-        #TODO remove test code and add real autocompletion
250
-        if autocompleter.querry:
251
-            autocompleter.results = [autocompleter.querry + " result-1",autocompleter.querry + " result-2",autocompleter.querry + " result-3",autocompleter.querry + " result-4"]
252
-    
255
+    query = request_data.get('q')
256
+
257
+    if not query:
258
+        return
259
+
260
+    completer = autocomplete_backends.get(request.cookies.get('autocomplete'))
261
+
262
+    if not completer:
263
+        return
264
+
265
+    try:
266
+        results = completer(query)
267
+    except Exception, e:
268
+        print e
269
+        results = []
270
+
253 271
     if request_data.get('format') == 'x-suggestions':
254
-        return Response(json.dumps([autocompleter.querry,autocompleter.results]),
255
-                                   mimetype='application/json')
272
+        return Response(json.dumps([query, results]),
273
+                        mimetype='application/json')
256 274
     else:
257
-        return Response(json.dumps(autocompleter.results),
258
-                                   mimetype='application/json')
275
+        return Response(json.dumps(results),
276
+                        mimetype='application/json')
259 277
 
260 278
 
261 279
 @app.route('/preferences', methods=['GET', 'POST'])
@@ -276,6 +294,7 @@ def preferences():
276 294
     else:
277 295
         selected_categories = []
278 296
         locale = None
297
+        autocomplete = ''
279 298
         for pd_name, pd in request.form.items():
280 299
             if pd_name.startswith('category_'):
281 300
                 category = pd_name[9:]
@@ -284,6 +303,8 @@ def preferences():
284 303
                 selected_categories.append(category)
285 304
             elif pd_name == 'locale' and pd in settings['locales']:
286 305
                 locale = pd
306
+            elif pd_name == 'autocomplete':
307
+                autocomplete = pd
287 308
             elif pd_name == 'language' and (pd == 'all' or
288 309
                                             pd in (x[0] for
289 310
                                                    x in language_codes)):
@@ -319,8 +340,14 @@ def preferences():
319 340
             # cookie max age: 4 weeks
320 341
             resp.set_cookie(
321 342
                 'categories', ','.join(selected_categories),
322
-                max_age=60 * 60 * 24 * 7 * 4
343
+                max_age=cookie_max_age
323 344
             )
345
+
346
+            resp.set_cookie(
347
+                'autocomplete', autocomplete,
348
+                max_age=cookie_max_age
349
+            )
350
+
324 351
         return resp
325 352
     return render('preferences.html',
326 353
                   client=settings.get('client', None),
@@ -330,6 +357,7 @@ def preferences():
330 357
                   language_codes=language_codes,
331 358
                   categs=categories.items(),
332 359
                   blocked_engines=blocked_engines,
360
+                  autocomplete_backends=autocomplete_backends,
333 361
                   shortcuts={y: x for x, y in engine_shortcuts.items()})
334 362
 
335 363
 
@@ -361,7 +389,12 @@ def opensearch():
361 389
     # chrome/chromium only supports HTTP GET....
362 390
     if request.headers.get('User-Agent', '').lower().find('webkit') >= 0:
363 391
         method = 'get'
364
-    ret = render('opensearch.xml', method=method, host=get_base_url(),client=settings['client'])
392
+
393
+    ret = render('opensearch.xml',
394
+                 method=method,
395
+                 host=get_base_url(),
396
+                 client=settings['client'])
397
+
365 398
     resp = Response(response=ret,
366 399
                     status=200,
367 400
                     mimetype="application/xml")