Преглед изворни кода

Merge pull request #832 from dalf/input_check

Input check
Adam Tauber пре 8 година
родитељ
комит
3a57a1a0d0

+ 32
- 0
searx/exceptions.py Прегледај датотеку

1
+'''
2
+searx is free software: you can redistribute it and/or modify
3
+it under the terms of the GNU Affero General Public License as published by
4
+the Free Software Foundation, either version 3 of the License, or
5
+(at your option) any later version.
6
+
7
+searx is distributed in the hope that it will be useful,
8
+but WITHOUT ANY WARRANTY; without even the implied warranty of
9
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10
+GNU Affero General Public License for more details.
11
+
12
+You should have received a copy of the GNU Affero General Public License
13
+along with searx. If not, see < http://www.gnu.org/licenses/ >.
14
+
15
+(C) 2017- by Alexandre Flament, <alex@al-f.net>
16
+'''
17
+
18
+
19
+class SearxException(Exception):
20
+    pass
21
+
22
+
23
+class SearxParameterException(SearxException):
24
+
25
+    def __init__(self, name, value):
26
+        if value == '' or value is None:
27
+            message = 'Empty ' + name + ' parameter'
28
+        else:
29
+            message = 'Invalid value "' + value + '" for parameter ' + name
30
+        super(SearxParameterException, self).__init__(message)
31
+        self.parameter_name = name
32
+        self.parameter_value = value

+ 43
- 23
searx/search.py Прегледај датотеку

31
 from searx.results import ResultContainer
31
 from searx.results import ResultContainer
32
 from searx import logger
32
 from searx import logger
33
 from searx.plugins import plugins
33
 from searx.plugins import plugins
34
+from searx.languages import language_codes
35
+from searx.exceptions import SearxParameterException
34
 
36
 
35
 logger = logger.getChild('search')
37
 logger = logger.getChild('search')
36
 
38
 
37
 number_of_searches = 0
39
 number_of_searches = 0
38
 
40
 
41
+language_code_set = set(l[0].lower() for l in language_codes)
42
+language_code_set.add('all')
43
+
39
 
44
 
40
 def send_http_request(engine, request_params, start_time, timeout_limit):
45
 def send_http_request(engine, request_params, start_time, timeout_limit):
41
     # for page_load_time stats
46
     # for page_load_time stats
182
 
187
 
183
 
188
 
184
 def get_search_query_from_webapp(preferences, form):
189
 def get_search_query_from_webapp(preferences, form):
185
-    query = None
186
-    query_engines = []
187
-    query_categories = []
188
-    query_pageno = 1
189
-    query_lang = 'all'
190
-    query_time_range = None
190
+    # no text for the query ?
191
+    if not form.get('q'):
192
+        raise SearxParameterException('q', '')
191
 
193
 
192
     # set blocked engines
194
     # set blocked engines
193
     disabled_engines = preferences.engines.get_disabled()
195
     disabled_engines = preferences.engines.get_disabled()
194
 
196
 
195
-    # set specific language if set
196
-    query_lang = preferences.get_value('language')
197
-
198
-    # safesearch
199
-    query_safesearch = preferences.get_value('safesearch')
200
-
201
-    # TODO better exceptions
202
-    if not form.get('q'):
203
-        raise Exception('noquery')
204
-
205
-    # set pagenumber
206
-    pageno_param = form.get('pageno', '1')
207
-    if not pageno_param.isdigit() or int(pageno_param) < 1:
208
-        pageno_param = 1
209
-
210
-    query_pageno = int(pageno_param)
211
-
212
     # parse query, if tags are set, which change
197
     # parse query, if tags are set, which change
213
     # the serch engine or search-language
198
     # the serch engine or search-language
214
     raw_text_query = RawTextQuery(form['q'], disabled_engines)
199
     raw_text_query = RawTextQuery(form['q'], disabled_engines)
217
     # set query
202
     # set query
218
     query = raw_text_query.getSearchQuery()
203
     query = raw_text_query.getSearchQuery()
219
 
204
 
205
+    # get and check page number
206
+    pageno_param = form.get('pageno', '1')
207
+    if not pageno_param.isdigit() or int(pageno_param) < 1:
208
+        raise SearxParameterException('pageno', pageno_param)
209
+    query_pageno = int(pageno_param)
210
+
211
+    # get language
220
     # set specific language if set on request, query or preferences
212
     # set specific language if set on request, query or preferences
221
     # TODO support search with multible languages
213
     # TODO support search with multible languages
222
     if len(raw_text_query.languages):
214
     if len(raw_text_query.languages):
226
     else:
218
     else:
227
         query_lang = preferences.get_value('language')
219
         query_lang = preferences.get_value('language')
228
 
220
 
221
+    # check language
222
+    if query_lang not in language_code_set:
223
+        raise SearxParameterException('language', query_lang)
224
+
225
+    # get safesearch
226
+    if 'safesearch' in form:
227
+        query_safesearch = form.get('safesearch')
228
+        # first check safesearch
229
+        if not query_safesearch.isdigit():
230
+            raise SearxParameterException('safesearch', query_safesearch)
231
+        query_safesearch = int(query_safesearch)
232
+    else:
233
+        query_safesearch = preferences.get_value('safesearch')
234
+
235
+    # safesearch : second check
236
+    if query_safesearch < 0 or query_safesearch > 2:
237
+        raise SearxParameterException('safesearch', query_safesearch)
238
+
239
+    # get time_range
229
     query_time_range = form.get('time_range')
240
     query_time_range = form.get('time_range')
230
 
241
 
242
+    # check time_range
243
+    if not(query_time_range is None)\
244
+       and not (query_time_range in ['', 'day', 'week', 'month', 'year']):
245
+        raise SearxParameterException('time_range', query_time_range)
246
+
247
+    # query_engines
231
     query_engines = raw_text_query.engines
248
     query_engines = raw_text_query.engines
232
 
249
 
250
+    # query_categories
251
+    query_categories = []
252
+
233
     # if engines are calculated from query,
253
     # if engines are calculated from query,
234
     # set categories by using that informations
254
     # set categories by using that informations
235
     if query_engines and raw_text_query.specific:
255
     if query_engines and raw_text_query.specific:

+ 62
- 0
searx/templates/__common__/about.html Прегледај датотеку

1
+<div{% if rtl %} dir="ltr"{% endif %}>
2
+    <h1>About <a href="{{ url_for('index') }}">searx</a></h1>
3
+
4
+    <p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, aggregating the results of other <a href="{{ url_for('preferences') }}">search engines</a> while not storing information about its users.
5
+    </p>
6
+    <h2>Why use searx?</h2>
7
+    <ul>
8
+        <li>searx may not offer you as personalised results as Google, but it doesn't generate a profile about you</li>
9
+        <li>searx doesn't care about what you search for, never shares anything with a third party, and it can't be used to compromise you</li>
10
+        <li>searx is free software, the code is 100% open and you can help to make it better. See more on <a href="https://github.com/asciimoo/searx">github</a></li>
11
+    </ul>
12
+    <p>If you do care about privacy, want to be a conscious user, or otherwise believe
13
+    in digital freedom, make searx your default search engine or run it on your own server</p>
14
+
15
+<h2>Technical details - How does it work?</h2>
16
+
17
+<p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>,
18
+inspired by the <a href="https://beniz.github.io/seeks/">seeks project</a>.<br />
19
+It provides basic privacy by mixing your queries with searches on other platforms without storing search data. Queries are made using a POST request on every browser (except chrome*). Therefore they show up in neither our logs, nor your url history. In case of Chrome* users there is an exception, searx uses the search bar to perform GET requests.<br />
20
+Searx can be added to your browser's search bar; moreover, it can be set as the default search engine.
21
+</p>
22
+
23
+<h2>How can I make it my own?</h2>
24
+
25
+<p>Searx appreciates your concern regarding logs, so take the <a href="https://github.com/asciimoo/searx">code</a> and run it yourself! <br />Add your Searx to this <a href="https://github.com/asciimoo/searx/wiki/Searx-instances">list</a> to help other people reclaim their privacy and make the Internet freer!
26
+<br />The more decentralized the Internet is, the more freedom we have!</p>
27
+
28
+
29
+<h2>More about searx</h2>
30
+
31
+<ul>
32
+    <li><a href="https://github.com/asciimoo/searx">github</a></li>
33
+    <li><a href="https://www.ohloh.net/p/searx/">ohloh</a></li>
34
+    <li><a href="https://twitter.com/Searx_engine">twitter</a></li>
35
+    <li>IRC: #searx @ freenode (<a href="https://kiwiirc.com/client/irc.freenode.com/searx">webclient</a>)</li>
36
+    <li><a href="https://www.transifex.com/projects/p/searx/">transifex</a></li>
37
+</ul>
38
+
39
+
40
+<hr />
41
+
42
+<h2 id="faq">FAQ</h2>
43
+
44
+<h3>How to add to firefox?</h3>
45
+<p><a href="#" onclick="window.external.AddSearchProvider(window.location.protocol + '//' + window.location.host + '{{ url_for('opensearch') }}');">Install</a> searx as a search engine on any version of Firefox! (javascript required)</p>
46
+
47
+<h2 id="dev_faq">Developer FAQ</h2>
48
+
49
+<h3>New engines?</h3>
50
+<ul>
51
+    <li>Edit your <a href="https://raw.github.com/asciimoo/searx/master/searx/settings.yml">settings.yml</a></li>
52
+    <li>Create your custom engine module, check the <a href="https://github.com/asciimoo/searx/blob/master/examples/basic_engine.py">example engine</a></li>
53
+</ul>
54
+<p>Don't forget to restart searx after config edit!</p>
55
+
56
+<h3>Installation/WSGI support?</h3>
57
+<p>See the <a href="https://github.com/asciimoo/searx/wiki/Installation">installation and setup</a> wiki page</p>
58
+
59
+<h3>How to debug engines?</h3>
60
+<p><a href="{{ url_for('stats') }}">Stats page</a> contains some useful data about the engines used.</p>
61
+
62
+</div>

searx/templates/oscar/opensearch.xml → searx/templates/__common__/opensearch.xml Прегледај датотеку


searx/templates/oscar/opensearch_response_rss.xml → searx/templates/__common__/opensearch_response_rss.xml Прегледај датотеку

11
     <opensearch:itemsPerPage>{{ number_of_results }}</opensearch:itemsPerPage>
11
     <opensearch:itemsPerPage>{{ number_of_results }}</opensearch:itemsPerPage>
12
     <atom:link rel="search" type="application/opensearchdescription+xml" href="{{ base_url }}opensearch.xml"/>
12
     <atom:link rel="search" type="application/opensearchdescription+xml" href="{{ base_url }}opensearch.xml"/>
13
     <opensearch:Query role="request" searchTerms="{{ q|e }}" startPage="1" />
13
     <opensearch:Query role="request" searchTerms="{{ q|e }}" startPage="1" />
14
+    {% if error_message %}
15
+    <item>
16
+      <title>Error</title>
17
+      <description>{{ error_message|e }}</description>
18
+    </item>
19
+    {% endif %}
14
     {% for r in results %}
20
     {% for r in results %}
15
     <item>
21
     <item>
16
       <title>{{ r.title }}</title>
22
       <title>{{ r.title }}</title>

+ 1
- 62
searx/templates/courgette/about.html Прегледај датотеку

1
 {% extends 'courgette/base.html' %}
1
 {% extends 'courgette/base.html' %}
2
 {% block content %}
2
 {% block content %}
3
 {% include 'courgette/github_ribbon.html' %}
3
 {% include 'courgette/github_ribbon.html' %}
4
-<div class="row"{% if rtl %} dir="ltr"{% endif %}>
5
-    <h1>About <a href="{{ url_for('index') }}">searx</a></h1>
6
-
7
-    <p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, aggregating the results of other <a href="{{ url_for('preferences') }}">search engines</a> while not storing information about its users.
8
-    </p>
9
-    <h2>Why use searx?</h2>
10
-    <ul>
11
-        <li>searx may not offer you as personalised results as Google, but it doesn't generate a profile about you</li>
12
-        <li>searx doesn't care about what you search for, never shares anything with a third party, and it can't be used to compromise you</li>
13
-        <li>searx is free software, the code is 100% open and you can help to make it better. See more on <a href="https://github.com/asciimoo/searx">github</a></li>
14
-    </ul>
15
-    <p>If you do care about privacy, want to be a conscious user, or otherwise believe
16
-    in digital freedom, make searx your default search engine or run it on your own server</p>
17
-
18
-<h2>Technical details - How does it work?</h2>
19
-
20
-<p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>,
21
-inspired by the <a href="https://beniz.github.io/seeks/">seeks project</a>.<br />
22
-It provides basic privacy by mixing your queries with searches on other platforms without storing search data. Queries are made using a POST request on every browser (except chrome*). Therefore they show up in neither our logs, nor your url history. In case of Chrome* users there is an exception, searx uses the search bar to perform GET requests.<br />
23
-Searx can be added to your browser's search bar; moreover, it can be set as the default search engine.
24
-</p>
25
-
26
-<h2>How can I make it my own?</h2>
27
-
28
-<p>Searx appreciates your concern regarding logs, so take the <a href="https://github.com/asciimoo/searx">code</a> and run it yourself! <br />Add your Searx to this <a href="https://github.com/asciimoo/searx/wiki/Searx-instances">list</a> to help other people reclaim their privacy and make the Internet freer!
29
-<br />The more decentralized the Internet, is the more freedom we have!</p>
30
-
31
-
32
-<h2>More about searx</h2>
33
-
34
-<ul>
35
-    <li><a href="https://github.com/asciimoo/searx">github</a></li>
36
-    <li><a href="https://www.ohloh.net/p/searx/">ohloh</a></li>
37
-    <li><a href="https://twitter.com/Searx_engine">twitter</a></li>
38
-    <li>IRC: #searx @ freenode (<a href="https://kiwiirc.com/client/irc.freenode.com/searx">webclient</a>)</li>
39
-    <li><a href="https://www.transifex.com/projects/p/searx/">transifex</a></li>
40
-</ul>
41
-
42
-
43
-<hr />
44
-
45
-<h2 id="faq">FAQ</h2>
46
-
47
-<h3>How to add to firefox?</h3>
48
-<p><a href="#" onclick="window.external.AddSearchProvider(window.location.protocol + '//' + window.location.host + '{{ url_for('opensearch') }}');">Install</a> searx as a search engine on any version of Firefox! (javascript required)</p>
49
-
50
-<h2 id="dev_faq">Developer FAQ</h2>
51
-
52
-<h3>New engines?</h3>
53
-<ul>
54
-    <li>Edit your <a href="https://raw.github.com/asciimoo/searx/master/searx/settings.yml">settings.yml</a></li>
55
-    <li>Create your custom engine module, check the <a href="https://github.com/asciimoo/searx/blob/master/examples/basic_engine.py">example engine</a></li>
56
-</ul>
57
-<p>Don't forget to restart searx after config edit!</p>
58
-
59
-<h3>Installation/WSGI support?</h3>
60
-<p>See the <a href="https://github.com/asciimoo/searx/wiki/Installation">installation and setup</a> wiki page</p>
61
-
62
-<h3>How to debug engines?</h3>
63
-<p><a href="{{ url_for('stats') }}">Stats page</a> contains some useful data about the engines used.</p>
64
-
65
-</div>
4
+{% include '__common__/about.html' %}
66
 {% endblock %}
5
 {% endblock %}

+ 0
- 28
searx/templates/courgette/opensearch.xml Прегледај датотеку

1
-<?xml version="1.0" encoding="utf-8"?>
2
-<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
3
-  <ShortName>{{ instance_name }}</ShortName>
4
-  <Description>a privacy-respecting, hackable metasearch engine</Description>
5
-  <InputEncoding>UTF-8</InputEncoding>
6
-  <Image>{{ urljoin(host, url_for('static', filename='img/favicon.png')) }}</Image>
7
-  <LongName>searx metasearch</LongName>
8
-  {% if opensearch_method == 'get' %}
9
-    <Url type="text/html" method="get" template="{{ host }}search?q={searchTerms}"/>
10
-    {% if autocomplete %}
11
-    <Url type="application/x-suggestions+json" method="get" template="{{ host }}autocompleter">
12
-        <Param name="format" value="x-suggestions" />
13
-        <Param name="q" value="{searchTerms}" />
14
-    </Url>
15
-    {% endif %}
16
-  {% else %}
17
-    <Url type="text/html" method="post" template="{{ host }}">
18
-        <Param name="q" value="{searchTerms}" />
19
-    </Url>
20
-    {% if autocomplete %}
21
-    <!-- TODO, POST REQUEST doesn't work -->
22
-    <Url type="application/x-suggestions+json" method="get" template="{{ host }}autocompleter">
23
-        <Param name="format" value="x-suggestions" />
24
-        <Param name="q" value="{searchTerms}" />
25
-    </Url>
26
-    {% endif %}
27
-  {% endif %}
28
-</OpenSearchDescription>

+ 0
- 23
searx/templates/courgette/opensearch_response_rss.xml Прегледај датотеку

1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<rss version="2.0"
3
-     xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"
4
-     xmlns:atom="http://www.w3.org/2005/Atom">
5
-  <channel>
6
-    <title>Searx search: {{ q|e }}</title>
7
-    <link>{{ base_url }}?q={{ q|e }}</link>
8
-    <description>Search results for "{{ q|e }}" - searx</description>
9
-    <opensearch:totalResults>{{ number_of_results }}</opensearch:totalResults>
10
-    <opensearch:startIndex>1</opensearch:startIndex>
11
-    <opensearch:itemsPerPage>{{ number_of_results }}</opensearch:itemsPerPage>
12
-    <atom:link rel="search" type="application/opensearchdescription+xml" href="{{ base_url }}opensearch.xml"/>
13
-    <opensearch:Query role="request" searchTerms="{{ q|e }}" startPage="1" />
14
-    {% for r in results %}
15
-    <item>
16
-      <title>{{ r.title }}</title>
17
-      <link>{{ r.url }}</link>
18
-      <description>{{ r.content }}</description>
19
-      {% if r.pubdate %}<pubDate>{{ r.pubdate }}</pubDate>{% endif %}
20
-    </item>
21
-    {% endfor %}
22
-  </channel>
23
-</rss>

+ 1
- 62
searx/templates/legacy/about.html Прегледај датотеку

1
 {% extends 'legacy/base.html' %}
1
 {% extends 'legacy/base.html' %}
2
 {% block content %}
2
 {% block content %}
3
 {% include 'legacy/github_ribbon.html' %}
3
 {% include 'legacy/github_ribbon.html' %}
4
-<div class="row"{% if rtl %} dir="ltr"{% endif %}>
5
-    <h1>About <a href="{{ url_for('index') }}">searx</a></h1>
6
-
7
-    <p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, aggregating the results of other <a href="{{ url_for('preferences') }}">search engines</a> while not storing information about its users.
8
-    </p>
9
-    <h2>Why use searx?</h2>
10
-    <ul>
11
-        <li>searx may not offer you as personalised results as Google, but it doesn't generate a profile about you</li>
12
-        <li>searx doesn't care about what you search for, never shares anything with a third party, and it can't be used to compromise you</li>
13
-        <li>searx is free software, the code is 100% open and you can help to make it better. See more on <a href="https://github.com/asciimoo/searx">github</a></li>
14
-    </ul>
15
-    <p>If you do care about privacy, want to be a conscious user, or otherwise believe
16
-    in digital freedom, make searx your default search engine or run it on your own server</p>
17
-
18
-<h2>Technical details - How does it work?</h2>
19
-
20
-<p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>,
21
-inspired by the <a href="https://beniz.github.io/seeks/">seeks project</a>.<br />
22
-It provides basic privacy by mixing your queries with searches on other platforms without storing search data. Queries are made using a POST request on every browser (except chrome*). Therefore they show up in neither our logs, nor your url history. In case of Chrome* users there is an exception, if searx used from the search bar it performs GET requests.<br />
23
-Searx can be added to your browser's search bar; moreover, it can be set as the default search engine.
24
-</p>
25
-
26
-<h2>How can I make it my own?</h2>
27
-
28
-<p>Searx appreciates your concern regarding logs, so take the <a href="https://github.com/asciimoo/searx">code</a> and run it yourself! <br />Add your Searx to this <a href="https://github.com/asciimoo/searx/wiki/Searx-instances">list</a> to help other people reclaim their privacy and make the Internet freer!
29
-<br />The more decentralized Internet is the more freedom we have!</p>
30
-
31
-
32
-<h2>More about searx</h2>
33
-
34
-<ul>
35
-    <li><a href="https://github.com/asciimoo/searx">github</a></li>
36
-    <li><a href="https://www.ohloh.net/p/searx/">ohloh</a></li>
37
-    <li><a href="https://twitter.com/Searx_engine">twitter</a></li>
38
-    <li>IRC: #searx @ freenode (<a href="https://kiwiirc.com/client/irc.freenode.com/searx">webclient</a>)</li>
39
-    <li><a href="https://www.transifex.com/projects/p/searx/">transifex</a></li>
40
-</ul>
41
-
42
-
43
-<hr />
44
-
45
-<h2 id="faq">FAQ</h2>
46
-
47
-<h3>How to add to firefox?</h3>
48
-<p><a href="#" onclick="window.external.AddSearchProvider(window.location.protocol + '//' + window.location.host + '{{ url_for('opensearch') }}');">Install</a> searx as a search engine on any version of Firefox! (javascript required)</p>
49
-
50
-<h2 id="dev_faq">Developer FAQ</h2>
51
-
52
-<h3>New engines?</h3>
53
-<ul>
54
-    <li>Edit your <a href="https://raw.github.com/asciimoo/searx/master/searx/settings.yml">settings.yml</a></li>
55
-    <li>Create your custom engine module, check the <a href="https://github.com/asciimoo/searx/blob/master/examples/basic_engine.py">example engine</a></li>
56
-</ul>
57
-<p>Don't forget to restart searx after config edit!</p>
58
-
59
-<h3>Installation/WSGI support?</h3>
60
-<p>See the <a href="https://github.com/asciimoo/searx/wiki/Installation">installation and setup</a> wiki page</p>
61
-
62
-<h3>How to debug engines?</h3>
63
-<p><a href="{{ url_for('stats') }}">Stats page</a> contains some useful data about the engines used.</p>
64
-
65
-</div>
4
+{% include '__common__/about.html' %}
66
 {% endblock %}
5
 {% endblock %}

+ 0
- 28
searx/templates/legacy/opensearch.xml Прегледај датотеку

1
-<?xml version="1.0" encoding="utf-8"?>
2
-<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
3
-  <ShortName>{{ instance_name }}</ShortName>
4
-  <Description>a privacy-respecting, hackable metasearch engine</Description>
5
-  <InputEncoding>UTF-8</InputEncoding>
6
-  <Image>{{ urljoin(host, url_for('static', filename='img/favicon.png')) }}</Image>
7
-  <LongName>searx metasearch</LongName>
8
-  {% if opensearch_method == 'get' %}
9
-    <Url type="text/html" method="get" template="{{ host }}search?q={searchTerms}"/>
10
-    {% if autocomplete %}
11
-    <Url type="application/x-suggestions+json" method="get" template="{{ host }}autocompleter">
12
-        <Param name="format" value="x-suggestions" />
13
-        <Param name="q" value="{searchTerms}" />
14
-    </Url>
15
-    {% endif %}
16
-  {% else %}
17
-    <Url type="text/html" method="post" template="{{ host }}">
18
-        <Param name="q" value="{searchTerms}" />
19
-    </Url>
20
-    {% if autocomplete %}
21
-    <!-- TODO, POST REQUEST doesn't work -->
22
-    <Url type="application/x-suggestions+json" method="get" template="{{ host }}autocompleter">
23
-        <Param name="format" value="x-suggestions" />
24
-        <Param name="q" value="{searchTerms}" />
25
-    </Url>
26
-    {% endif %}
27
-  {% endif %}
28
-</OpenSearchDescription>

+ 0
- 23
searx/templates/legacy/opensearch_response_rss.xml Прегледај датотеку

1
-<?xml version="1.0" encoding="UTF-8"?>
2
-<rss version="2.0"
3
-     xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"
4
-     xmlns:atom="http://www.w3.org/2005/Atom">
5
-  <channel>
6
-    <title>Searx search: {{ q|e }}</title>
7
-    <link>{{ base_url }}?q={{ q|e }}</link>
8
-    <description>Search results for "{{ q|e }}" - searx</description>
9
-    <opensearch:totalResults>{{ number_of_results }}</opensearch:totalResults>
10
-    <opensearch:startIndex>1</opensearch:startIndex>
11
-    <opensearch:itemsPerPage>{{ number_of_results }}</opensearch:itemsPerPage>
12
-    <atom:link rel="search" type="application/opensearchdescription+xml" href="{{ base_url }}opensearch.xml"/>
13
-    <opensearch:Query role="request" searchTerms="{{ q|e }}" startPage="1" />
14
-    {% for r in results %}
15
-    <item>
16
-      <title>{{ r.title }}</title>
17
-      <link>{{ r.url }}</link>
18
-      <description>{{ r.content }}</description>
19
-      {% if r.pubdate %}<pubDate>{{ r.pubdate }}</pubDate>{% endif %}
20
-    </item>
21
-    {% endfor %}
22
-  </channel>
23
-</rss>

+ 1
- 62
searx/templates/oscar/about.html Прегледај датотеку

1
 {% extends "oscar/base.html" %}
1
 {% extends "oscar/base.html" %}
2
 {% block title %}{{ _('about') }} - {% endblock %}
2
 {% block title %}{{ _('about') }} - {% endblock %}
3
 {% block content %}
3
 {% block content %}
4
-<div{% if rtl %} dir="ltr"{% endif %}>
5
-    <h1>About <a href="{{ url_for('index') }}">searx</a></h1>
6
-
7
-    <p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, aggregating the results of other <a href="{{ url_for('preferences') }}">search engines</a> while not storing information about its users.
8
-    </p>
9
-    <h2>Why use searx?</h2>
10
-    <ul>
11
-        <li>searx may not offer you as personalised results as Google, but it doesn't generate a profile about you</li>
12
-        <li>searx doesn't care about what you search for, never shares anything with a third party, and it can't be used to compromise you</li>
13
-        <li>searx is free software, the code is 100% open and you can help to make it better. See more on <a href="https://github.com/asciimoo/searx">github</a></li>
14
-    </ul>
15
-    <p>If you do care about privacy, want to be a conscious user, or otherwise believe
16
-    in digital freedom, make searx your default search engine or run it on your own server</p>
17
-
18
-<h2>Technical details - How does it work?</h2>
19
-
20
-<p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>,
21
-inspired by the <a href="https://beniz.github.io/seeks/">seeks project</a>.<br />
22
-It provides basic privacy by mixing your queries with searches on other platforms without storing search data. Queries are made using a POST request on every browser (except chrome*). Therefore they show up in neither our logs, nor your url history. In case of Chrome* users there is an exception, searx uses the search bar to perform GET requests.<br />
23
-Searx can be added to your browser's search bar; moreover, it can be set as the default search engine.
24
-</p>
25
-
26
-<h2>How can I make it my own?</h2>
27
-
28
-<p>Searx appreciates your concern regarding logs, so take the <a href="https://github.com/asciimoo/searx">code</a> and run it yourself! <br />Add your Searx to this <a href="https://github.com/asciimoo/searx/wiki/Searx-instances">list</a> to help other people reclaim their privacy and make the Internet freer!
29
-<br />The more decentralized the Internet is, the more freedom we have!</p>
30
-
31
-
32
-<h2>More about searx</h2>
33
-
34
-<ul>
35
-    <li><a href="https://github.com/asciimoo/searx">github</a></li>
36
-    <li><a href="https://www.ohloh.net/p/searx/">ohloh</a></li>
37
-    <li><a href="https://twitter.com/Searx_engine">twitter</a></li>
38
-    <li>IRC: #searx @ freenode (<a href="https://kiwiirc.com/client/irc.freenode.com/searx">webclient</a>)</li>
39
-    <li><a href="https://www.transifex.com/projects/p/searx/">transifex</a></li>
40
-</ul>
41
-
42
-
43
-<hr />
44
-
45
-<h2 id="faq">FAQ</h2>
46
-
47
-<h3>How to add to firefox?</h3>
48
-<p><a href="#" onclick="window.external.AddSearchProvider(window.location.protocol + '//' + window.location.host + '{{ url_for('opensearch') }}');">Install</a> searx as a search engine on any version of Firefox! (javascript required)</p>
49
-
50
-<h2 id="dev_faq">Developer FAQ</h2>
51
-
52
-<h3>New engines?</h3>
53
-<ul>
54
-    <li>Edit your <a href="https://raw.github.com/asciimoo/searx/master/searx/settings.yml">settings.yml</a></li>
55
-    <li>Create your custom engine module, check the <a href="https://github.com/asciimoo/searx/blob/master/examples/basic_engine.py">example engine</a></li>
56
-</ul>
57
-<p>Don't forget to restart searx after config edit!</p>
58
-
59
-<h3>Installation/WSGI support?</h3>
60
-<p>See the <a href="https://github.com/asciimoo/searx/wiki/Installation">installation and setup</a> wiki page</p>
61
-
62
-<h3>How to debug engines?</h3>
63
-<p><a href="{{ url_for('stats') }}">Stats page</a> contains some useful data about the engines used.</p>
64
-
65
-</div>
4
+{% include '__common__/about.html' %}
66
 {% endblock %}
5
 {% endblock %}

+ 1
- 62
searx/templates/pix-art/about.html Прегледај датотеку

1
 {% extends 'pix-art/base.html' %}
1
 {% extends 'pix-art/base.html' %}
2
 {% block content %}
2
 {% block content %}
3
-<div class="row"{% if rtl %} dir="ltr"{% endif %}>
4
-    <h1>About <a href="{{ url_for('index') }}">searx</a></h1>
5
-
6
-    <p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>, aggregating the results of other <a href="{{ url_for('preferences') }}">search engines</a> while not storing information about its users.
7
-    </p>
8
-    <h2>Why use searx?</h2>
9
-    <ul>
10
-        <li>searx may not offer you as personalised results as Google, but it doesn't generate a profile about you</li>
11
-        <li>searx doesn't care about what you search for, never shares anything with a third party, and it can't be used to compromise you</li>
12
-        <li>searx is free software, the code is 100% open and you can help to make it better. See more on <a href="https://github.com/asciimoo/searx">github</a></li>
13
-    </ul>
14
-    <p>If you do care about privacy, want to be a conscious user, or otherwise believe
15
-    in digital freedom, make searx your default search engine or run it on your own server</p>
16
-
17
-<h2>Technical details - How does it work?</h2>
18
-
19
-<p>Searx is a <a href="https://en.wikipedia.org/wiki/Metasearch_engine">metasearch engine</a>,
20
-inspired by the <a href="https://beniz.github.io/seeks/">seeks project</a>.<br />
21
-It provides basic privacy by mixing your queries with searches on other platforms without storing search data. Queries are made using a POST request on every browser (except chrome*). Therefore they show up in neither our logs, nor your url history. In case of Chrome* users there is an exception, if searx used from the search bar it performs GET requests.<br />
22
-Searx can be added to your browser's search bar; moreover, it can be set as the default search engine.
23
-</p>
24
-
25
-<h2>How can I make it my own?</h2>
26
-
27
-<p>Searx appreciates your concern regarding logs, so take the <a href="https://github.com/asciimoo/searx">code</a> and run it yourself! <br />Add your Searx to this <a href="https://github.com/asciimoo/searx/wiki/Searx-instances">list</a> to help other people reclaim their privacy and make the Internet freer!
28
-<br />The more decentralized Internet is the more freedom we have!</p>
29
-
30
-
31
-<h2>More about searx</h2>
32
-
33
-<ul>
34
-    <li><a href="https://github.com/asciimoo/searx">github</a></li>
35
-    <li><a href="https://www.ohloh.net/p/searx/">ohloh</a></li>
36
-    <li><a href="https://twitter.com/Searx_engine">twitter</a></li>
37
-    <li>IRC: #searx @ freenode (<a href="https://kiwiirc.com/client/irc.freenode.com/searx">webclient</a>)</li>
38
-    <li><a href="https://www.transifex.com/projects/p/searx/">transifex</a></li>
39
-</ul>
40
-
41
-
42
-<hr />
43
-
44
-<h2 id="faq">FAQ</h2>
45
-
46
-<h3>How to add to firefox?</h3>
47
-<p><a href="#" onclick="window.external.AddSearchProvider(window.location.protocol + '//' + window.location.host + '{{ url_for('opensearch') }}');">Install</a> searx as a search engine on any version of Firefox! (javascript required)</p>
48
-
49
-<h2 id="dev_faq">Developer FAQ</h2>
50
-
51
-<h3>New engines?</h3>
52
-<ul>
53
-    <li>Edit your <a href="https://raw.github.com/asciimoo/searx/master/searx/settings.yml">settings.yml</a></li>
54
-    <li>Create your custom engine module, check the <a href="https://github.com/asciimoo/searx/blob/master/examples/basic_engine.py">example engine</a></li>
55
-</ul>
56
-<p>Don't forget to restart searx after config edit!</p>
57
-
58
-<h3>Installation/WSGI support?</h3>
59
-<p>See the <a href="https://github.com/asciimoo/searx/wiki/Installation">installation and setup</a> wiki page</p>
60
-
61
-<h3>How to debug engines?</h3>
62
-<p><a href="{{ url_for('stats') }}">Stats page</a> contains some useful data about the engines used.</p>
63
-
64
-</div>
3
+{% include '__common__/about.html' %}
65
 {% endblock %}
4
 {% endblock %}

+ 2
- 0
searx/utils.py Прегледај датотеку

175
     templates_path = os.path.join(root, 'templates')
175
     templates_path = os.path.join(root, 'templates')
176
 
176
 
177
     themes = os.listdir(os.path.join(static_path, 'themes'))
177
     themes = os.listdir(os.path.join(static_path, 'themes'))
178
+    if '__common__' in themes:
179
+        themes.remove('__common__')
178
     return static_path, templates_path, themes
180
     return static_path, templates_path, themes
179
 
181
 
180
 
182
 

+ 57
- 18
searx/webapp.py Прегледај датотеку

52
 from flask_babel import Babel, gettext, format_date, format_decimal
52
 from flask_babel import Babel, gettext, format_date, format_decimal
53
 from flask.json import jsonify
53
 from flask.json import jsonify
54
 from searx import settings, searx_dir, searx_debug
54
 from searx import settings, searx_dir, searx_debug
55
+from searx.exceptions import SearxException, SearxParameterException
55
 from searx.engines import (
56
 from searx.engines import (
56
     categories, engines, engine_shortcuts, get_engines_stats, initialize_engines
57
     categories, engines, engine_shortcuts, get_engines_stats, initialize_engines
57
 )
58
 )
226
     2. cookies
227
     2. cookies
227
     3. settings"""
228
     3. settings"""
228
 
229
 
229
-    if override and override in themes:
230
+    if override and (override in themes or override == '__common__'):
230
         return override
231
         return override
231
     theme_name = request.args.get('theme', request.preferences.get_value('theme'))
232
     theme_name = request.args.get('theme', request.preferences.get_value('theme'))
232
     if theme_name not in themes:
233
     if theme_name not in themes:
400
             request.user_plugins.append(plugin)
401
             request.user_plugins.append(plugin)
401
 
402
 
402
 
403
 
404
+def index_error(output_format, error_message):
405
+    if output_format == 'json':
406
+        return Response(json.dumps({'error': error_message}),
407
+                        mimetype='application/json')
408
+    elif output_format == 'csv':
409
+        response = Response('', mimetype='application/csv')
410
+        cont_disp = 'attachment;Filename=searx.csv'
411
+        response.headers.add('Content-Disposition', cont_disp)
412
+        return response
413
+    elif output_format == 'rss':
414
+        response_rss = render(
415
+            'opensearch_response_rss.xml',
416
+            results=[],
417
+            q=request.form['q'] if 'q' in request.form else '',
418
+            number_of_results=0,
419
+            base_url=get_base_url(),
420
+            error_message=error_message
421
+        )
422
+        return Response(response_rss, mimetype='text/xml')
423
+    else:
424
+        # html
425
+        request.errors.append(gettext('search error'))
426
+        return render(
427
+            'index.html',
428
+        )
429
+
430
+
403
 @app.route('/search', methods=['GET', 'POST'])
431
 @app.route('/search', methods=['GET', 'POST'])
404
 @app.route('/', methods=['GET', 'POST'])
432
 @app.route('/', methods=['GET', 'POST'])
405
 def index():
433
 def index():
408
     Supported outputs: html, json, csv, rss.
436
     Supported outputs: html, json, csv, rss.
409
     """
437
     """
410
 
438
 
439
+    # output_format
440
+    output_format = request.form.get('format', 'html')
441
+    if output_format not in ['html', 'csv', 'json', 'rss']:
442
+        output_format = 'html'
443
+
444
+    # check if there is query
411
     if request.form.get('q') is None:
445
     if request.form.get('q') is None:
412
-        return render(
413
-            'index.html',
414
-        )
446
+        if output_format == 'html':
447
+            return render(
448
+                'index.html',
449
+            )
450
+        else:
451
+            return index_error(output_format, 'No query'), 400
415
 
452
 
416
     # search
453
     # search
417
     search_query = None
454
     search_query = None
421
         # search = Search(search_query) #  without plugins
458
         # search = Search(search_query) #  without plugins
422
         search = SearchWithPlugins(search_query, request)
459
         search = SearchWithPlugins(search_query, request)
423
         result_container = search.search()
460
         result_container = search.search()
424
-    except:
425
-        request.errors.append(gettext('search error'))
461
+    except Exception as e:
462
+        # log exception
426
         logger.exception('search error')
463
         logger.exception('search error')
427
-        return render(
428
-            'index.html',
429
-        )
430
 
464
 
465
+        # is it an invalid input parameter or something else ?
466
+        if (issubclass(e.__class__, SearxParameterException)):
467
+            return index_error(output_format, e.message), 400
468
+        else:
469
+            return index_error(output_format, gettext('search error')), 500
470
+
471
+    # results
431
     results = result_container.get_ordered_results()
472
     results = result_container.get_ordered_results()
473
+    number_of_results = result_container.results_number()
474
+    if number_of_results < result_container.results_length():
475
+        number_of_results = 0
432
 
476
 
433
     # UI
477
     # UI
434
     advanced_search = request.form.get('advanced_search', None)
478
     advanced_search = request.form.get('advanced_search', None)
435
-    output_format = request.form.get('format', 'html')
436
-    if output_format not in ['html', 'csv', 'json', 'rss']:
437
-        output_format = 'html'
438
 
479
 
439
     # output
480
     # output
440
     for result in results:
481
     for result in results:
470
                 else:
511
                 else:
471
                     result['publishedDate'] = format_date(result['publishedDate'])
512
                     result['publishedDate'] = format_date(result['publishedDate'])
472
 
513
 
473
-    number_of_results = result_container.results_number()
474
-    if number_of_results < result_container.results_length():
475
-        number_of_results = 0
476
-
477
     if output_format == 'json':
514
     if output_format == 'json':
478
         return Response(json.dumps({'query': search_query.query,
515
         return Response(json.dumps({'query': search_query.query,
479
                                     'number_of_results': number_of_results,
516
                                     'number_of_results': number_of_results,
501
             results=results,
538
             results=results,
502
             q=request.form['q'],
539
             q=request.form['q'],
503
             number_of_results=number_of_results,
540
             number_of_results=number_of_results,
504
-            base_url=get_base_url()
541
+            base_url=get_base_url(),
542
+            override_theme='__common__',
505
         )
543
         )
506
         return Response(response_rss, mimetype='text/xml')
544
         return Response(response_rss, mimetype='text/xml')
507
 
545
 
722
     ret = render('opensearch.xml',
760
     ret = render('opensearch.xml',
723
                  opensearch_method=method,
761
                  opensearch_method=method,
724
                  host=get_base_url(),
762
                  host=get_base_url(),
725
-                 urljoin=urljoin)
763
+                 urljoin=urljoin,
764
+                 override_theme='__common__')
726
 
765
 
727
     resp = Response(response=ret,
766
     resp = Response(response=ret,
728
                     status=200,
767
                     status=200,

+ 2
- 0
tests/unit/test_webapp.py Прегледај датотеку

46
         Search.search = search_mock
46
         Search.search = search_mock
47
 
47
 
48
         def get_current_theme_name_mock(override=None):
48
         def get_current_theme_name_mock(override=None):
49
+            if override:
50
+                return override
49
             return 'legacy'
51
             return 'legacy'
50
 
52
 
51
         webapp.get_current_theme_name = get_current_theme_name_mock
53
         webapp.get_current_theme_name = get_current_theme_name_mock