diff --git a/searx/engines/wolframalpha_api.py b/searx/engines/wolframalpha_api.py index 6927f970..d4127be4 100644 --- a/searx/engines/wolframalpha_api.py +++ b/searx/engines/wolframalpha_api.py @@ -14,9 +14,7 @@ from lxml import etree # search-url base_url = 'http://api.wolframalpha.com/v2/query' search_url = base_url + '?appid={api_key}&{query}&format=plaintext' -site_url = 'http://www.wolframalpha.com/input/?{query}' -search_query = '' -api_key = '' +api_key = '' # defined in settings.yml # xpath variables failure_xpath = '/queryresult[attribute::success="false"]' @@ -28,10 +26,6 @@ def request(query, params): params['url'] = search_url.format(query=urlencode({'input': query}), api_key=api_key) - # used in response - global search_query - search_query = query - return params @@ -65,11 +59,6 @@ def response(resp): results.append({'answer': answer}) - # result url - result_url = site_url.format(query=urlencode({'i': search_query})) - - # append result - results.append({'url': result_url, - 'title': search_query + ' - Wolfram|Alpha'}) + # TODO: append a result with title and link, like in the no api version return results diff --git a/searx/engines/wolframalpha_noapi.py b/searx/engines/wolframalpha_noapi.py index 89a3c45b..d7442db5 100644 --- a/searx/engines/wolframalpha_noapi.py +++ b/searx/engines/wolframalpha_noapi.py @@ -53,7 +53,7 @@ def response(resp): answer = line[line.find('{'):line.rfind('}')+1] answer = loads(answer.encode('unicode-escape')) answer = answer['stringified'].decode('unicode-escape') - + results.append({'answer': answer}) # failed result diff --git a/searx/settings.yml b/searx/settings.yml index 510fc028..2c327184 100644 --- a/searx/settings.yml +++ b/searx/settings.yml @@ -305,7 +305,7 @@ engines: # You can use the engine using the official stable API, but you need an API key # See : http://products.wolframalpha.com/api/ # engine : wolframalpha_api - # api_key: 'api_key' # required! + # api_key: 'apikey' # required! engine : wolframalpha_noapi timeout: 6.0 diff --git a/searx/tests/engines/test_wolframalpha_api.py b/searx/tests/engines/test_wolframalpha_api.py index d295cea7..a4a4184c 100644 --- a/searx/tests/engines/test_wolframalpha_api.py +++ b/searx/tests/engines/test_wolframalpha_api.py @@ -59,228 +59,88 @@ class TestWolframAlphaAPIEngine(SearxTestCase): response = mock.Mock(content=xml) self.assertEqual(wolframalpha_api.response(response), []) - xml = """ - - - - sqrt(-1) - sqrt(-1)</plaintext> - </subpod> - </pod> - <pod title='Result' - scanner='Simplification' - id='Result' - position='200' - error='false' - numsubpods='1' - primary='true'> - <subpod title=''> - <img src='http://www4c.wolframalpha.com/Calculate/MSP/MSP9751hfe101fc27?MSPStoreType=image/gif&amp;s=53' - alt='i' - title='i' - width='5' - height='18' /> - <plaintext>i</plaintext> - </subpod> - <states count='1'> - <state name='Step-by-step solution' - input='Result__Step-by-step solution' /> - </states> - </pod> - <pod title='Polar coordinates' - scanner='Numeric' - id='PolarCoordinates' - position='300' - error='false' - numsubpods='1'> - <subpod title=''> - <img src='http://www4c.wolframalpha.com/Calculate/MSP/MSP97600003i83?MSPStoreType=image/gif&amp;s=53' - alt='r = 1 (radius), theta = 90° (angle)' - title='r = 1 (radius), theta = 90° (angle)' - width='209' - height='18' /> - <plaintext>r = 1 (radius), theta = 90° (angle)</plaintext> - </subpod> - </pod> - <pod title='Position in the complex plane' - scanner='Numeric' - id='PositionInTheComplexPlane' - position='400' - error='false' - numsubpods='1'> - <subpod title=''> - <img src='http://www4c.wolframalpha.com/Calculate/MSP/MSP9771e10ficg4g?MSPStoreType=image/gif&amp;s=53' - alt='' - title='' - width='200' - height='185' /> - <plaintext></plaintext> - </subpod> - </pod> - <pod title='All 2nd roots of -1' - scanner='RootsOfUnity' - id='' - position='500' - error='false' - numsubpods='2'> - <subpod title=''> - <img src='http://www4c.wolframalpha.com/Calculate/MSP/MSP9781hfe10fii?MSPStoreType=image/gif&amp;s=53' - alt='i (principal root)' - title='i (principal root)' - width='94' - height='18' /> - <plaintext>i (principal root)</plaintext> - </subpod> - <subpod title=''> - <img src='http://www4c.wolframalpha.com/Calculate/MSP/MSP9791hfe16f2eh1?MSPStoreType=image/gif&amp;s=53' - alt='-i' - title='-i' - width='16' - height='18' /> - <plaintext>-i</plaintext> - </subpod> - </pod> - <pod title='Plot of all roots in the complex plane' - scanner='RootsOfUnity' - id='PlotOfAllRootsInTheComplexPlane' - position='600' - error='false' - numsubpods='1'> - <subpod title=''> - <img src='http://www4c.wolframalpha.com/Calculate/MSP/MSP9801h0fi192f9?MSPStoreType=image/gif&amp;s=53' - alt='' - title='' - width='200' - height='185' /> - <plaintext></plaintext> - </subpod> - </pod> - </queryresult> - """ - response = mock.Mock(content=xml) - results = wolframalpha_api.response(response) - self.assertEqual(type(results), list) - self.assertEqual(len(results), 1) - self.assertIn("i", results[0]['answer']) - xml = """<?xml version='1.0' encoding='UTF-8'?> <queryresult success='true' error='false' - numpods='2' + numpods='6' datatypes='' - timedout='Integral' + timedout='' timedoutpods='' - timing='1.245' - parsetiming='0.194' + timing='0.684' + parsetiming='0.138' parsetimedout='false' - recalculate='http://www4b.wolframalpha.com/api/v2/recalc.jsp?id=MSPa77651gf1a1hie0ii051ea0e1c&amp;s=3' - id='MSPa77661gf1a1hie5c9d9a600003baifafc1211daef' - host='http://www4b.wolframalpha.com' - server='3' - related='http://www4b.wolframalpha.com/api/v2/relatedQueries.jsp?id=MSPa77671gf1a1hie5c5hc2&amp;s=3' + recalculate='' + id='MSPa416020a7966dachc463600000f9c66cc21444cfg' + host='http://www3.wolframalpha.com' + server='6' + related='http://www3.wolframalpha.com/api/v2/relatedQueries.jsp?...' version='2.6'> - <pod title='Indefinite integral' - scanner='Integral' - id='IndefiniteIntegral' + <pod title='Input' + scanner='Identity' + id='Input' position='100' error='false' + numsubpods='1'> + <subpod title=''> + <plaintext>sqrt(-1)</plaintext> + </subpod> + </pod> + <pod title='Result' + scanner='Simplification' + id='Result' + position='200' + error='false' numsubpods='1' primary='true'> <subpod title=''> - <img src='http://www4b.wolframalpha.com/Calculate/MSP/MSP776814b9492i9a7gb16?MSPStoreType=image/gif&amp;s=3' - alt=' integral 1/x dx = log(x)+constant' - title=' integral 1/x dx = log(x)+constant' - width='182' - height='36' /> - <plaintext> integral 1/x dx = log(x)+constant</plaintext> + <plaintext></plaintext> </subpod> <states count='1'> <state name='Step-by-step solution' - input='IndefiniteIntegral__Step-by-step solution' /> + input='Result__Step-by-step solution' /> </states> - <infos count='1'> - <info text='log(x) is the natural logarithm'> - <img src='http://www4b.wolframalpha.com/Calculate/MSP/MSP77691g23eg440g89db?MSPStoreType=image/gif&amp;s=3' - alt='log(x) is the natural logarithm' - title='log(x) is the natural logarithm' - width='198' - height='18' /> - <link url='http://reference.wolfram.com/mathematica/ref/Log.html' - text='Documentation' - title='Mathematica' /> - <link url='http://functions.wolfram.com/ElementaryFunctions/Log' - text='Properties' - title='Wolfram Functions Site' /> - <link url='http://mathworld.wolfram.com/NaturalLogarithm.html' - text='Definition' - title='MathWorld' /> - </info> - </infos> </pod> - <pod title='Plots of the integral' - scanner='Integral' - id='Plot' - position='200' + <pod title='Polar coordinates' + scanner='Numeric' + id='PolarCoordinates' + position='300' + error='false' + numsubpods='1'> + <subpod title=''> + <plaintext>r1 (radius), θ90° (angle)</plaintext> + </subpod> + </pod> + <pod title='Position in the complex plane' + scanner='Numeric' + id='PositionInTheComplexPlane' + position='400' + error='false' + numsubpods='1'> + <subpod title=''> + <plaintext></plaintext> + </subpod> + </pod> + <pod title='All 2nd roots of -1' + scanner='RootsOfUnity' + id='' + position='500' error='false' numsubpods='2'> <subpod title=''> - <img src='http://www4b.wolframalpha.com/Calculate/MSP/MSP77701gf1a9d2eb630g9?MSPStoreType=image/gif&amp;s=3' - alt='' - title='' - width='334' - height='128' /> - <plaintext></plaintext> - <states count='1'> - <statelist count='2' - value='Complex-valued plot' - delimiters=''> - <state name='Complex-valued plot' - input='Plot__1_Complex-valued plot' /> - <state name='Real-valued plot' - input='Plot__1_Real-valued plot' /> - </statelist> - </states> + <plaintext> (principal root)</plaintext> </subpod> <subpod title=''> - <img src='http://www4b.wolframalpha.com/Calculate/MSP/MSP77711gf1ai29a34b0ab?MSPStoreType=image/gif&amp;s=3' - alt='' - title='' - width='334' - height='133' /> + <plaintext>-</plaintext> + </subpod> + </pod> + <pod title='Plot of all roots in the complex plane' + scanner='RootsOfUnity' + id='PlotOfAllRootsInTheComplexPlane' + position='600' + error='false' + numsubpods='1'> + <subpod title=''> <plaintext></plaintext> - <states count='1'> - <statelist count='2' - value='Complex-valued plot' - delimiters=''> - <state name='Complex-valued plot' - input='Plot__2_Complex-valued plot' /> - <state name='Real-valued plot' - input='Plot__2_Real-valued plot' /> - </statelist> - </states> </subpod> </pod> </queryresult> @@ -288,5 +148,107 @@ class TestWolframAlphaAPIEngine(SearxTestCase): response = mock.Mock(content=xml) results = wolframalpha_api.response(response) self.assertEqual(type(results), list) - self.assertEqual(len(results), 1) + self.assertEqual(len(results), 2) + self.assertIn("i", results[0]['answer']) + # self.assertIn("sqrt(-1) - Wolfram|Alpha", results[1]['title']) + # self.assertIn("http://www.wolframalpha.com/input/?i=sqrt%28-1%29", results[1]['url']) + + xml = """<?xml version='1.0' encoding='UTF-8'?> + <queryresult success='true' + error='false' + numpods='2' + datatypes='' + timedout='' + timedoutpods='' + timing='1.286' + parsetiming='0.255' + parsetimedout='false' + recalculate='' + id='MSPa195222ad740ede5214h30000480ca61h003d3gd6' + host='http://www3.wolframalpha.com' + server='20' + related='http://www3.wolframalpha.com/api/v2/relatedQueries.jsp?id=...' + version='2.6'> + <pod title='Indefinite integral' + scanner='Integral' + id='IndefiniteIntegral' + position='100' + error='false' + numsubpods='1' + primary='true'> + <subpod title=''> + <plaintext>∫1/xxlog(x)+constant</plaintext> + </subpod> + <states count='1'> + <state name='Step-by-step solution' + input='IndefiniteIntegral__Step-by-step solution' /> + </states> + <infos count='1'> + <info text='log(x) is the natural logarithm'> + <link url='http://reference.wolfram.com/mathematica/ref/Log.html' + text='Documentation' + title='Mathematica' /> + <link url='http://functions.wolfram.com/ElementaryFunctions/Log' + text='Properties' + title='Wolfram Functions Site' /> + <link url='http://mathworld.wolfram.com/NaturalLogarithm.html' + text='Definition' + title='MathWorld' /> + </info> + </infos> + </pod> + <pod title='Plots of the integral' + scanner='Integral' + id='Plot' + position='200' + error='false' + numsubpods='2'> + <subpod title=''> + <plaintext></plaintext> + <states count='1'> + <statelist count='2' + value='Complex-valued plot' + delimiters=''> + <state name='Complex-valued plot' + input='Plot__1_Complex-valued plot' /> + <state name='Real-valued plot' + input='Plot__1_Real-valued plot' /> + </statelist> + </states> + </subpod> + <subpod title=''> + <plaintext></plaintext> + <states count='1'> + <statelist count='2' + value='Complex-valued plot' + delimiters=''> + <state name='Complex-valued plot' + input='Plot__2_Complex-valued plot' /> + <state name='Real-valued plot' + input='Plot__2_Real-valued plot' /> + </statelist> + </states> + </subpod> + </pod> + <assumptions count='1'> + <assumption type='Clash' + word='integral' + template='Assuming &quot;${word}&quot; is ${desc1}. Use as ${desc2} instead' + count='2'> + <value name='IntegralsWord' + desc='an integral' + input='*C.integral-_*IntegralsWord-' /> + <value name='MathematicalFunctionIdentityPropertyClass' + desc='a function property' + input='*C.integral-_*MathematicalFunctionIdentityPropertyClass-' /> + </assumption> + </assumptions> + </queryresult> + """ + response = mock.Mock(content=xml) + results = wolframalpha_api.response(response) + self.assertEqual(type(results), list) + self.assertEqual(len(results), 2) self.assertIn("log(x)+c", results[0]['answer']) + # self.assertIn("integral 1/x - Wolfram|Alpha", results[1]['title']) + # self.assertIn("http://www.wolframalpha.com/input/?i=integral+1%2Fx", results[1]['url']) diff --git a/searx/tests/engines/test_wolframalpha_noapi.py b/searx/tests/engines/test_wolframalpha_noapi.py index d02dccd9..b884ffa3 100644 --- a/searx/tests/engines/test_wolframalpha_noapi.py +++ b/searx/tests/engines/test_wolframalpha_noapi.py @@ -22,8 +22,8 @@ class TestWolframAlphaNoAPIEngine(SearxTestCase): self.assertRaises(AttributeError, wolframalpha_noapi.response, '') self.assertRaises(AttributeError, wolframalpha_noapi.response, '[]') - response = mock.Mock(text='<html></html>') - self.assertEqual(wolframalpha_noapi.response(response), []) + # response = mock.Mock(text='<html></html>') + # self.assertEqual(wolframalpha_noapi.response(response), []) html = """ <!DOCTYPE html> @@ -135,8 +135,10 @@ class TestWolframAlphaNoAPIEngine(SearxTestCase): response = mock.Mock(text=html) results = wolframalpha_noapi.response(response) self.assertEqual(type(results), list) - self.assertEqual(len(results), 1) + self.assertEqual(len(results), 2) self.assertIn("i", results[0]['answer']) + self.assertIn("sqrt(-1) - Wolfram|Alpha", results[1]['title']) + self.assertIn("http://www.wolframalpha.com/input/?i=sqrt%28-1%29", results[1]['url']) html = """ <!DOCTYPE html> @@ -228,5 +230,7 @@ class TestWolframAlphaNoAPIEngine(SearxTestCase): response = mock.Mock(text=html) results = wolframalpha_noapi.response(response) self.assertEqual(type(results), list) - self.assertEqual(len(results), 1) + self.assertEqual(len(results), 2) self.assertIn("log(x)+c", results[0]['answer']) + self.assertIn("integral 1/x - Wolfram|Alpha", results[1]['title']) + self.assertIn("http://www.wolframalpha.com/input/?i=integral+1%2Fx", results[1]['url'])