@@ -28,10 +28,12 @@ from flask import (
28from flask.ext.babel import Babel
28from flask.ext.babel import Babel
29from searx import settings, searx_dir
29from searx import settings, searx_dir
30from searx.engines import (
30from searx.engines import (
31− search, categories, engines, get_engines_stats, engine_shortcuts
31+ search as do_search, categories, engines, get_engines_stats,
33from searx.utils import UnicodeWriter, highlight_content, html_to_text
34from searx.utils import UnicodeWriter, highlight_content, html_to_text
34from searx.languages import language_codes
35from searx.languages import language_codes
36+from searx.search import Search
37app = Flask(
39app = Flask(
@@ -94,95 +96,32 @@ def render(template_name, **kwargs):
94 return render_template(template_name, **kwargs)
96 return render_template(template_name, **kwargs)
97−def parse_query(query):
99− query_parts = query.split()
101− if query_parts[0].startswith('!'):
102− prefix = query_parts[0][1:].replace('_', ' ')
103− if prefix in engine_shortcuts:
104− query_engines.append({'category': 'none',
105− 'name': engine_shortcuts[prefix]})
106− elif prefix in engines:
107− query_engines.append({'category': 'none',
109− elif prefix in categories:
110− query_engines.extend({'category': prefix,
111− 'name': engine.name}
112− for engine in categories[prefix])
114− if len(query_engines):
115− query = query.replace(query_parts[0], '', 1).strip()
116− return query, query_engines
119@app.route('/', methods=['GET', 'POST'])
99@app.route('/', methods=['GET', 'POST'])
120def index():
100def index():
121 """Render index page.
101 """Render index page.
123 Supported outputs: html, json, csv, rss.
103 Supported outputs: html, json, csv, rss.
128− if request.cookies.get('language')\
129− and request.cookies['language'] in (x[0] for x in language_codes):
130− lang = request.cookies['language']
132− if request.method == 'POST':
133− request_data = request.form
135− request_data = request.args
136− if not request_data.get('q'):
137− return render('index.html')
139− pageno_param = request_data.get('pageno', '1')
106+ try:
140− if not pageno_param.isdigit() or int(pageno_param) < 1:
107+ search = Search(request)
141 return render('index.html')
109 return render('index.html')
143− pageno = int(pageno_param)
111+ # TODO moar refactor - do_search integration into Search class
145− selected_categories = []
147− query, selected_engines = parse_query(request_data['q'].encode('utf-8'))
149− if len(selected_engines):
150− selected_categories = list(set(engine['category']
151− for engine in selected_engines))
153− for pd_name, pd in request_data.items():
154− if pd_name.startswith('category_'):
155− category = pd_name[9:]
156− if not category in categories:
158− selected_categories.append(category)
159− if not len(selected_categories):
160− cookie_categories = request.cookies.get('categories', '')
161− cookie_categories = cookie_categories.split(',')
162− for ccateg in cookie_categories:
163− if ccateg in categories:
164− selected_categories.append(ccateg)
165− if not len(selected_categories):
166− selected_categories = ['general']
168− for categ in selected_categories:
169− selected_engines.extend({'category': categ,
171− for x in categories[categ])
173− results, suggestions = search(query,
112+ search.results, search.suggestions = do_search(search.query,
174− request,
113+ request,
175− selected_engines,
114+ search.engines,
176− pageno,
115+ search.pageno,
177− lang)
116+ search.lang)
179− for result in results:
118+ for result in search.results:
180− if not paging and engines[result['engine']].paging:
119+ if not search.paging and engines[result['engine']].paging:
181− paging = True
120+ search.paging = True
182− if request_data.get('format', 'html') == 'html':
121+ if search.request_data.get('format', 'html') == 'html':
183 if 'content' in result:
122 if 'content' in result:
184− result['content'] = highlight_content(result['content'], query)
123+ result['content'] = highlight_content(result['content'], search.query)
185− result['title'] = highlight_content(result['title'], query)
124+ result['title'] = highlight_content(result['title'], search.query)
187 if 'content' in result:
126 if 'content' in result:
188 result['content'] = html_to_text(result['content']).strip()
127 result['content'] = html_to_text(result['content']).strip()
@@ -199,40 +138,40 @@ def index():
199 if engine in favicons:
138 if engine in favicons:
200 result['favicon'] = engine
139 result['favicon'] = engine
202− if request_data.get('format') == 'json':
141+ if search.request_data.get('format') == 'json':
203− return Response(json.dumps({'query': query, 'results': results}),
142+ return Response(json.dumps({'query': search.query, 'results': search.results}),
204 mimetype='application/json')
143 mimetype='application/json')
205− elif request_data.get('format') == 'csv':
144+ elif search.request_data.get('format') == 'csv':
206 csv = UnicodeWriter(cStringIO.StringIO())
145 csv = UnicodeWriter(cStringIO.StringIO())
207 keys = ('title', 'url', 'content', 'host', 'engine', 'score')
146 keys = ('title', 'url', 'content', 'host', 'engine', 'score')
208− if len(results):
147+ if len(search.results):
209 csv.writerow(keys)
148 csv.writerow(keys)
210− for row in results:
149+ for row in search.results:
211 row['host'] = row['parsed_url'].netloc
150 row['host'] = row['parsed_url'].netloc
212 csv.writerow([row.get(key, '') for key in keys])
151 csv.writerow([row.get(key, '') for key in keys])
213 csv.stream.seek(0)
152 csv.stream.seek(0)
214 response = Response(csv.stream.read(), mimetype='application/csv')
153 response = Response(csv.stream.read(), mimetype='application/csv')
215− content_disp = 'attachment;Filename=searx_-_{0}.csv'.format(query)
154+ content_disp = 'attachment;Filename=searx_-_{0}.csv'.format(search.query)
216 response.headers.add('Content-Disposition', content_disp)
155 response.headers.add('Content-Disposition', content_disp)
217 return response
156 return response
218− elif request_data.get('format') == 'rss':
157+ elif search.request_data.get('format') == 'rss':
219 response_rss = render(
158 response_rss = render(
220 'opensearch_response_rss.xml',
159 'opensearch_response_rss.xml',
221− results=results,
160+ results=search.results,
222− q=request_data['q'],
161+ q=search.request_data['q'],
223− number_of_results=len(results),
162+ number_of_results=len(search.results),
224 base_url=get_base_url()
163 base_url=get_base_url()
226 return Response(response_rss, mimetype='text/xml')
165 return Response(response_rss, mimetype='text/xml')
228 return render(
167 return render(
229 'results.html',
168 'results.html',
230− results=results,
169+ results=search.results,
231− q=request_data['q'],
170+ q=search.request_data['q'],
232− selected_categories=selected_categories,
171+ selected_categories=search.categories,
233− paging=paging,
172+ paging=search.paging,
234− pageno=pageno,
173+ pageno=search.pageno,
235− suggestions=suggestions
174+ suggestions=search.suggestions