Explorar el Código

Merge branch 'master' into http1.1

Alexandre Flament hace 8 años
padre
commit
a88768efd8
Se han modificado 87 ficheros con 624 adiciones y 117 borrados
  1. 5
    0
      .travis.yml
  2. 2
    0
      AUTHORS.rst
  3. 2
    2
      manage.sh
  4. 3
    3
      requirements-dev.txt
  5. 1
    1
      requirements.txt
  6. 9
    3
      searx/engines/__init__.py
  7. 1
    1
      searx/engines/digbt.py
  8. 11
    35
      searx/engines/kickass.py
  9. 109
    0
      searx/engines/pdbe.py
  10. 78
    0
      searx/engines/seedpeer.py
  11. 26
    1
      searx/settings.yml
  12. 3
    3
      searx/settings_robot.yml
  13. 0
    0
      searx/static/themes/legacy/css/style-rtl.css
  14. 0
    0
      searx/static/themes/legacy/css/style.css
  15. 0
    0
      searx/static/themes/legacy/img/favicon.png
  16. 0
    0
      searx/static/themes/legacy/img/github_ribbon.png
  17. 0
    0
      searx/static/themes/legacy/img/icons/icon_500px.ico
  18. 0
    0
      searx/static/themes/legacy/img/icons/icon_bing.ico
  19. 0
    0
      searx/static/themes/legacy/img/icons/icon_dailymotion.ico
  20. 0
    0
      searx/static/themes/legacy/img/icons/icon_deezer.ico
  21. 0
    0
      searx/static/themes/legacy/img/icons/icon_deviantart.ico
  22. 0
    0
      searx/static/themes/legacy/img/icons/icon_digg.ico
  23. 0
    0
      searx/static/themes/legacy/img/icons/icon_duckduckgo.ico
  24. 0
    0
      searx/static/themes/legacy/img/icons/icon_flickr.ico
  25. 0
    0
      searx/static/themes/legacy/img/icons/icon_github.ico
  26. 0
    0
      searx/static/themes/legacy/img/icons/icon_google play apps.ico
  27. 0
    0
      searx/static/themes/legacy/img/icons/icon_google play movies.ico
  28. 0
    0
      searx/static/themes/legacy/img/icons/icon_google play music.ico
  29. 0
    0
      searx/static/themes/legacy/img/icons/icon_google.ico
  30. 0
    0
      searx/static/themes/legacy/img/icons/icon_kickass.ico
  31. 0
    0
      searx/static/themes/legacy/img/icons/icon_openstreetmap.ico
  32. 0
    0
      searx/static/themes/legacy/img/icons/icon_searchcode code.ico
  33. 0
    0
      searx/static/themes/legacy/img/icons/icon_searchcode doc.ico
  34. 0
    0
      searx/static/themes/legacy/img/icons/icon_searchcode.ico
  35. 0
    0
      searx/static/themes/legacy/img/icons/icon_soundcloud.ico
  36. 0
    0
      searx/static/themes/legacy/img/icons/icon_stackoverflow.ico
  37. 0
    0
      searx/static/themes/legacy/img/icons/icon_startpage.ico
  38. 0
    0
      searx/static/themes/legacy/img/icons/icon_subtitleseeker.ico
  39. 0
    0
      searx/static/themes/legacy/img/icons/icon_twitter.ico
  40. 0
    0
      searx/static/themes/legacy/img/icons/icon_vimeo.ico
  41. 0
    0
      searx/static/themes/legacy/img/icons/icon_wikipedia.ico
  42. 0
    0
      searx/static/themes/legacy/img/icons/icon_yahoo.ico
  43. 0
    0
      searx/static/themes/legacy/img/icons/icon_youtube.ico
  44. 0
    0
      searx/static/themes/legacy/img/preference-icon.png
  45. 0
    0
      searx/static/themes/legacy/img/search-icon.png
  46. 0
    0
      searx/static/themes/legacy/img/searx.png
  47. 0
    0
      searx/static/themes/legacy/img/searx_logo.svg
  48. 0
    0
      searx/static/themes/legacy/js/searx.js
  49. 0
    0
      searx/static/themes/legacy/less/autocompleter.less
  50. 0
    0
      searx/static/themes/legacy/less/code.less
  51. 0
    0
      searx/static/themes/legacy/less/definitions.less
  52. 0
    0
      searx/static/themes/legacy/less/mixins.less
  53. 0
    0
      searx/static/themes/legacy/less/search.less
  54. 0
    0
      searx/static/themes/legacy/less/style-rtl.less
  55. 0
    0
      searx/static/themes/legacy/less/style.less
  56. 1
    1
      searx/templates/courgette/base.html
  57. 1
    1
      searx/templates/legacy/404.html
  58. 2
    2
      searx/templates/legacy/about.html
  59. 1
    1
      searx/templates/legacy/base.html
  60. 0
    0
      searx/templates/legacy/categories.html
  61. 0
    0
      searx/templates/legacy/github_ribbon.html
  62. 3
    3
      searx/templates/legacy/index.html
  63. 0
    0
      searx/templates/legacy/infobox.html
  64. 0
    0
      searx/templates/legacy/opensearch.xml
  65. 0
    0
      searx/templates/legacy/opensearch_response_rss.xml
  66. 2
    2
      searx/templates/legacy/preferences.html
  67. 0
    0
      searx/templates/legacy/result_templates/code.html
  68. 0
    0
      searx/templates/legacy/result_templates/default.html
  69. 0
    0
      searx/templates/legacy/result_templates/images.html
  70. 0
    0
      searx/templates/legacy/result_templates/map.html
  71. 0
    0
      searx/templates/legacy/result_templates/torrent.html
  72. 0
    0
      searx/templates/legacy/result_templates/videos.html
  73. 5
    5
      searx/templates/legacy/results.html
  74. 1
    1
      searx/templates/legacy/search.html
  75. 1
    1
      searx/templates/legacy/stats.html
  76. 6
    0
      searx/templates/oscar/macros.html
  77. 1
    1
      searx/templates/pix-art/preferences.html
  78. 1
    1
      searx/templates/pix-art/stats.html
  79. 15
    0
      searx/utils.py
  80. 22
    5
      searx/webapp.py
  81. 24
    28
      tests/robot/test_basic.robot
  82. 110
    0
      tests/unit/engines/seedpeer_fixture.html
  83. 3
    1
      tests/unit/engines/test_digbt.py
  84. 13
    13
      tests/unit/engines/test_kickass.py
  85. 109
    0
      tests/unit/engines/test_pdbe.py
  86. 51
    0
      tests/unit/engines/test_seedpeer.py
  87. 2
    2
      tests/unit/test_webapp.py

+ 5
- 0
.travis.yml Ver fichero

@@ -4,6 +4,8 @@ cache:
4 4
   - npm
5 5
   - directories:
6 6
     - $HOME/.cache/pip
7
+addons:
8
+  firefox: "latest"
7 9
 language: python
8 10
 python:
9 11
   - "2.7"
@@ -12,6 +14,9 @@ before_install:
12 14
   - "sh -e /etc/init.d/xvfb start"
13 15
   - npm install less grunt-cli
14 16
   - ( cd searx/static/themes/oscar;npm install; cd - )
17
+  - mkdir -p ~/drivers; export PATH=~/drivers:$PATH;
18
+  - GECKODRIVER_URL="https://github.com/mozilla/geckodriver/releases/download/v0.11.1/geckodriver-v0.11.1-linux64.tar.gz";
19
+  - FILE=`mktemp`; wget "$GECKODRIVER_URL" -qO $FILE && tar xz -C ~/drivers -f $FILE geckodriver; rm $FILE; chmod 777 ~/drivers/geckodriver;
15 20
 install:
16 21
   - ./manage.sh update_dev_packages
17 22
   - pip install coveralls

+ 2
- 0
AUTHORS.rst Ver fichero

@@ -58,3 +58,5 @@ generally made searx better:
58 58
 - marc @a01200356
59 59
 - Harry Wood @harry-wood
60 60
 - Thomas Renard @threnard
61
+- Pydo `<https://github.com/pydo>`_
62
+- Athemis `<https://github.com/Athemis>`_

+ 2
- 2
manage.sh Ver fichero

@@ -53,8 +53,8 @@ build_style() {
53 53
 
54 54
 styles() {
55 55
     echo '[!] Building styles'
56
-	build_style themes/default/less/style.less themes/default/css/style.css
57
-	build_style themes/default/less/style-rtl.less themes/default/css/style-rtl.css
56
+	build_style themes/legacy/less/style.less themes/legacy/css/style.css
57
+	build_style themes/legacy/less/style-rtl.less themes/legacy/css/style-rtl.css
58 58
 	build_style themes/courgette/less/style.less themes/courgette/css/style.css
59 59
 	build_style themes/courgette/less/style-rtl.less themes/courgette/css/style-rtl.css
60 60
 	build_style less/bootstrap/bootstrap.less css/bootstrap.min.css

+ 3
- 3
requirements-dev.txt Ver fichero

@@ -3,8 +3,8 @@ mock==2.0.0
3 3
 nose2[coverage-plugin]
4 4
 pep8==1.7.0
5 5
 plone.testing==5.0.0
6
-robotframework-selenium2library==1.7.4
6
+robotframework-selenium2library==1.8.0
7 7
 robotsuite==1.7.0
8
-transifex-client==0.11
8
+transifex-client==0.12.2
9 9
 unittest2==1.1.0
10
-zope.testrunner==4.4.10
10
+zope.testrunner==4.5.1

+ 1
- 1
requirements.txt Ver fichero

@@ -1,4 +1,4 @@
1
-certifi==2016.2.28
1
+certifi==2016.9.26
2 2
 flask==0.11.1
3 3
 flask-babel==0.11.1
4 4
 lxml==3.6.0

+ 9
- 3
searx/engines/__init__.py Ver fichero

@@ -57,11 +57,17 @@ def load_module(filename):
57 57
 
58 58
 
59 59
 def load_engine(engine_data):
60
-    engine_name = engine_data['engine']
60
+
61
+    if '_' in engine_data['name']:
62
+        logger.error('Engine name conains underscore: "{}"'.format(engine_data['name']))
63
+        sys.exit(1)
64
+
65
+    engine_module = engine_data['engine']
66
+
61 67
     try:
62
-        engine = load_module(engine_name + '.py')
68
+        engine = load_module(engine_module + '.py')
63 69
     except:
64
-        logger.exception('Cannot load engine "{}"'.format(engine_name))
70
+        logger.exception('Cannot load engine "{}"'.format(engine_module))
65 71
         return None
66 72
 
67 73
     for param_name in engine_data:

+ 1
- 1
searx/engines/digbt.py Ver fichero

@@ -40,7 +40,7 @@ def response(resp):
40 40
     results = list()
41 41
     for result in search_res:
42 42
         url = urljoin(URL, result.xpath('.//a[@title]/@href')[0])
43
-        title = result.xpath('.//a[@title]/text()')[0]
43
+        title = extract_text(result.xpath('.//a[@title]'))
44 44
         content = extract_text(result.xpath('.//div[@class="files"]'))
45 45
         files_data = extract_text(result.xpath('.//div[@class="tail"]')).split()
46 46
         filesize = get_torrent_size(files_data[FILESIZE], files_data[FILESIZE_MULTIPLIER])

+ 11
- 35
searx/engines/kickass.py Ver fichero

@@ -16,13 +16,14 @@ from urllib import quote
16 16
 from lxml import html
17 17
 from operator import itemgetter
18 18
 from searx.engines.xpath import extract_text
19
+from searx.utils import get_torrent_size, convert_str_to_int
19 20
 
20 21
 # engine dependent config
21 22
 categories = ['videos', 'music', 'files']
22 23
 paging = True
23 24
 
24 25
 # search-url
25
-url = 'https://kickass.to/'
26
+url = 'https://kickass.cd/'
26 27
 search_url = url + 'search/{search_term}/{pageno}/'
27 28
 
28 29
 # specific xpath variables
@@ -57,41 +58,16 @@ def response(resp):
57 58
         href = urljoin(url, link.attrib['href'])
58 59
         title = extract_text(link)
59 60
         content = escape(extract_text(result.xpath(content_xpath)))
60
-        seed = result.xpath('.//td[contains(@class, "green")]/text()')[0]
61
-        leech = result.xpath('.//td[contains(@class, "red")]/text()')[0]
62
-        filesize = result.xpath('.//td[contains(@class, "nobr")]/text()')[0]
63
-        filesize_multiplier = result.xpath('.//td[contains(@class, "nobr")]//span/text()')[0]
64
-        files = result.xpath('.//td[contains(@class, "center")][2]/text()')[0]
65
-
66
-        # convert seed to int if possible
67
-        if seed.isdigit():
68
-            seed = int(seed)
69
-        else:
70
-            seed = 0
61
+        seed = extract_text(result.xpath('.//td[contains(@class, "green")]'))
62
+        leech = extract_text(result.xpath('.//td[contains(@class, "red")]'))
63
+        filesize_info = extract_text(result.xpath('.//td[contains(@class, "nobr")]'))
64
+        files = extract_text(result.xpath('.//td[contains(@class, "center")][2]'))
71 65
 
72
-        # convert leech to int if possible
73
-        if leech.isdigit():
74
-            leech = int(leech)
75
-        else:
76
-            leech = 0
77
-
78
-        # convert filesize to byte if possible
79
-        try:
80
-            filesize = float(filesize)
81
-
82
-            # convert filesize to byte
83
-            if filesize_multiplier == 'TB':
84
-                filesize = int(filesize * 1024 * 1024 * 1024 * 1024)
85
-            elif filesize_multiplier == 'GB':
86
-                filesize = int(filesize * 1024 * 1024 * 1024)
87
-            elif filesize_multiplier == 'MB':
88
-                filesize = int(filesize * 1024 * 1024)
89
-            elif filesize_multiplier == 'KB':
90
-                filesize = int(filesize * 1024)
91
-        except:
92
-            filesize = None
93
-
94
-        # convert files to int if possible
66
+        seed = convert_str_to_int(seed)
67
+        leech = convert_str_to_int(leech)
68
+
69
+        filesize, filesize_multiplier = filesize_info.split()
70
+        filesize = get_torrent_size(filesize, filesize_multiplier)
95 71
         if files.isdigit():
96 72
             files = int(files)
97 73
         else:

+ 109
- 0
searx/engines/pdbe.py Ver fichero

@@ -0,0 +1,109 @@
1
+"""
2
+ PDBe (Protein Data Bank in Europe)
3
+
4
+ @website       https://www.ebi.ac.uk/pdbe
5
+ @provide-api   yes (https://www.ebi.ac.uk/pdbe/api/doc/search.html),
6
+                unlimited
7
+ @using-api     yes
8
+ @results       python dictionary (from json)
9
+ @stable        yes
10
+ @parse         url, title, content, img_src
11
+"""
12
+
13
+from json import loads
14
+from flask_babel import gettext
15
+
16
+categories = ['science']
17
+
18
+hide_obsolete = False
19
+
20
+# status codes of unpublished entries
21
+pdb_unpublished_codes = ['HPUB', 'HOLD', 'PROC', 'WAIT', 'AUTH', 'AUCO', 'REPL', 'POLC', 'REFI', 'TRSF', 'WDRN']
22
+# url for api query
23
+pdbe_solr_url = 'https://www.ebi.ac.uk/pdbe/search/pdb/select?'
24
+# base url for results
25
+pdbe_entry_url = 'https://www.ebi.ac.uk/pdbe/entry/pdb/{pdb_id}'
26
+# link to preview image of structure
27
+pdbe_preview_url = 'https://www.ebi.ac.uk/pdbe/static/entry/{pdb_id}_deposited_chain_front_image-200x200.png'
28
+
29
+
30
+def request(query, params):
31
+
32
+    params['url'] = pdbe_solr_url
33
+    params['method'] = 'POST'
34
+    params['data'] = {
35
+        'q': query,
36
+        'wt': "json"  # request response in parsable format
37
+    }
38
+    return params
39
+
40
+
41
+def construct_body(result):
42
+    # set title
43
+    title = result['title']
44
+
45
+    # construct content body
46
+    content = """{title}<br />{authors} {journal} <strong>{volume}</strong>&nbsp;{page} ({year})"""
47
+
48
+    # replace placeholders with actual content
49
+    try:
50
+        if result['journal']:
51
+            content = content.format(
52
+                title=result['citation_title'],
53
+                authors=result['entry_author_list'][0], journal=result['journal'], volume=result['journal_volume'],
54
+                page=result['journal_page'], year=result['citation_year'])
55
+        else:
56
+            content = content.format(
57
+                title=result['citation_title'],
58
+                authors=result['entry_author_list'][0], journal='', volume='', page='', year=result['release_year'])
59
+        img_src = pdbe_preview_url.format(pdb_id=result['pdb_id'])
60
+    except (KeyError):
61
+        content = None
62
+        img_src = None
63
+
64
+    # construct url for preview image
65
+    try:
66
+        img_src = pdbe_preview_url.format(pdb_id=result['pdb_id'])
67
+    except (KeyError):
68
+        img_src = None
69
+
70
+    return [title, content, img_src]
71
+
72
+
73
+def response(resp):
74
+
75
+    results = []
76
+    json = loads(resp.text)['response']['docs']
77
+
78
+    # parse results
79
+    for result in json:
80
+        # catch obsolete entries and mark them accordingly
81
+        if result['status'] in pdb_unpublished_codes:
82
+            continue
83
+        if hide_obsolete:
84
+            continue
85
+        if result['status'] == 'OBS':
86
+            # expand title to add some sort of warning message
87
+            title = gettext('{title}&nbsp;(OBSOLETE)').format(title=result['title'])
88
+            superseded_url = pdbe_entry_url.format(pdb_id=result['superseded_by'])
89
+
90
+            # since we can't construct a proper body from the response, we'll make up our own
91
+            msg_superseded = gettext("This entry has been superseded by")
92
+            content = '<em>{msg_superseded} \<a href="{url}">{pdb_id}</a></em>'.format(
93
+                msg_superseded=msg_superseded,
94
+                url=superseded_url,
95
+                pdb_id=result['superseded_by'], )
96
+
97
+            # obsoleted entries don't have preview images
98
+            img_src = None
99
+        else:
100
+            title, content, img_src = construct_body(result)
101
+
102
+        results.append({
103
+            'url': pdbe_entry_url.format(pdb_id=result['pdb_id']),
104
+            'title': title,
105
+            'content': content,
106
+            'img_src': img_src
107
+        })
108
+
109
+    return results

+ 78
- 0
searx/engines/seedpeer.py Ver fichero

@@ -0,0 +1,78 @@
1
+#  Seedpeer (Videos, Music, Files)
2
+#
3
+# @website     http://seedpeer.eu
4
+# @provide-api no (nothing found)
5
+#
6
+# @using-api   no
7
+# @results     HTML (using search portal)
8
+# @stable      yes (HTML can change)
9
+# @parse       url, title, content, seed, leech, magnetlink
10
+
11
+from urlparse import urljoin
12
+from cgi import escape
13
+from urllib import quote
14
+from lxml import html
15
+from operator import itemgetter
16
+from searx.engines.xpath import extract_text
17
+
18
+
19
+url = 'http://www.seedpeer.eu/'
20
+search_url = url + 'search/{search_term}/7/{page_no}.html'
21
+# specific xpath variables
22
+torrent_xpath = '//*[@id="body"]/center/center/table[2]/tr/td/a'
23
+alternative_torrent_xpath = '//*[@id="body"]/center/center/table[1]/tr/td/a'
24
+title_xpath = '//*[@id="body"]/center/center/table[2]/tr/td/a/text()'
25
+alternative_title_xpath = '//*[@id="body"]/center/center/table/tr/td/a'
26
+seeds_xpath = '//*[@id="body"]/center/center/table[2]/tr/td[4]/font/text()'
27
+alternative_seeds_xpath = '//*[@id="body"]/center/center/table/tr/td[4]/font/text()'
28
+peers_xpath = '//*[@id="body"]/center/center/table[2]/tr/td[5]/font/text()'
29
+alternative_peers_xpath = '//*[@id="body"]/center/center/table/tr/td[5]/font/text()'
30
+age_xpath = '//*[@id="body"]/center/center/table[2]/tr/td[2]/text()'
31
+alternative_age_xpath = '//*[@id="body"]/center/center/table/tr/td[2]/text()'
32
+size_xpath = '//*[@id="body"]/center/center/table[2]/tr/td[3]/text()'
33
+alternative_size_xpath = '//*[@id="body"]/center/center/table/tr/td[3]/text()'
34
+
35
+
36
+# do search-request
37
+def request(query, params):
38
+    params['url'] = search_url.format(search_term=quote(query),
39
+                                      page_no=params['pageno'] - 1)
40
+    return params
41
+
42
+
43
+# get response from search-request
44
+def response(resp):
45
+    results = []
46
+    dom = html.fromstring(resp.text)
47
+    torrent_links = dom.xpath(torrent_xpath)
48
+    if len(torrent_links) > 0:
49
+        seeds = dom.xpath(seeds_xpath)
50
+        peers = dom.xpath(peers_xpath)
51
+        titles = dom.xpath(title_xpath)
52
+        sizes = dom.xpath(size_xpath)
53
+        ages = dom.xpath(age_xpath)
54
+    else:  # under ~5 results uses a different xpath
55
+        torrent_links = dom.xpath(alternative_torrent_xpath)
56
+        seeds = dom.xpath(alternative_seeds_xpath)
57
+        peers = dom.xpath(alternative_peers_xpath)
58
+        titles = dom.xpath(alternative_title_xpath)
59
+        sizes = dom.xpath(alternative_size_xpath)
60
+        ages = dom.xpath(alternative_age_xpath)
61
+    # return empty array if nothing is found
62
+    if not torrent_links:
63
+        return []
64
+
65
+    # parse results
66
+    for index, result in enumerate(torrent_links):
67
+        link = result.attrib.get('href')
68
+        href = urljoin(url, link)
69
+        results.append({'url': href,
70
+                        'title': titles[index].text_content(),
71
+                        'content': '{}, {}'.format(sizes[index], ages[index]),
72
+                        'seed': seeds[index],
73
+                        'leech': peers[index],
74
+
75
+                        'template': 'torrent.html'})
76
+
77
+    # return results sorted by seeder
78
+    return sorted(results, key=itemgetter('seed'), reverse=True)

+ 26
- 1
searx/settings.yml Ver fichero

@@ -18,6 +18,12 @@ ui:
18 18
     default_theme : oscar # ui theme
19 19
     default_locale : "" # Default interface locale - leave blank to detect from browser information or use codes from the 'locales' config section
20 20
 
21
+# searx supports result proxification using an external service: https://github.com/asciimoo/morty
22
+# uncomment below section if you have running morty proxy
23
+#result_proxy:
24
+#    url : http://127.0.0.1:3000/
25
+#    key : your_morty_proxy_key
26
+
21 27
 outgoing: # communication with search engines
22 28
     request_timeout : 2.0 # seconds
23 29
     useragent_suffix : "" # suffix of searx_useragent, could contain informations like an email address to the administrator
@@ -301,6 +307,12 @@ engines:
301 307
     timeout : 6.0
302 308
     disabled : True
303 309
 
310
+  - name: kickass
311
+    engine : kickass
312
+    shortcut : kc
313
+    timeout : 4.0
314
+    disabled : True
315
+
304 316
   - name : microsoft academic
305 317
     engine : json_engine
306 318
     paging : True
@@ -339,6 +351,13 @@ engines:
339 351
     disabled : True
340 352
     shortcut : or
341 353
 
354
+  - name : pdbe
355
+    engine : pdbe
356
+    shortcut : pdb
357
+# Hide obsolete PDB entries.
358
+# Default is not to hide obsolete structures
359
+#    hide_obsolete : False
360
+
342 361
   - name : photon
343 362
     engine : photon
344 363
     shortcut : ph
@@ -377,7 +396,7 @@ engines:
377 396
     timeout : 10.0
378 397
     disabled : True
379 398
 
380
-  - name : scanr_structures
399
+  - name : scanr structures
381 400
     shortcut: scs
382 401
     engine : scanr_structures
383 402
     disabled : True
@@ -495,6 +514,12 @@ engines:
495 514
     timeout: 6.0
496 515
     categories : science
497 516
 
517
+  - name : seedpeer
518
+    engine : seedpeer
519
+    shortcut: speu
520
+    categories: files, music, videos
521
+    disabled: True
522
+
498 523
   - name : dictzone
499 524
     engine : dictzone
500 525
     shortcut : dc

+ 3
- 3
searx/settings_robot.yml Ver fichero

@@ -15,7 +15,7 @@ server:
15 15
 
16 16
 ui:
17 17
     themes_path : ""
18
-    default_theme : default
18
+    default_theme : legacy
19 19
     default_locale : ""
20 20
 
21 21
 outgoing:
@@ -23,12 +23,12 @@ outgoing:
23 23
     useragent_suffix : ""
24 24
 
25 25
 engines:
26
-  - name : general_dummy
26
+  - name : general dummy
27 27
     engine : dummy
28 28
     categories : general
29 29
     shortcut : gd
30 30
 
31
-  - name : dummy_dummy
31
+  - name : dummy dummy
32 32
     engine : dummy
33 33
     categories : dummy
34 34
     shortcut : dd

searx/static/themes/default/css/style-rtl.css → searx/static/themes/legacy/css/style-rtl.css Ver fichero


searx/static/themes/default/css/style.css → searx/static/themes/legacy/css/style.css Ver fichero


searx/static/themes/default/img/favicon.png → searx/static/themes/legacy/img/favicon.png Ver fichero


searx/static/themes/default/img/github_ribbon.png → searx/static/themes/legacy/img/github_ribbon.png Ver fichero


searx/static/themes/default/img/icons/icon_500px.ico → searx/static/themes/legacy/img/icons/icon_500px.ico Ver fichero


searx/static/themes/default/img/icons/icon_bing.ico → searx/static/themes/legacy/img/icons/icon_bing.ico Ver fichero


searx/static/themes/default/img/icons/icon_dailymotion.ico → searx/static/themes/legacy/img/icons/icon_dailymotion.ico Ver fichero


searx/static/themes/default/img/icons/icon_deezer.ico → searx/static/themes/legacy/img/icons/icon_deezer.ico Ver fichero


searx/static/themes/default/img/icons/icon_deviantart.ico → searx/static/themes/legacy/img/icons/icon_deviantart.ico Ver fichero


searx/static/themes/default/img/icons/icon_digg.ico → searx/static/themes/legacy/img/icons/icon_digg.ico Ver fichero


searx/static/themes/default/img/icons/icon_duckduckgo.ico → searx/static/themes/legacy/img/icons/icon_duckduckgo.ico Ver fichero


searx/static/themes/default/img/icons/icon_flickr.ico → searx/static/themes/legacy/img/icons/icon_flickr.ico Ver fichero


searx/static/themes/default/img/icons/icon_github.ico → searx/static/themes/legacy/img/icons/icon_github.ico Ver fichero


searx/static/themes/default/img/icons/icon_google play apps.ico → searx/static/themes/legacy/img/icons/icon_google play apps.ico Ver fichero


searx/static/themes/default/img/icons/icon_google play movies.ico → searx/static/themes/legacy/img/icons/icon_google play movies.ico Ver fichero


searx/static/themes/default/img/icons/icon_google play music.ico → searx/static/themes/legacy/img/icons/icon_google play music.ico Ver fichero


searx/static/themes/default/img/icons/icon_google.ico → searx/static/themes/legacy/img/icons/icon_google.ico Ver fichero


searx/static/themes/default/img/icons/icon_kickass.ico → searx/static/themes/legacy/img/icons/icon_kickass.ico Ver fichero


searx/static/themes/default/img/icons/icon_openstreetmap.ico → searx/static/themes/legacy/img/icons/icon_openstreetmap.ico Ver fichero


searx/static/themes/default/img/icons/icon_searchcode code.ico → searx/static/themes/legacy/img/icons/icon_searchcode code.ico Ver fichero


searx/static/themes/default/img/icons/icon_searchcode doc.ico → searx/static/themes/legacy/img/icons/icon_searchcode doc.ico Ver fichero


searx/static/themes/default/img/icons/icon_searchcode.ico → searx/static/themes/legacy/img/icons/icon_searchcode.ico Ver fichero


searx/static/themes/default/img/icons/icon_soundcloud.ico → searx/static/themes/legacy/img/icons/icon_soundcloud.ico Ver fichero


searx/static/themes/default/img/icons/icon_stackoverflow.ico → searx/static/themes/legacy/img/icons/icon_stackoverflow.ico Ver fichero


searx/static/themes/default/img/icons/icon_startpage.ico → searx/static/themes/legacy/img/icons/icon_startpage.ico Ver fichero


searx/static/themes/default/img/icons/icon_subtitleseeker.ico → searx/static/themes/legacy/img/icons/icon_subtitleseeker.ico Ver fichero


searx/static/themes/default/img/icons/icon_twitter.ico → searx/static/themes/legacy/img/icons/icon_twitter.ico Ver fichero


searx/static/themes/default/img/icons/icon_vimeo.ico → searx/static/themes/legacy/img/icons/icon_vimeo.ico Ver fichero


searx/static/themes/default/img/icons/icon_wikipedia.ico → searx/static/themes/legacy/img/icons/icon_wikipedia.ico Ver fichero


searx/static/themes/default/img/icons/icon_yahoo.ico → searx/static/themes/legacy/img/icons/icon_yahoo.ico Ver fichero


searx/static/themes/default/img/icons/icon_youtube.ico → searx/static/themes/legacy/img/icons/icon_youtube.ico Ver fichero


searx/static/themes/default/img/preference-icon.png → searx/static/themes/legacy/img/preference-icon.png Ver fichero


searx/static/themes/default/img/search-icon.png → searx/static/themes/legacy/img/search-icon.png Ver fichero


searx/static/themes/default/img/searx.png → searx/static/themes/legacy/img/searx.png Ver fichero


searx/static/themes/default/img/searx_logo.svg → searx/static/themes/legacy/img/searx_logo.svg Ver fichero


searx/static/themes/default/js/searx.js → searx/static/themes/legacy/js/searx.js Ver fichero


searx/static/themes/default/less/autocompleter.less → searx/static/themes/legacy/less/autocompleter.less Ver fichero


searx/static/themes/default/less/code.less → searx/static/themes/legacy/less/code.less Ver fichero


searx/static/themes/default/less/definitions.less → searx/static/themes/legacy/less/definitions.less Ver fichero


searx/static/themes/default/less/mixins.less → searx/static/themes/legacy/less/mixins.less Ver fichero


searx/static/themes/default/less/search.less → searx/static/themes/legacy/less/search.less Ver fichero


searx/static/themes/default/less/style-rtl.less → searx/static/themes/legacy/less/style-rtl.less Ver fichero


searx/static/themes/default/less/style.less → searx/static/themes/legacy/less/style.less Ver fichero


+ 1
- 1
searx/templates/courgette/base.html Ver fichero

@@ -22,7 +22,7 @@
22 22
         {% endblock %}
23 23
         {% block meta %}{% endblock %}
24 24
         {% block head %}
25
-        <link title="searx" type="application/opensearchdescription+xml" rel="search" href="{{ url_for('opensearch') }}"/>
25
+        <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ url_for('opensearch') }}"/>
26 26
         {% endblock %}
27 27
         <script type="text/javascript">
28 28
             searx = {};

searx/templates/default/404.html → searx/templates/legacy/404.html Ver fichero

@@ -1,4 +1,4 @@
1
-{% extends "default/base.html" %}
1
+{% extends "legacy/base.html" %}
2 2
 {% block content %}
3 3
 <div class="center">
4 4
     <h1>{{ _('Page not found') }}</h1>

searx/templates/default/about.html → searx/templates/legacy/about.html Ver fichero

@@ -1,6 +1,6 @@
1
-{% extends 'default/base.html' %}
1
+{% extends 'legacy/base.html' %}
2 2
 {% block content %}
3
-{% include 'default/github_ribbon.html' %}
3
+{% include 'legacy/github_ribbon.html' %}
4 4
 <div class="row"{% if rtl %} dir="ltr"{% endif %}>
5 5
     <h1>About <a href="{{ url_for('index') }}">searx</a></h1>
6 6
 

searx/templates/default/base.html → searx/templates/legacy/base.html Ver fichero

@@ -17,7 +17,7 @@
17 17
         {% endblock %}
18 18
         {% block meta %}{% endblock %}
19 19
         {% block head %}
20
-        <link title="searx" type="application/opensearchdescription+xml" rel="search" href="{{ url_for('opensearch') }}"/>
20
+        <link title="{{ instance_name }}" type="application/opensearchdescription+xml" rel="search" href="{{ url_for('opensearch') }}"/>
21 21
         {% endblock %}
22 22
     </head>
23 23
     <body>

searx/templates/default/categories.html → searx/templates/legacy/categories.html Ver fichero


searx/templates/default/github_ribbon.html → searx/templates/legacy/github_ribbon.html Ver fichero


searx/templates/default/index.html → searx/templates/legacy/index.html Ver fichero

@@ -1,8 +1,8 @@
1
-{% extends "default/base.html" %}
1
+{% extends "legacy/base.html" %}
2 2
 {% block content %}
3 3
 <div class="center">
4 4
     <div class="title"><h1>searx</h1></div>
5
-    {% include 'default/search.html' %}
5
+    {% include 'legacy/search.html' %}
6 6
     <p class="top_margin">
7 7
     	{% if rtl %}
8 8
     	<a href="{{ url_for('preferences') }}" class="hmarg">{{ _('preferences') }}</a>
@@ -13,6 +13,6 @@
13 13
         {% endif %}
14 14
     </p>
15 15
 </div>
16
-{% include 'default/github_ribbon.html' %}
16
+{% include 'legacy/github_ribbon.html' %}
17 17
 {% endblock %}
18 18
 

searx/templates/default/infobox.html → searx/templates/legacy/infobox.html Ver fichero


searx/templates/default/opensearch.xml → searx/templates/legacy/opensearch.xml Ver fichero


searx/templates/default/opensearch_response_rss.xml → searx/templates/legacy/opensearch_response_rss.xml Ver fichero


searx/templates/default/preferences.html → searx/templates/legacy/preferences.html Ver fichero

@@ -1,4 +1,4 @@
1
-{% extends "default/base.html" %}
1
+{% extends "legacy/base.html" %}
2 2
 {% block head %} {% endblock %}
3 3
 {% block content %}
4 4
 <div class="row">
@@ -8,7 +8,7 @@
8 8
     <fieldset>
9 9
         <legend>{{ _('Default categories') }}</legend>
10 10
         {% set display_tooltip = false %}
11
-        {% include 'default/categories.html' %}
11
+        {% include 'legacy/categories.html' %}
12 12
     </fieldset>
13 13
     <fieldset>
14 14
         <legend>{{ _('Search language') }}</legend>

searx/templates/default/result_templates/code.html → searx/templates/legacy/result_templates/code.html Ver fichero


searx/templates/default/result_templates/default.html → searx/templates/legacy/result_templates/default.html Ver fichero


searx/templates/default/result_templates/images.html → searx/templates/legacy/result_templates/images.html Ver fichero


searx/templates/default/result_templates/map.html → searx/templates/legacy/result_templates/map.html Ver fichero


searx/templates/default/result_templates/torrent.html → searx/templates/legacy/result_templates/torrent.html Ver fichero


searx/templates/default/result_templates/videos.html → searx/templates/legacy/result_templates/videos.html Ver fichero


searx/templates/default/results.html → searx/templates/legacy/results.html Ver fichero

@@ -1,10 +1,10 @@
1
-{% extends "default/base.html" %}
1
+{% extends "legacy/base.html" %}
2 2
 {% block title %}{{ q }} - {% endblock %}
3 3
 {% block meta %}<link rel="alternate" type="application/rss+xml" title="Searx search: {{ q }}" href="{{ url_for('index') }}?q={{ q|urlencode }}&amp;format=rss&amp;{% for category in selected_categories %}category_{{ category }}=1&amp;{% endfor %}pageno={{ pageno }}">{% endblock %}
4 4
 {% block content %}
5 5
 <div class="preferences_container right"><a href="{{ url_for('preferences') }}" id="preferences"><span>preferences</span></a></div>
6 6
 <div class="small search center">
7
-    {% include 'default/search.html' %}
7
+    {% include 'legacy/search.html' %}
8 8
 </div>
9 9
 <div id="results">
10 10
     <div id="sidebar">
@@ -55,16 +55,16 @@
55 55
     {% if infoboxes %}
56 56
     <div id="infoboxes">
57 57
       {% for infobox in infoboxes %}
58
-         {% include 'default/infobox.html' %}
58
+         {% include 'legacy/infobox.html' %}
59 59
       {% endfor %}
60 60
     </div>
61 61
     {% endif %}
62 62
 
63 63
     {% for result in results %}
64 64
         {% if result['template'] %}
65
-            {% include get_result_template('default', result['template']) %}
65
+            {% include get_result_template('legacy', result['template']) %}
66 66
         {% else %}
67
-            {% include 'default/result_templates/default.html' %}
67
+            {% include 'legacy/result_templates/default.html' %}
68 68
         {% endif %}
69 69
     {% endfor %}
70 70
 

searx/templates/default/search.html → searx/templates/legacy/search.html Ver fichero

@@ -4,5 +4,5 @@
4 4
         <input type="submit" value="search" id="search_submit" />
5 5
     </div>
6 6
     {% set display_tooltip = true %}
7
-    {% include 'default/categories.html' %}
7
+    {% include 'legacy/categories.html' %}
8 8
 </form>

searx/templates/default/stats.html → searx/templates/legacy/stats.html Ver fichero

@@ -1,4 +1,4 @@
1
-{% extends "default/base.html" %}
1
+{% extends "legacy/base.html" %}
2 2
 {% block head %} {% endblock %}
3 3
 {% block content %}
4 4
 <h2>{{ _('Engine stats') }}</h2>

+ 6
- 0
searx/templates/oscar/macros.html Ver fichero

@@ -33,6 +33,9 @@
33 33
         <span class="label label-default">{{ engine }}</span>
34 34
     {% endfor %}
35 35
     <small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info") }}</small>
36
+    {% if proxify %}
37
+    <small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small>
38
+    {% endif %}
36 39
 </div>
37 40
     <div class="text-muted"><small>{{ result.pretty_url }}</small></div>
38 41
 {%- endmacro %}
@@ -44,6 +47,9 @@
44 47
         <span class="label label-default">{{ engine }}</span>
45 48
     {% endfor %}
46 49
     <small>{{ result_link("https://web.archive.org/web/" + result.url, icon('link') + _('cached'), "text-info") }}</small>
50
+    {% if proxify %}
51
+    <small>{{ result_link(proxify(result.url), icon('sort') + _('proxied'), "text-info") }}</small>
52
+    {% endif %}
47 53
     <div class="text-muted"><small>{{ result.pretty_url }}</small></div>
48 54
 {%- endmacro %}
49 55
 

+ 1
- 1
searx/templates/pix-art/preferences.html Ver fichero

@@ -1,4 +1,4 @@
1
-{% extends "default/base.html" %}
1
+{% extends "legacy/base.html" %}
2 2
 {% block head %} {% endblock %}
3 3
 {% block content %}
4 4
 <div class="row">

+ 1
- 1
searx/templates/pix-art/stats.html Ver fichero

@@ -1,4 +1,4 @@
1
-{% extends "default/base.html" %}
1
+{% extends "legacy/base.html" %}
2 2
 {% block head %} {% endblock %}
3 3
 {% block content %}
4 4
 <h2>{{ _('Engine stats') }}</h2>

+ 15
- 0
searx/utils.py Ver fichero

@@ -252,12 +252,27 @@ def get_torrent_size(filesize, filesize_multiplier):
252 252
             filesize = int(filesize * 1024 * 1024)
253 253
         elif filesize_multiplier == 'KB':
254 254
             filesize = int(filesize * 1024)
255
+        elif filesize_multiplier == 'TiB':
256
+            filesize = int(filesize * 1000 * 1000 * 1000 * 1000)
257
+        elif filesize_multiplier == 'GiB':
258
+            filesize = int(filesize * 1000 * 1000 * 1000)
259
+        elif filesize_multiplier == 'MiB':
260
+            filesize = int(filesize * 1000 * 1000)
261
+        elif filesize_multiplier == 'KiB':
262
+            filesize = int(filesize * 1000)
255 263
     except:
256 264
         filesize = None
257 265
 
258 266
     return filesize
259 267
 
260 268
 
269
+def convert_str_to_int(number_str):
270
+    if number_str.isdigit():
271
+        return int(number_str)
272
+    else:
273
+        return 0
274
+
275
+
261 276
 def is_valid_lang(lang):
262 277
     is_abbr = (len(lang) == 2)
263 278
     if is_abbr:

+ 22
- 5
searx/webapp.py Ver fichero

@@ -22,10 +22,11 @@ if __name__ == '__main__':
22 22
     from os.path import realpath, dirname
23 23
     path.append(realpath(dirname(realpath(__file__)) + '/../'))
24 24
 
25
-import json
26 25
 import cStringIO
27
-import os
28 26
 import hashlib
27
+import hmac
28
+import json
29
+import os
29 30
 import requests
30 31
 
31 32
 from searx import logger
@@ -245,6 +246,20 @@ def url_for_theme(endpoint, override_theme=None, **values):
245 246
     return url_for(endpoint, **values)
246 247
 
247 248
 
249
+def proxify(url):
250
+    if url.startswith('//'):
251
+        url = 'https:' + url
252
+
253
+    if not settings.get('result_proxy'):
254
+        return url
255
+
256
+    h = hmac.new(settings['result_proxy']['key'], url.encode('utf-8'), hashlib.sha256).hexdigest()
257
+
258
+    return '{0}?{1}'.format(settings['result_proxy']['url'],
259
+                            urlencode(dict(mortyurl=url.encode('utf-8'),
260
+                                           mortyhash=h)))
261
+
262
+
248 263
 def image_proxify(url):
249 264
 
250 265
     if url.startswith('//'):
@@ -253,8 +268,7 @@ def image_proxify(url):
253 268
     if not request.preferences.get_value('image_proxy'):
254 269
         return url
255 270
 
256
-    hash_string = url + settings['server']['secret_key']
257
-    h = hashlib.sha256(hash_string.encode('utf-8')).hexdigest()
271
+    h = hmac.new(settings['server']['secret_key'], url.encode('utf-8'), hashlib.sha256).hexdigest()
258 272
 
259 273
     return '{0}?{1}'.format(url_for('image_proxy'),
260 274
                             urlencode(dict(url=url.encode('utf-8'), h=h)))
@@ -313,6 +327,8 @@ def render(template_name, override_theme=None, **kwargs):
313 327
 
314 328
     kwargs['image_proxify'] = image_proxify
315 329
 
330
+    kwargs['proxify'] = proxify if settings.get('result_proxy') else None
331
+
316 332
     kwargs['get_result_template'] = get_result_template
317 333
 
318 334
     kwargs['theme'] = get_current_theme_name(override=override_theme)
@@ -602,7 +618,7 @@ def image_proxy():
602 618
     if not url:
603 619
         return '', 400
604 620
 
605
-    h = hashlib.sha256(url + settings['server']['secret_key'].encode('utf-8')).hexdigest()
621
+    h = hmac.new(settings['server']['secret_key'], url, hashlib.sha256).hexdigest()
606 622
 
607 623
     if h != request.args.get('h'):
608 624
         return '', 400
@@ -660,6 +676,7 @@ Allow: /
660 676
 Allow: /about
661 677
 Disallow: /stats
662 678
 Disallow: /preferences
679
+Disallow: /*?*q=*
663 680
 """, mimetype='text/plain')
664 681
 
665 682
 

+ 24
- 28
tests/robot/test_basic.robot Ver fichero

@@ -4,6 +4,14 @@ Test Setup      Open Browser  http://localhost:11111/
4 4
 Test Teardown   Close All Browsers
5 5
 
6 6
 
7
+*** Keywords ***
8
+Submit Preferences
9
+    Set Selenium Speed  2 seconds
10
+    Submit Form  id=search_form
11
+    Location Should Be  http://localhost:11111/
12
+    Set Selenium Speed  0 seconds
13
+
14
+
7 15
 *** Test Cases ***
8 16
 Front page
9 17
     Page Should Contain  about
@@ -24,8 +32,8 @@ Preferences page
24 32
     Page Should Contain  Preferences
25 33
     Page Should Contain  Default categories
26 34
     Page Should Contain  Currently used search engines
27
-    Page Should Contain  dummy_dummy
28
-    Page Should Contain  general_dummy
35
+    Page Should Contain  dummy dummy
36
+    Page Should Contain  general dummy
29 37
 
30 38
 Switch category
31 39
     Go To  http://localhost:11111/preferences
@@ -33,8 +41,7 @@ Switch category
33 41
     Page Should Contain Checkbox  category_dummy
34 42
     Click Element  xpath=//*[.="general"]
35 43
     Click Element  xpath=//*[.="dummy"]
36
-    Submit Form  id=search_form
37
-    Location Should Be  http://localhost:11111/
44
+    Submit Preferences
38 45
     Checkbox Should Not Be Selected  category_general
39 46
     Checkbox Should Be Selected  category_dummy
40 47
 
@@ -43,8 +50,7 @@ Change language
43 50
     Page Should Contain  preferences
44 51
     Go To  http://localhost:11111/preferences
45 52
     Select From List  locale  hu
46
-    Submit Form  id=search_form
47
-    Location Should Be  http://localhost:11111/
53
+    Submit Preferences
48 54
     Page Should Contain  rólunk
49 55
     Page Should Contain  beállítások
50 56
 
@@ -53,13 +59,11 @@ Change method
53 59
     Page Should Contain  preferences
54 60
     Go To  http://localhost:11111/preferences
55 61
     Select From List  method  GET
56
-    Submit Form  id=search_form
57
-    Location Should Be  http://localhost:11111/
62
+    Submit Preferences
58 63
     Go To  http://localhost:11111/preferences
59 64
     List Selection Should Be  method  GET
60 65
     Select From List  method  POST
61
-    Submit Form  id=search_form
62
-    Location Should Be  http://localhost:11111/
66
+    Submit Preferences
63 67
     Go To  http://localhost:11111/preferences
64 68
     List Selection Should Be  method  POST
65 69
 
@@ -67,10 +71,9 @@ Change theme
67 71
     Page Should Contain  about
68 72
     Page Should Contain  preferences
69 73
     Go To  http://localhost:11111/preferences
70
-    List Selection Should Be  theme  default
74
+    List Selection Should Be  theme  legacy
71 75
     Select From List  theme  oscar
72
-    Submit Form  id=search_form
73
-    Location Should Be  http://localhost:11111/
76
+    Submit Preferences
74 77
     Go To  http://localhost:11111/preferences
75 78
     List Selection Should Be  theme  oscar
76 79
 
@@ -80,8 +83,7 @@ Change safesearch
80 83
     Go To  http://localhost:11111/preferences
81 84
     List Selection Should Be  safesearch  None
82 85
     Select From List  safesearch  Strict
83
-    Submit Form  id=search_form
84
-    Location Should Be  http://localhost:11111/
86
+    Submit Preferences
85 87
     Go To  http://localhost:11111/preferences
86 88
     List Selection Should Be  safesearch  Strict
87 89
 
@@ -91,8 +93,7 @@ Change image proxy
91 93
     Go To  http://localhost:11111/preferences
92 94
     List Selection Should Be  image_proxy  Disabled
93 95
     Select From List  image_proxy  Enabled
94
-    Submit Form  id=search_form
95
-    Location Should Be  http://localhost:11111/
96
+    Submit Preferences
96 97
     Go To  http://localhost:11111/preferences
97 98
     List Selection Should Be  image_proxy  Enabled
98 99
 
@@ -102,8 +103,7 @@ Change search language
102 103
     Go To  http://localhost:11111/preferences
103 104
     List Selection Should Be  language  Automatic
104 105
     Select From List  language  Turkish (Turkey) - tr_TR
105
-    Submit Form  id=search_form
106
-    Location Should Be  http://localhost:11111/
106
+    Submit Preferences
107 107
     Go To  http://localhost:11111/preferences
108 108
     List Selection Should Be  language  Turkish (Turkey) - tr_TR
109 109
 
@@ -113,8 +113,7 @@ Change autocomplete
113 113
     Go To  http://localhost:11111/preferences
114 114
     List Selection Should Be  autocomplete  -
115 115
     Select From List  autocomplete  google
116
-    Submit Form  id=search_form
117
-    Location Should Be  http://localhost:11111/
116
+    Submit Preferences
118 117
     Go To  http://localhost:11111/preferences
119 118
     List Selection Should Be  autocomplete  google
120 119
 
@@ -126,8 +125,7 @@ Change allowed/disabled engines
126 125
     Element Should Contain  xpath=//label[@class="deny"][@for='engine_dummy_dummy_dummy']  Block
127 126
     Element Should Contain  xpath=//label[@class="deny"][@for='engine_general_general_dummy']  Block
128 127
     Click Element  xpath=//label[@class="deny"][@for='engine_general_general_dummy']
129
-    Submit Form  id=search_form
130
-    Location Should Be  http://localhost:11111/
128
+    Submit Preferences
131 129
     Page Should Contain  about
132 130
     Page Should Contain  preferences
133 131
     Go To  http://localhost:11111/preferences
@@ -139,18 +137,16 @@ Block a plugin
139 137
     Page Should Contain  about
140 138
     Page Should Contain  preferences
141 139
     Go To  http://localhost:11111/preferences
142
-    List Selection Should Be  theme  default
140
+    List Selection Should Be  theme  legacy
143 141
     Select From List  theme  oscar
144
-    Submit Form  id=search_form
145
-    Location Should Be  http://localhost:11111/
142
+    Submit Preferences
146 143
     Go To  http://localhost:11111/preferences
147 144
     List Selection Should Be  theme  oscar
148 145
     Page Should Contain  Plugins
149 146
     Click Link  Plugins
150 147
     Checkbox Should Not Be Selected  id=plugin_HTTPS_rewrite
151 148
     Click Element  xpath=//label[@for='plugin_HTTPS_rewrite']
152
-    Submit Form  id=search_form
153
-    Location Should Be  http://localhost:11111/
149
+    Submit Preferences
154 150
     Go To  http://localhost:11111/preferences
155 151
     Page Should Contain  Plugins
156 152
     Click Link  Plugins

+ 110
- 0
tests/unit/engines/seedpeer_fixture.html Ver fichero

@@ -0,0 +1,110 @@
1
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2
+        <html xmlns="http://www.w3.org/1999/xhtml">
3
+        <head>
4
+        </head>
5
+        <body>
6
+            <div id="header">
7
+                <div id="whoIsYou">
8
+                        <a href="/lang.php"><small>SeedPeer in your own language?</small></a>&nbsp;&nbsp;&nbsp;<a href="http://www.seedpeer.eu"><img src="/images/flags/uk.gif" width="16px" alt="Torrents EN" /></a> <a href="http://spanish.seedpeer.eu"><img src="/images/flags/es.gif" width="16px" alt="Torrents ES" /></a> <a href="http://german.seedpeer.eu"><img src="/images/flags/de.gif" width="16px" alt="Torrents DE" /></a> <a href="http://french.seedpeer.eu"><img src="/images/flags/fr.gif" width="16px" alt="Torrents FR" /></a> <a href="http://portuguese.seedpeer.eu"><img src="/images/flags/pt.gif" width="16px" alt="Torrents Portuguese" /></a> <a href="http://swedish.seedpeer.eu"><img src="/images/flags/se.gif" width="16px" alt="Torrents Sweden" /></a>
9
+                        </div>
10
+
11
+                <script type="text/javascript">
12
+                whoIsYou();
13
+                </script>
14
+                    <div id="search">
15
+                        <form action="/search.php" method="get">
16
+                            <input id="topsearchbar" name="search" value="narcos season 2" />
17
+                            <input type="submit" class="searchbutton" value="Torrents" />
18
+                            <input style="color:#000" type="submit" class="searchbutton" name="usenet" value="Usenet Binaries" />
19
+                        </form>
20
+                        <div id="suggestion"></div>
21
+                    </div>
22
+                    <div id="logo"><a href="/"><img src="/images/logo2.gif" alt="Seedpeer homepage" width="415" height="143" /></a></div>
23
+                    <div id="subtext"><a href="/">Home</a> &gt; <a href="/search.html">Torrent search</a> &gt; Narcos season 2 | page 1</div>
24
+            </div>
25
+        <div id="nav">
26
+            <ul>
27
+        <!--
28
+                <li><font style="color:red;font-size:9px;font-weight:bold;">NEW</font><a title="Download TOP Games for FREE" rel="nofollow" href="http://www.bigrebelads.com/affiliate/index?ref=9301" target="_blank">FREE Games</a></li>
29
+
30
+        -->
31
+                <li style="border-left:none" id="categories"><a title="Browse Torrent Categories" href="/browse.html">Categories</a>
32
+                    <ul>
33
+                        <li><a title="Browse Anime Torrents" href="/browse.html#6">Anime</a></li>
34
+                        <li><a title="Browse Game Torrents" href="/browse.html#4">Games</a></li>
35
+                        <li><a title="Browse Movie Torrents" href="/browse.html#1">Movies</a></li>
36
+                        <li><a title="Browse Music Torrents" href="/browse.html#3">Music</a></li>
37
+                        <li><a title="Browse Software Torrents" href="/browse.html#5">Software</a></li>
38
+                        <li><a title="Browse TV Torrents" href="/browse.html#2">TV Shows</a></li>
39
+                        <li><a title="Browse Other Torrents" href="/browse.html#7">Others</a></li>
40
+                    </ul>
41
+                    </li>
42
+                        <li><a title="Upload A Torrents" href="/upload.html">Upload torrent</a></li>
43
+                        <li id="verified"><a title="Verified Torrents" href="/verified.html">Verified</a></li>
44
+                        <li id="searchoptions"><a title="Search Torrents" href="/search.html">Torrent search</a></li>
45
+                        <li id="newsgroups"><a style="color:#212b3e" title="News Groups" href="/usenet.html">Usenet Binaries</a></li>
46
+                        <li id="about" style="border-right:none"><a rel="nofollow" href="/faq.html">About Us</a>
47
+                    <ul>
48
+                        <li><a title="SeedPeer Statistics" href="/stats.html">Statistics</a></li>
49
+                        <li><a title="Contact Us" href="/contact.html">Contact</a></li>
50
+                        <li><a title="Frequently  Asked Questions" href="/faq.html">FAQ</a></li>
51
+                        <li><a title="SeedPeer API" href="http://api.seedpeer.eu">Our API</a></li>
52
+                        <li><a title="SeedPeer Blog" href="/blog">Blog</a></li>
53
+                    </ul>
54
+                    </li>
55
+                    <!--<li><a href="/toolbar.php">Our Toolbar</a></li>-->
56
+                </ul>
57
+            <div class="clear"></div>
58
+        </div>
59
+        <div id="body"><div id="pageTop"></div>
60
+        <div id="headerbox"><h1>Verified <font class="colored">Narcos season 2</font> torrents</h1></div><table width="100%"><tr><th>
61
+        <span style="float:right">
62
+        <a href="/search/narcos-season-2/8/1.html"><img style="vertical-align:middle" src="/images/comments.gif" alt="comments" /></a> |
63
+        <a href="/search/narcos-season-2/7/1.html"><img style="vertical-align:middle" src="/images/ver.gif" alt="verified" /></a>
64
+        </span>
65
+        <a href="/search/narcos-season-2/1/1.html">Torrent name</a></th><th class="right"><a href="/search/narcos-season-2/2/1.html">Age</a></th><th class="right"><a href="/search/narcos-season-2/3/1.html">Size</a></th><th class="right"><a href="/search/narcos-season-2/4/1.html">Seeds</a></th><th class="right"><a href="/search/narcos-season-2/5/1.html">Peers</a></th><th class="center"><a href="/search/narcos-season-2/6/1.html">Health</a></th><td class="tableAd" rowspan="6"><iframe src="http://creative.wwwpromoter.com/13689?d=300x250" width="300" height="250" style="border: none;" frameborder="0" scrolling="no"></iframe></td></tr><tr class=""><td><a class="pblink" id="pblink_table_item_1" href="" data-tad="431726" data-last-search="narcos+season+2" target="_blank" rel="nofollow"><strong class='colored'>Narcos season 2</strong> Full Version</a></td><td class="right">20 hours</td><td class="right">681.3 MB</td><td class="right"><font color="green">28</font> </td><td class="right"><font color="navy">654</font> </td><td class="center"><img src="/images/h5.gif" alt="Health" /></td></tr><tr class="tdark"><td><a class="pblink" id="pblink_table_item_2" href="" data-tad="431727" data-url="narcos+season+2" target="_blank" rel="nofollow"><strong class='colored'>Narcos season 2</strong> Trusted Source</a></td><td class="right">12 hours</td><td class="right">787.1 MB</td><td class="right"><font color="green">64</font> </td><td class="right"><font color="navy">220</font> </td><td class="center"><img src="/images/h5.gif" alt="Health" /></td></tr><tr class=""><td><a class="pblink" id="pblink_table_item_3" href="" data-tad="431729" data-last-search="narcos+season+2" target="_blank" rel="nofollow"><strong class='colored'>Full Narcos season 2 Download</strong></a> <small><a class="pblink" id="pblink_table_item_4" href="" data-tad="431729" data-last-search="narcos+season+2" target="_blank" rel="nofollow">Usenet</a></small></td><td class="right">24 hours</td><td class="right">775.5 MB</td><td class="right"><font color="green">60</font> </td><td class="right"><font color="navy">236</font> </td><td class="center"><img src="/images/h5.gif" alt="Health" /></td></tr><tr class="tdark"><td><a class="pblink" id="pblink_table_item_5" href="" data-tad="431730" data-last-search="narcos+season+2" target="_blank" rel="nofollow"><strong class='colored'>Narcos season 2</strong> 2014 - DIRECT STREAMING</a> <small><a class="pblink" id="pblink_table_item_6" href="" data-tad="431729" data-last-search="narcos+season+2" target="_blank" rel="nofollow">Movies</a></small></td><td class="right">17 hours</td><td class="right">654.1 MB</td><td class="right"><font color="green">2</font> </td><td class="right"><font color="navy">391</font> </td><td class="center"><img src="/images/h5.gif" alt="Health" /></td></tr><tr class=""><td><a class="pblink" id="pblink_table_item_7" href="" data-tad="431731" data-last-search="narcos+season+2" target="_blank" rel="nofollow"><strong class='colored'>Narcos season 2</strong> 2014</a> <small><a class="pblink" id="pblink_table_item_8" href="" data-tad="431729" data-last-search="narcos+season+2" target="_blank" rel="nofollow">Movies</a></small></td><td class="right">20 hours</td><td class="right">754.5 MB</td><td class="right"><font color="green">21</font> </td><td class="right"><font color="navy">919</font> </td><td class="center"><img src="/images/h5.gif" alt="Health" /></td></tr></table><br /><br /><center><iframe src='http://creative.wwwpromoter.com/13689?d=728x90' width='728' height='90' style='border: none;' frameborder='0' scrolling='no'></iframe><center><span style="float:right;margin:1em .2em 0 0"><a title="Download at the speed of your connection" href="/usenet.php?search=narcos+season+2"><img src="/images/dlf.gif" alt="Search Binaries" /></a></span><div style="margin-bottom:1em;margin-right:290px" id="headerbox"><h1><a href="/searchfeed/narcos+season+2.xml" target="_blank" title="SeedPeer RSS Torrent Search Feed fornarcos season 2"><img src="/images/feedIcon.png" border="0" /></a>&nbsp;2 <font class="colored">Narcos season 2</font> Torrents were found</h1></div><table width="100%"><tr><th>
66
+        <span style="float:right">
67
+        <a href="/search/narcos-season-2/8/1.html"><img style="vertical-align:middle" src="/images/comments.gif" alt="comments" /></a> |
68
+        <a href="/search/narcos-season-2/7/1.html"><img style="vertical-align:middle" src="/images/ver.gif" alt="verified" /></a>
69
+        </span>
70
+        <a href="/search/narcos-season-2/1/1.html">Torrent name</a></th><th class="right"><a href="/search/narcos-season-2/2/1.html">Age</a></th><th class="right"><a href="/search/narcos-season-2/3/1.html">Size</a></th><th class="right"><a href="/search/narcos-season-2/4/1.html">Seeds</a></th><th class="right"><a href="/search/narcos-season-2/5/1.html">Peers</a></th><th class="center"><a href="/search/narcos-season-2/6/1.html">Health</a></th></tr><tr class=""><td><small class="comments"><a href="http://www.facebook.com/sharer.php?t=Download%20<strong class='colored'>Narcos</strong> <strong class='colored'>Season</strong> <strong class='colored'>2</strong> Complete 7<strong class='colored'>2</strong>0p WebRip EN-SUB x<strong class='colored'>2</strong>64-[MULVAcoded] S0<strong class='colored'>2</strong>%20 torrent&u=http://seedpeer.seedpeer.eu/details/11686840/Narcos-Season-2-Complete-720p-WebRip-EN-SUB-x264-[MULVAcoded]-S02.html"><img src="/images/facebook.png" alt="Add to Facebook" width="14" height="14" /></a></small><a href="/details/11686840/Narcos-Season-2-Complete-720p-WebRip-EN-SUB-x264-[MULVAcoded]-S02.html"><strong class='colored'>Narcos</strong> <strong class='colored'>Season</strong> <strong class='colored'>2</strong> Complete 7<strong class='colored'>2</strong>0p WebRip EN-SUB x<strong class='colored'>2</strong>64-[MULVAcoded] S0<strong class='colored'>2</strong> <small><a href="/browse.html#11686840"></a></small></a></td><td class="right">19 hours</td><td class="right">4.39 GB</td><td class="right"><font color="green">715</font> </td><td class="right"><font color="navy">183</font> </td><td class="center"><img src="/images/h5.gif" alt="Health" width="40" height="11" /></td></tr><tr class="tdark"><td><small class="comments"><a href="http://www.facebook.com/sharer.php?t=Download%20<strong class='colored'>Narcos</strong> - <strong class='colored'>Season</strong> <strong class='colored'>2</strong> - 7<strong class='colored'>2</strong>0p WEBRiP - x<strong class='colored'>2</strong>65 HEVC - ShAaNiG%20 torrent&u=http://seedpeer.seedpeer.eu/details/11685972/Narcos---Season-2---720p-WEBRiP---x265-HEVC---ShAaNiG.html"><img src="/images/facebook.png" alt="Add to Facebook" width="14" height="14" /></a></small><a href="/details/11685972/Narcos---Season-2---720p-WEBRiP---x265-HEVC---ShAaNiG.html"><strong class='colored'>Narcos</strong> - <strong class='colored'>Season</strong> <strong class='colored'>2</strong> - 7<strong class='colored'>2</strong>0p WEBRiP - x<strong class='colored'>2</strong>65 HEVC - ShAaNiG <small><a href="/browse.html#11685972"></a></small></a></td><td class="right">1 day</td><td class="right">2.48 GB</td><td class="right"><font color="green">861</font> </td><td class="right"><font color="navy">332</font> </td><td class="center"><img src="/images/h5.gif" alt="Health" width="40" height="11" /></td></tr></table><div id="headerbox"><h1>Related searches for: <font class="colored">Narcos season 2</font></h1></div><div id="search_suggestions"><br />Other suggested searches: </div><br /><a href="http://torrentz2.eu/search?f=narcos-season-2">Search for "narcos-season-2" on Torrentz2.eu</a><br /><a href="http://torrent-finder.info/show.php?q=narcos-season-2">Search for "narcos-season-2" on Torrent-Finder</a><br /><center><iframe src='http://creative.wwwpromoter.com/13689?d=300x250' width='300' height='250' style='border: none;' frameborder='0' scrolling='no'></iframe>&nbsp;<iframe src='http://creative.wwwpromoter.com/13689?d=300x250' width='300' height='250' style='border: none;' frameborder='0' scrolling='no'></iframe>&nbsp;<iframe src='http://creative.wwwpromoter.com/13689?d=300x250' width='300' height='250' style='border: none;' frameborder='0' scrolling='no'></iframe></center><div id="footer">
71
+        <table width="100%">
72
+        <tr>
73
+        <td width="30%">
74
+        <h2>Torrents Download</h2>
75
+        <a href="/">Torrent search</a><br />
76
+        <a href="/browse.html">Browse categories</a><br />
77
+        <a href="/verified.html">Verified Torrents</a><br />
78
+        <a href="/order-date.html">Today's torrents</a><br />
79
+        <a href="/yesterday.html">Yesterday's torrents</a><br />
80
+        <a href="/stats.html">Statistics</a><br />
81
+        <br />
82
+        <a href="/faq.html#copyright"><strong>Copyright & Removal</strong></a>
83
+        </td>
84
+        <td width="30%"><h2>Cool Stuff</h2>
85
+        <a href="/promotional.php">Promotional</a><br />
86
+        <a href="/contact.html">Advertising Information</a><br />
87
+        <strong><a href="/plugins.php" title="Add a search plugin to Firefox or Internet Explorer">Search Plugin <span style="color:red">*</span></a></strong><br />
88
+        <a href="http://www.utorrent.com">&micro;Torrent Client</a><br />
89
+        <a href="/blog">Seedpeer Blog</a><br />
90
+        </td>
91
+        <td width="30%"><h2>Links</h2>
92
+         <a href="http://www.sumotorrent.com" target="_blank"><strong>SumoTorrent</strong></a><br />
93
+         <a href="http://www.torrent-finder.info" target="_blank"><strong>Torrent Finder</strong></a><br />
94
+         <a href="http://www.torrentpond.com" target="_blank"><strong>TorrentPond</strong></a><br />
95
+         <a href="https://www.limetorrents.cc" target="_blank">LimeTorrents.cc</a><br />
96
+         <a href="http://www.torrents.to/" target="_blank">Torrents.to</a><br />
97
+         <a href="http://www.torrentfunk.com" target="_blank">TorrentFunk</a><br />
98
+         <a href="https://monova.org" target="_blank">Monova</a><br />
99
+         <a href="http://www.torrentroom.com" target="_blank">TorrentRoom</a><br />
100
+         <a href="http://www.katcr.co/" target="_blank">Kickass Torrents Community</a><br />
101
+        </td>
102
+        <td width="10%"><div id="bottomlogo"></div></td>
103
+        </tr>
104
+        </table>
105
+        <br />
106
+        <br />
107
+        </div>
108
+        </div>
109
+        </body>
110
+        </html>

+ 3
- 1
tests/unit/engines/test_digbt.py Ver fichero

@@ -28,7 +28,9 @@ class TestDigBTEngine(SearxTestCase):
28 28
         <table class="table">
29 29
             <tr><td class="x-item">
30 30
             <div>
31
-                <a title="The Big Bang Theory" class="title" href="/The-Big-Bang-Theory-d2.html">The Big Bang Theory</a>
31
+                <a title="The Big Bang Theory" class="title" href="/The-Big-Bang-Theory-d2.html">
32
+                    The Big <span class="highlight">Bang</span> Theory
33
+                </a>
32 34
                 <span class="ctime"><span style="color:red;">4 hours ago</span></span>
33 35
             </div>
34 36
             <div class="files">

+ 13
- 13
tests/unit/engines/test_kickass.py Ver fichero

@@ -14,7 +14,7 @@ class TestKickassEngine(SearxTestCase):
14 14
         params = kickass.request(query, dicto)
15 15
         self.assertIn('url', params)
16 16
         self.assertIn(query, params['url'])
17
-        self.assertIn('kickass.to', params['url'])
17
+        self.assertIn('kickass.cd', params['url'])
18 18
         self.assertFalse(params['verify'])
19 19
 
20 20
     def test_response(self):
@@ -84,7 +84,7 @@ class TestKickassEngine(SearxTestCase):
84 84
                         </span>
85 85
                     </div>
86 86
                 </td>
87
-                <td class="nobr center">449 <span>bytes</span></td>
87
+                <td class="nobr center">449 bytes</td>
88 88
                 <td class="center">4</td>
89 89
                 <td class="center">2&nbsp;years</td>
90 90
                 <td class="green center">10</td>
@@ -97,7 +97,7 @@ class TestKickassEngine(SearxTestCase):
97 97
         self.assertEqual(type(results), list)
98 98
         self.assertEqual(len(results), 1)
99 99
         self.assertEqual(results[0]['title'], 'This should be the title')
100
-        self.assertEqual(results[0]['url'], 'https://kickass.to/url.html')
100
+        self.assertEqual(results[0]['url'], 'https://kickass.cd/url.html')
101 101
         self.assertEqual(results[0]['content'], 'Posted by riri in Other &gt; Unsorted')
102 102
         self.assertEqual(results[0]['seed'], 10)
103 103
         self.assertEqual(results[0]['leech'], 1)
@@ -191,7 +191,7 @@ class TestKickassEngine(SearxTestCase):
191 191
                         </span>
192 192
                     </div>
193 193
                 </td>
194
-                <td class="nobr center">1 <span>KB</span></td>
194
+                <td class="nobr center">1 KiB</td>
195 195
                 <td class="center">4</td>
196 196
                 <td class="center">2&nbsp;years</td>
197 197
                 <td class="green center">10</td>
@@ -235,7 +235,7 @@ class TestKickassEngine(SearxTestCase):
235 235
                         </span>
236 236
                     </div>
237 237
                 </td>
238
-                <td class="nobr center">1 <span>MB</span></td>
238
+                <td class="nobr center">1 MiB</td>
239 239
                 <td class="center">4</td>
240 240
                 <td class="center">2&nbsp;years</td>
241 241
                 <td class="green center">9</td>
@@ -279,7 +279,7 @@ class TestKickassEngine(SearxTestCase):
279 279
                         </span>
280 280
                     </div>
281 281
                 </td>
282
-                <td class="nobr center">1 <span>GB</span></td>
282
+                <td class="nobr center">1 GiB</td>
283 283
                 <td class="center">4</td>
284 284
                 <td class="center">2&nbsp;years</td>
285 285
                 <td class="green center">8</td>
@@ -323,7 +323,7 @@ class TestKickassEngine(SearxTestCase):
323 323
                         </span>
324 324
                     </div>
325 325
                 </td>
326
-                <td class="nobr center">1 <span>TB</span></td>
326
+                <td class="nobr center">1 TiB</td>
327 327
                 <td class="center">4</td>
328 328
                 <td class="center">2&nbsp;years</td>
329 329
                 <td class="green center">7</td>
@@ -367,7 +367,7 @@ class TestKickassEngine(SearxTestCase):
367 367
                         </span>
368 368
                     </div>
369 369
                 </td>
370
-                <td class="nobr center">z <span>bytes</span></td>
370
+                <td class="nobr center">z bytes</td>
371 371
                 <td class="center">r</td>
372 372
                 <td class="center">2&nbsp;years</td>
373 373
                 <td class="green center">a</td>
@@ -380,17 +380,17 @@ class TestKickassEngine(SearxTestCase):
380 380
         self.assertEqual(type(results), list)
381 381
         self.assertEqual(len(results), 5)
382 382
         self.assertEqual(results[0]['title'], 'This should be the title')
383
-        self.assertEqual(results[0]['url'], 'https://kickass.to/url.html')
383
+        self.assertEqual(results[0]['url'], 'https://kickass.cd/url.html')
384 384
         self.assertEqual(results[0]['content'], 'Posted by riri in Other &gt; Unsorted')
385 385
         self.assertEqual(results[0]['seed'], 10)
386 386
         self.assertEqual(results[0]['leech'], 1)
387 387
         self.assertEqual(results[0]['files'], 4)
388 388
         self.assertEqual(results[0]['magnetlink'], 'magnet:?xt=urn:btih:MAGNETURL&dn=test')
389 389
         self.assertEqual(results[0]['torrentfile'], 'http://torcache.net/torrent/53917.torrent?title=test')
390
-        self.assertEqual(results[0]['filesize'], 1024)
391
-        self.assertEqual(results[1]['filesize'], 1048576)
392
-        self.assertEqual(results[2]['filesize'], 1073741824)
393
-        self.assertEqual(results[3]['filesize'], 1099511627776)
390
+        self.assertEqual(results[0]['filesize'], 1000)
391
+        self.assertEqual(results[1]['filesize'], 1000000)
392
+        self.assertEqual(results[2]['filesize'], 1000000000)
393
+        self.assertEqual(results[3]['filesize'], 1000000000000)
394 394
         self.assertEqual(results[4]['seed'], 0)
395 395
         self.assertEqual(results[4]['leech'], 0)
396 396
         self.assertEqual(results[4]['files'], None)

+ 109
- 0
tests/unit/engines/test_pdbe.py Ver fichero

@@ -0,0 +1,109 @@
1
+import mock
2
+from collections import defaultdict
3
+from searx.engines import pdbe
4
+from searx.testing import SearxTestCase
5
+
6
+
7
+class TestPdbeEngine(SearxTestCase):
8
+    def test_request(self):
9
+        query = 'test_query'
10
+        dicto = defaultdict(dict)
11
+        params = pdbe.request(query, dicto)
12
+        self.assertTrue('url' in params)
13
+        self.assertTrue('ebi.ac.uk' in params['url'])
14
+        self.assertTrue('data' in params)
15
+        self.assertTrue('q' in params['data'])
16
+        self.assertTrue(query in params['data']['q'])
17
+        self.assertTrue('wt' in params['data'])
18
+        self.assertTrue('json' in params['data']['wt'])
19
+        self.assertTrue('method' in params)
20
+        self.assertTrue(params['method'] == 'POST')
21
+
22
+    def test_response(self):
23
+        self.assertRaises(AttributeError, pdbe.response, None)
24
+        self.assertRaises(AttributeError, pdbe.response, [])
25
+        self.assertRaises(AttributeError, pdbe.response, '')
26
+        self.assertRaises(AttributeError, pdbe.response, '[]')
27
+
28
+        json = """
29
+{
30
+  "response": {
31
+    "docs": [
32
+      {
33
+        "citation_title": "X-ray crystal structure of ferric Aplysia limacina myoglobin in different liganded states.",
34
+        "citation_year": 1993,
35
+        "entry_author_list": [
36
+          "Conti E, Moser C, Rizzi M, Mattevi A, Lionetti C, Coda A, Ascenzi P, Brunori M, Bolognesi M"
37
+        ],
38
+        "journal": "J. Mol. Biol.",
39
+        "journal_page": "498-508",
40
+        "journal_volume": "233",
41
+        "pdb_id": "2fal",
42
+        "status": "REL",
43
+        "title": "X-RAY CRYSTAL STRUCTURE OF FERRIC APLYSIA LIMACINA MYOGLOBIN IN DIFFERENT LIGANDED STATES"
44
+      }
45
+    ],
46
+    "numFound": 1,
47
+    "start": 0
48
+  },
49
+  "responseHeader": {
50
+    "QTime": 0,
51
+    "params": {
52
+      "q": "2fal",
53
+      "wt": "json"
54
+    },
55
+    "status": 0
56
+  }
57
+}
58
+"""
59
+
60
+        response = mock.Mock(text=json)
61
+        results = pdbe.response(response)
62
+        self.assertEqual(type(results), list)
63
+        self.assertEqual(len(results), 1)
64
+        self.assertEqual(results[0]['title'],
65
+                         'X-RAY CRYSTAL STRUCTURE OF FERRIC APLYSIA LIMACINA MYOGLOBIN IN DIFFERENT LIGANDED STATES')
66
+        self.assertEqual(results[0]['url'], pdbe.pdbe_entry_url.format(pdb_id='2fal'))
67
+        self.assertEqual(results[0]['img_src'], pdbe.pdbe_preview_url.format(pdb_id='2fal'))
68
+        self.assertTrue('Conti E' in results[0]['content'])
69
+        self.assertTrue('X-ray crystal structure of ferric Aplysia limacina myoglobin in different liganded states.' in
70
+                        results[0]['content'])
71
+        self.assertTrue('1993' in results[0]['content'])
72
+
73
+        # Testing proper handling of PDB entries marked as obsolete
74
+        json = """
75
+{
76
+  "response": {
77
+    "docs": [
78
+      {
79
+        "citation_title": "Obsolete entry test",
80
+        "citation_year": 2016,
81
+        "entry_author_list": ["Doe J"],
82
+        "journal": "J. Obs.",
83
+        "journal_page": "1-2",
84
+        "journal_volume": "1",
85
+        "pdb_id": "xxxx",
86
+        "status": "OBS",
87
+        "title": "OBSOLETE ENTRY TEST",
88
+        "superseded_by": "yyyy"
89
+      }
90
+    ],
91
+    "numFound": 1,
92
+    "start": 0
93
+  },
94
+  "responseHeader": {
95
+    "QTime": 0,
96
+    "params": {
97
+      "q": "xxxx",
98
+      "wt": "json"
99
+    },
100
+    "status": 0
101
+  }
102
+}
103
+"""
104
+        response = mock.Mock(text=json)
105
+        results = pdbe.response(response)
106
+        self.assertEqual(type(results), list)
107
+        self.assertEqual(len(results), 1)
108
+        self.assertEqual(results[0]['title'], 'OBSOLETE ENTRY TEST&nbsp;(OBSOLETE)')
109
+        self.assertTrue(results[0]['content'].startswith('<em>This entry has been superseded by'))

+ 51
- 0
tests/unit/engines/test_seedpeer.py Ver fichero

@@ -0,0 +1,51 @@
1
+import mock
2
+from collections import defaultdict
3
+from searx.engines import seedpeer
4
+from searx.testing import SearxTestCase
5
+from datetime import datetime
6
+
7
+
8
+class TestSeedPeerEngine(SearxTestCase):
9
+
10
+    html = ''
11
+    with open('./tests/unit/engines/seedpeer_fixture.html') as fixture:
12
+        html += fixture.read()
13
+
14
+    def test_request(self):
15
+        query = 'test_query'
16
+        dicto = defaultdict(dict)
17
+        dicto['pageno'] = 1
18
+        params = seedpeer.request(query, dicto)
19
+        self.assertIn('url', params)
20
+        self.assertIn(query, params['url'])
21
+        self.assertIn('seedpeer.eu', params['url'])
22
+
23
+    def test_response_raises_attr_error_on_empty_response(self):
24
+        self.assertRaises(AttributeError, seedpeer.response, None)
25
+        self.assertRaises(AttributeError, seedpeer.response, [])
26
+        self.assertRaises(AttributeError, seedpeer.response, '')
27
+        self.assertRaises(AttributeError, seedpeer.response, '[]')
28
+
29
+    def test_response_returns_empty_list(self):
30
+        response = mock.Mock(text='<html></html>')
31
+        self.assertEqual(seedpeer.response(response), [])
32
+
33
+    def test_response_returns_all_results(self):
34
+        response = mock.Mock(text=self.html)
35
+        results = seedpeer.response(response)
36
+        self.assertTrue(isinstance(results, list))
37
+        self.assertEqual(len(results), 2)
38
+
39
+    def test_response_returns_correct_results(self):
40
+        response = mock.Mock(text=self.html)
41
+        results = seedpeer.response(response)
42
+        self.assertEqual(
43
+            results[0]['title'], 'Narcos - Season 2 - 720p WEBRiP - x265 HEVC - ShAaNiG '
44
+        )
45
+        self.assertEqual(
46
+            results[0]['url'],
47
+            'http://www.seedpeer.eu/details/11685972/Narcos---Season-2---720p-WEBRiP---x265-HEVC---ShAaNiG.html'
48
+        )
49
+        self.assertEqual(results[0]['content'], '2.48 GB, 1 day')
50
+        self.assertEqual(results[0]['seed'], '861')
51
+        self.assertEqual(results[0]['leech'], '332')

+ 2
- 2
tests/unit/test_webapp.py Ver fichero

@@ -44,7 +44,7 @@ class ViewsTestCase(SearxTestCase):
44 44
         webapp.Search.search = search_mock
45 45
 
46 46
         def get_current_theme_name_mock(override=None):
47
-            return 'default'
47
+            return 'legacy'
48 48
 
49 49
         webapp.get_current_theme_name = get_current_theme_name_mock
50 50
 
@@ -58,7 +58,7 @@ class ViewsTestCase(SearxTestCase):
58 58
     def test_index_html(self):
59 59
         result = self.app.post('/', data={'q': 'test'})
60 60
         self.assertIn(
61
-            '<h3 class="result_title"><img width="14" height="14" class="favicon" src="/static/themes/default/img/icons/icon_youtube.ico" alt="youtube" /><a href="http://second.test.xyz" rel="noreferrer">Second <span class="highlight">Test</span></a></h3>',  # noqa
61
+            '<h3 class="result_title"><img width="14" height="14" class="favicon" src="/static/themes/legacy/img/icons/icon_youtube.ico" alt="youtube" /><a href="http://second.test.xyz" rel="noreferrer">Second <span class="highlight">Test</span></a></h3>',  # noqa
62 62
             result.data
63 63
         )
64 64
         self.assertIn(