| 
									
										
										
										
											2021-01-13 11:31:25 +01:00
										 |  |  | # SPDX-License-Identifier: AGPL-3.0-or-later | 
					
						
							|  |  |  | """
 | 
					
						
							|  |  |  |  Wolfram|Alpha (Science) | 
					
						
							|  |  |  | """
 | 
					
						
							| 
									
										
										
										
											2015-12-30 03:59:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-30 07:53:15 +01:00
										 |  |  | from json import loads | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  | from time import time | 
					
						
							| 
									
										
										
										
											2020-08-06 17:42:46 +02:00
										 |  |  | from urllib.parse import urlencode | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | from searx.poolrequests import get as http_get | 
					
						
							| 
									
										
										
										
											2015-12-30 03:59:51 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-13 11:31:25 +01:00
										 |  |  | # about | 
					
						
							|  |  |  | about = { | 
					
						
							|  |  |  |     "website": 'https://www.wolframalpha.com/', | 
					
						
							|  |  |  |     "wikidata_id": 'Q207006', | 
					
						
							|  |  |  |     "official_api_documentation": 'https://products.wolframalpha.com/api/', | 
					
						
							|  |  |  |     "use_official_api": False, | 
					
						
							|  |  |  |     "require_api_key": False, | 
					
						
							|  |  |  |     "results": 'JSON', | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-30 03:59:51 +01:00
										 |  |  | # search-url | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  | url = 'https://www.wolframalpha.com/' | 
					
						
							| 
									
										
										
										
											2016-01-02 08:49:32 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  | search_url = url + 'input/json.jsp'\ | 
					
						
							| 
									
										
										
										
											2016-02-28 09:05:52 +01:00
										 |  |  |     '?async=false'\ | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  |     '&banners=raw'\ | 
					
						
							|  |  |  |     '&debuggingdata=false'\ | 
					
						
							|  |  |  |     '&format=image,plaintext,imagemap,minput,moutput'\ | 
					
						
							|  |  |  |     '&formattimeout=2'\ | 
					
						
							|  |  |  |     '&{query}'\ | 
					
						
							|  |  |  |     '&output=JSON'\ | 
					
						
							|  |  |  |     '&parsetimeout=2'\ | 
					
						
							|  |  |  |     '&proxycode={token}'\ | 
					
						
							|  |  |  |     '&scantimeout=0.5'\ | 
					
						
							|  |  |  |     '&sponsorcategories=true'\ | 
					
						
							|  |  |  |     '&statemethod=deploybutton' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-28 02:06:44 +01:00
										 |  |  | referer_url = url + 'input/?{query}' | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  | token = {'value': '', | 
					
						
							| 
									
										
										
										
											2016-07-08 01:41:33 +02:00
										 |  |  |          'last_updated': None} | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-28 02:06:44 +01:00
										 |  |  | # pods to display as image in infobox | 
					
						
							|  |  |  | # this pods do return a plaintext, but they look better and are more useful as images | 
					
						
							| 
									
										
										
										
											2016-02-28 07:47:36 +01:00
										 |  |  | image_pods = {'VisualRepresentation', | 
					
						
							|  |  |  |               'Illustration', | 
					
						
							| 
									
										
										
										
											2016-02-28 02:06:44 +01:00
										 |  |  |               'Symbol'} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | # seems, wolframalpha resets its token in every hour | 
					
						
							|  |  |  | def obtain_token(): | 
					
						
							|  |  |  |     update_time = time() - (time() % 3600) | 
					
						
							| 
									
										
										
										
											2016-02-17 17:21:54 +01:00
										 |  |  |     try: | 
					
						
							|  |  |  |         token_response = http_get('https://www.wolframalpha.com/input/api/v1/code?ts=9999999999999999999', timeout=2.0) | 
					
						
							|  |  |  |         token['value'] = loads(token_response.text)['code'] | 
					
						
							|  |  |  |         token['last_updated'] = update_time | 
					
						
							|  |  |  |     except: | 
					
						
							|  |  |  |         pass | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  |     return token | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-09-23 17:14:32 +02:00
										 |  |  | def init(engine_settings=None): | 
					
						
							| 
									
										
										
										
											2017-06-06 22:20:20 +02:00
										 |  |  |     obtain_token() | 
					
						
							| 
									
										
										
										
											2015-12-30 03:59:51 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | # do search-request | 
					
						
							|  |  |  | def request(query, params): | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  |     # obtain token if last update was more than an hour | 
					
						
							| 
									
										
										
										
											2016-11-30 18:43:03 +01:00
										 |  |  |     if time() - (token['last_updated'] or 0) > 3600: | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  |         obtain_token() | 
					
						
							|  |  |  |     params['url'] = search_url.format(query=urlencode({'input': query}), token=token['value']) | 
					
						
							| 
									
										
										
										
											2016-02-28 02:06:44 +01:00
										 |  |  |     params['headers']['Referer'] = referer_url.format(query=urlencode({'i': query})) | 
					
						
							| 
									
										
										
										
											2015-12-30 03:59:51 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return params | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2015-12-30 04:11:49 +01:00
										 |  |  | # get response from search-request | 
					
						
							|  |  |  | def response(resp): | 
					
						
							| 
									
										
										
										
											2016-02-28 02:06:44 +01:00
										 |  |  |     results = [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  |     resp_json = loads(resp.text) | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     if not resp_json['queryresult']['success']: | 
					
						
							|  |  |  |         return [] | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     # TODO handle resp_json['queryresult']['assumptions'] | 
					
						
							|  |  |  |     result_chunks = [] | 
					
						
							| 
									
										
										
										
											2016-07-08 01:41:33 +02:00
										 |  |  |     infobox_title = "" | 
					
						
							|  |  |  |     result_content = "" | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  |     for pod in resp_json['queryresult']['pods']: | 
					
						
							| 
									
										
										
										
											2016-02-28 07:47:36 +01:00
										 |  |  |         pod_id = pod.get('id', '') | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  |         pod_title = pod.get('title', '') | 
					
						
							| 
									
										
										
										
											2016-07-07 00:29:40 +02:00
										 |  |  |         pod_is_result = pod.get('primary', None) | 
					
						
							| 
									
										
										
										
											2016-02-28 02:06:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  |         if 'subpods' not in pod: | 
					
						
							| 
									
										
										
										
											2016-02-28 09:05:52 +01:00
										 |  |  |             continue | 
					
						
							| 
									
										
										
										
											2016-02-28 02:06:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-28 07:47:36 +01:00
										 |  |  |         if pod_id == 'Input' or not infobox_title: | 
					
						
							|  |  |  |             infobox_title = pod['subpods'][0]['plaintext'] | 
					
						
							| 
									
										
										
										
											2016-02-28 02:06:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  |         for subpod in pod['subpods']: | 
					
						
							| 
									
										
										
										
											2016-02-28 07:47:36 +01:00
										 |  |  |             if subpod['plaintext'] != '' and pod_id not in image_pods: | 
					
						
							| 
									
										
										
										
											2016-02-28 02:06:44 +01:00
										 |  |  |                 # append unless it's not an actual answer | 
					
						
							|  |  |  |                 if subpod['plaintext'] != '(requires interactivity)': | 
					
						
							|  |  |  |                     result_chunks.append({'label': pod_title, 'value': subpod['plaintext']}) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-07-08 01:41:33 +02:00
										 |  |  |                 if pod_is_result or not result_content: | 
					
						
							|  |  |  |                     if pod_id != "Input": | 
					
						
							|  |  |  |                         result_content = pod_title + ': ' + subpod['plaintext'] | 
					
						
							| 
									
										
										
										
											2016-07-07 00:29:40 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-28 02:06:44 +01:00
										 |  |  |             elif 'img' in subpod: | 
					
						
							|  |  |  |                 result_chunks.append({'label': pod_title, 'image': subpod['img']}) | 
					
						
							| 
									
										
										
										
											2016-02-17 17:07:19 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     if not result_chunks: | 
					
						
							|  |  |  |         return [] | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-02-28 02:06:44 +01:00
										 |  |  |     results.append({'infobox': infobox_title, | 
					
						
							|  |  |  |                     'attributes': result_chunks, | 
					
						
							| 
									
										
										
										
											2016-11-30 18:43:03 +01:00
										 |  |  |                     'urls': [{'title': 'Wolfram|Alpha', 'url': resp.request.headers['Referer']}]}) | 
					
						
							| 
									
										
										
										
											2016-02-28 02:06:44 +01:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-11-30 18:43:03 +01:00
										 |  |  |     results.append({'url': resp.request.headers['Referer'], | 
					
						
							| 
									
										
										
										
											2016-07-08 01:41:33 +02:00
										 |  |  |                     'title': 'Wolfram|Alpha (' + infobox_title + ')', | 
					
						
							|  |  |  |                     'content': result_content}) | 
					
						
							| 
									
										
										
										
											2016-02-28 02:06:44 +01:00
										 |  |  | 
 | 
					
						
							|  |  |  |     return results |