mirror of
				https://github.com/searxng/searxng
				synced 2024-01-01 19:24:07 +01:00 
			
		
		
		
	
						commit
						98aa70cd41
					
				
					 7 changed files with 207 additions and 29 deletions
				
			
		
							
								
								
									
										60
									
								
								searx/engines/spotify.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								searx/engines/spotify.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,60 @@ | |||
| ## Spotify (Music) | ||||
| # | ||||
| # @website     https://spotify.com | ||||
| # @provide-api yes (https://developer.spotify.com/web-api/search-item/) | ||||
| # | ||||
| # @using-api   yes | ||||
| # @results     JSON | ||||
| # @stable      yes | ||||
| # @parse       url, title, content, embedded | ||||
| 
 | ||||
| from json import loads | ||||
| from urllib import urlencode | ||||
| 
 | ||||
| # engine dependent config | ||||
| categories = ['music'] | ||||
| paging = True | ||||
| 
 | ||||
| # search-url | ||||
| url = 'https://api.spotify.com/' | ||||
| search_url = url + 'v1/search?{query}&type=track&offset={offset}' | ||||
| 
 | ||||
| embedded_url = '<iframe data-src="https://embed.spotify.com/?uri=spotify:track:{audioid}"\ | ||||
|      width="300" height="80" frameborder="0" allowtransparency="true"></iframe>' | ||||
| 
 | ||||
| 
 | ||||
| # do search-request | ||||
| def request(query, params): | ||||
|     offset = (params['pageno'] - 1) * 20 | ||||
| 
 | ||||
|     params['url'] = search_url.format(query=urlencode({'q': query}), | ||||
|                                       offset=offset) | ||||
| 
 | ||||
|     return params | ||||
| 
 | ||||
| 
 | ||||
| # get response from search-request | ||||
| def response(resp): | ||||
|     results = [] | ||||
| 
 | ||||
|     search_res = loads(resp.text) | ||||
| 
 | ||||
|     # parse results | ||||
|     for result in search_res.get('tracks', {}).get('items', {}): | ||||
|         if result['type'] == 'track': | ||||
|             title = result['name'] | ||||
|             url = result['external_urls']['spotify'] | ||||
|             content = result['artists'][0]['name'] +\ | ||||
|                 " • " +\ | ||||
|                 result['album']['name'] +\ | ||||
|                 " • " + result['name'] | ||||
|             embedded = embedded_url.format(audioid=result['id']) | ||||
| 
 | ||||
|             # append result | ||||
|             results.append({'url': url, | ||||
|                             'title': title, | ||||
|                             'embedded': embedded, | ||||
|                             'content': content}) | ||||
| 
 | ||||
|     # return results | ||||
|     return results | ||||
|  | @ -84,12 +84,6 @@ engines: | |||
| #    shortcut : fa | ||||
| #    api_key : 'apikey' # required! | ||||
| 
 | ||||
| # down - website is under criminal investigation by the UK | ||||
| #  - name : filecrop | ||||
| #    engine : filecrop | ||||
| #    categories : files | ||||
| #    shortcut : fc | ||||
| 
 | ||||
|   - name : 500px | ||||
|     engine : www500px | ||||
|     shortcut : px | ||||
|  | @ -109,11 +103,6 @@ engines: | |||
| # Or you can use the html non-stable engine, activated by default | ||||
|     engine : flickr_noapi | ||||
| 
 | ||||
|   - name : general-file | ||||
|     engine : generalfile | ||||
|     shortcut : gf | ||||
|     disabled : True | ||||
| 
 | ||||
|   - name : gigablast | ||||
|     engine : gigablast | ||||
|     shortcut : gb | ||||
|  | @ -201,6 +190,10 @@ engines: | |||
|     shortcut : scc | ||||
|     disabled : True | ||||
| 
 | ||||
|   - name : spotify | ||||
|     engine : spotify | ||||
|     shortcut : stf | ||||
| 
 | ||||
|   - name : subtitleseeker | ||||
|     engine : subtitleseeker | ||||
|     shortcut : ss | ||||
|  |  | |||
|  | @ -12,9 +12,14 @@ class TestBlekkoImagesEngine(SearxTestCase): | |||
|         dicto['pageno'] = 0 | ||||
|         dicto['safesearch'] = 1 | ||||
|         params = blekko_images.request(query, dicto) | ||||
|         self.assertTrue('url' in params) | ||||
|         self.assertTrue(query in params['url']) | ||||
|         self.assertTrue('blekko.com' in params['url']) | ||||
|         self.assertIn('url', params) | ||||
|         self.assertIn(query, params['url']) | ||||
|         self.assertIn('blekko.com', params['url']) | ||||
|         self.assertIn('page', params['url']) | ||||
| 
 | ||||
|         dicto['pageno'] = 1 | ||||
|         params = blekko_images.request(query, dicto) | ||||
|         self.assertNotIn('page', params['url']) | ||||
| 
 | ||||
|     def test_response(self): | ||||
|         self.assertRaises(AttributeError, blekko_images.response, None) | ||||
|  |  | |||
|  | @ -11,9 +11,14 @@ class TestGoogleImagesEngine(SearxTestCase): | |||
|         dicto = defaultdict(dict) | ||||
|         dicto['pageno'] = 1 | ||||
|         params = google_images.request(query, dicto) | ||||
|         self.assertTrue('url' in params) | ||||
|         self.assertTrue(query in params['url']) | ||||
|         self.assertTrue('googleapis.com' in params['url']) | ||||
|         self.assertIn('url', params) | ||||
|         self.assertIn(query, params['url']) | ||||
|         self.assertIn('googleapis.com', params['url']) | ||||
|         self.assertIn('safe=on', params['url']) | ||||
| 
 | ||||
|         dicto['safesearch'] = 0 | ||||
|         params = google_images.request(query, dicto) | ||||
|         self.assertIn('safe=off', params['url']) | ||||
| 
 | ||||
|     def test_response(self): | ||||
|         self.assertRaises(AttributeError, google_images.response, None) | ||||
|  |  | |||
							
								
								
									
										124
									
								
								searx/tests/engines/test_spotify.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								searx/tests/engines/test_spotify.py
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,124 @@ | |||
| from collections import defaultdict | ||||
| import mock | ||||
| from searx.engines import spotify | ||||
| from searx.testing import SearxTestCase | ||||
| 
 | ||||
| 
 | ||||
| class TestSpotifyEngine(SearxTestCase): | ||||
| 
 | ||||
|     def test_request(self): | ||||
|         query = 'test_query' | ||||
|         dicto = defaultdict(dict) | ||||
|         dicto['pageno'] = 0 | ||||
|         params = spotify.request(query, dicto) | ||||
|         self.assertIn('url', params) | ||||
|         self.assertIn(query, params['url']) | ||||
|         self.assertIn('spotify.com', params['url']) | ||||
| 
 | ||||
|     def test_response(self): | ||||
|         self.assertRaises(AttributeError, spotify.response, None) | ||||
|         self.assertRaises(AttributeError, spotify.response, []) | ||||
|         self.assertRaises(AttributeError, spotify.response, '') | ||||
|         self.assertRaises(AttributeError, spotify.response, '[]') | ||||
| 
 | ||||
|         response = mock.Mock(text='{}') | ||||
|         self.assertEqual(spotify.response(response), []) | ||||
| 
 | ||||
|         response = mock.Mock(text='{"data": []}') | ||||
|         self.assertEqual(spotify.response(response), []) | ||||
| 
 | ||||
|         json = """ | ||||
|         { | ||||
|           "tracks": { | ||||
|             "href": "https://api.spotify.com/v1/search?query=nosfell&offset=0&limit=20&type=track", | ||||
|             "items": [ | ||||
|               { | ||||
|                 "album": { | ||||
|                   "album_type": "album", | ||||
|                   "external_urls": { | ||||
|                     "spotify": "https://open.spotify.com/album/5c9ap1PBkSGLxT3J73toxA" | ||||
|                   }, | ||||
|                   "href": "https://api.spotify.com/v1/albums/5c9ap1PBkSGLxT3J73toxA", | ||||
|                   "id": "5c9ap1PBkSGLxT3J73toxA", | ||||
|                   "name": "Album Title", | ||||
|                   "type": "album", | ||||
|                   "uri": "spotify:album:5c9ap1PBkSGLxT3J73toxA" | ||||
|                 }, | ||||
|                 "artists": [ | ||||
|                   { | ||||
|                     "external_urls": { | ||||
|                       "spotify": "https://open.spotify.com/artist/0bMc6b75FfZEpQHG1jifKu" | ||||
|                     }, | ||||
|                     "href": "https://api.spotify.com/v1/artists/0bMc6b75FfZEpQHG1jifKu", | ||||
|                     "id": "0bMc6b75FfZEpQHG1jifKu", | ||||
|                     "name": "Artist Name", | ||||
|                     "type": "artist", | ||||
|                     "uri": "spotify:artist:0bMc6b75FfZEpQHG1jifKu" | ||||
|                   } | ||||
|                 ], | ||||
|                 "disc_number": 1, | ||||
|                 "duration_ms": 202386, | ||||
|                 "explicit": false, | ||||
|                 "external_ids": { | ||||
|                   "isrc": "FRV640600067" | ||||
|                 }, | ||||
|                 "external_urls": { | ||||
|                   "spotify": "https://open.spotify.com/track/2GzvFiedqW8hgqUpWcASZa" | ||||
|                 }, | ||||
|                 "href": "https://api.spotify.com/v1/tracks/2GzvFiedqW8hgqUpWcASZa", | ||||
|                 "id": "1000", | ||||
|                 "is_playable": true, | ||||
|                 "name": "Title of track", | ||||
|                 "popularity": 6, | ||||
|                 "preview_url": "https://p.scdn.co/mp3-preview/7b8ecda580965a066b768c2647f877e43f7b1a0a", | ||||
|                 "track_number": 3, | ||||
|                 "type": "track", | ||||
|                 "uri": "spotify:track:2GzvFiedqW8hgqUpWcASZa" | ||||
|               } | ||||
|             ], | ||||
|             "limit": 20, | ||||
|             "next": "https://api.spotify.com/v1/search?query=nosfell&offset=20&limit=20&type=track", | ||||
|             "offset": 0, | ||||
|             "previous": null, | ||||
|             "total": 107 | ||||
|           } | ||||
|         } | ||||
|         """ | ||||
|         response = mock.Mock(text=json) | ||||
|         results = spotify.response(response) | ||||
|         self.assertEqual(type(results), list) | ||||
|         self.assertEqual(len(results), 1) | ||||
|         self.assertEqual(results[0]['title'], 'Title of track') | ||||
|         self.assertEqual(results[0]['url'], 'https://open.spotify.com/track/2GzvFiedqW8hgqUpWcASZa') | ||||
|         self.assertEqual(results[0]['content'], 'Artist Name • Album Title • Title of track') | ||||
|         self.assertIn('1000', results[0]['embedded']) | ||||
| 
 | ||||
|         json = """ | ||||
|         { | ||||
|           "tracks": { | ||||
|             "href": "https://api.spotify.com/v1/search?query=nosfell&offset=0&limit=20&type=track", | ||||
|             "items": [ | ||||
|               { | ||||
|                 "href": "https://api.spotify.com/v1/tracks/2GzvFiedqW8hgqUpWcASZa", | ||||
|                 "id": "1000", | ||||
|                 "is_playable": true, | ||||
|                 "name": "Title of track", | ||||
|                 "popularity": 6, | ||||
|                 "preview_url": "https://p.scdn.co/mp3-preview/7b8ecda580965a066b768c2647f877e43f7b1a0a", | ||||
|                 "track_number": 3, | ||||
|                 "type": "album", | ||||
|                 "uri": "spotify:track:2GzvFiedqW8hgqUpWcASZa" | ||||
|               } | ||||
|             ], | ||||
|             "limit": 20, | ||||
|             "next": "https://api.spotify.com/v1/search?query=nosfell&offset=20&limit=20&type=track", | ||||
|             "offset": 0, | ||||
|             "previous": null, | ||||
|             "total": 107 | ||||
|           } | ||||
|         } | ||||
|         """ | ||||
|         response = mock.Mock(text=json) | ||||
|         results = spotify.response(response) | ||||
|         self.assertEqual(type(results), list) | ||||
|         self.assertEqual(len(results), 0) | ||||
|  | @ -75,12 +75,6 @@ class TestYahooEngine(SearxTestCase): | |||
|     <li> | ||||
|         <div class="dd algo lst Sr"> | ||||
|             <div class="compTitle"> | ||||
|                 <h3 class="title"><a class=" td-u" href="http://r.search.yahoo.com/_ylt=AwrBT7zgEudUW.wAe2ZXNyoA; | ||||
|                      _ylu=X3oDMTBybGY3bmpvBGNvbG8DYmYxBHBvcwMyBHZ0aWQDBHNlYwNzcg--/RV=2\/RE=1424458593/RO=10 | ||||
|                      /RU=https%3a%2f%2fthis.is.the.second.url%2f/RK=0/RS=jIctjj_cBH1Efj88GCgHKp3__Qk-" | ||||
|                      target="_blank" data-bid="54e712e136926"> | ||||
|                      This is the second <b><b>title</b></b></a> | ||||
|                 </h3> | ||||
|             </div> | ||||
|             <div class="compText aAbs"> | ||||
|                 <p class="lh-18">This is the second content</p> | ||||
|  | @ -102,16 +96,12 @@ class TestYahooEngine(SearxTestCase): | |||
|         """ | ||||
|         response = mock.Mock(text=html) | ||||
|         results = yahoo.response(response) | ||||
|         print results | ||||
|         self.assertEqual(type(results), list) | ||||
|         self.assertEqual(len(results), 3) | ||||
|         self.assertEqual(len(results), 2) | ||||
|         self.assertEqual(results[0]['title'], 'This is the title') | ||||
|         self.assertEqual(results[0]['url'], 'https://this.is.the.url/') | ||||
|         self.assertEqual(results[0]['content'], 'This is the content') | ||||
|         self.assertEqual(results[1]['title'], 'This is the second title') | ||||
|         self.assertEqual(results[1]['url'], 'https://this.is.the.second.url/') | ||||
|         self.assertEqual(results[1]['content'], 'This is the second content') | ||||
|         self.assertEqual(results[2]['suggestion'], 'This is the suggestion') | ||||
|         self.assertEqual(results[1]['suggestion'], 'This is the suggestion') | ||||
| 
 | ||||
|         html = """ | ||||
| <ol class="reg mb-15 searchCenterMiddle"> | ||||
|  |  | |||
|  | @ -28,6 +28,7 @@ from searx.tests.engines.test_piratebay import *  # noqa | |||
| from searx.tests.engines.test_searchcode_code import *  # noqa | ||||
| from searx.tests.engines.test_searchcode_doc import *  # noqa | ||||
| from searx.tests.engines.test_soundcloud import *  # noqa | ||||
| from searx.tests.engines.test_spotify import *  # noqa | ||||
| from searx.tests.engines.test_stackoverflow import *  # noqa | ||||
| from searx.tests.engines.test_startpage import *  # noqa | ||||
| from searx.tests.engines.test_subtitleseeker import *  # noqa | ||||
|  |  | |||
		Loading…
	
	Add table
		
		Reference in a new issue
	
	 Adam Tauber
						Adam Tauber