-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathwolfram.py
99 lines (82 loc) · 3.98 KB
/
wolfram.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
from data.wolfram_templates import wolfram_templates
import requests
import xml.etree.ElementTree as ET
import random
import traceback
import re
def answers(client, event, wolfram_appid, bingid):
# This function can also be used directly as a response function if you want to remove the Pokemon stuff
message = event.get('text_query', '')
if not event.get('speaking_to_me') or len(message) < 2:
# Don't waste API calls on mostly empty strings
return None
words = [word.lower() for word in message.split() if len(word) > 1]
image_triggers = ['giphy', 'gif', 'animate', 'animated', 'image', 'picture', 'meme', 'graph', 'chart']
is_image = len(set(words).intersection(image_triggers)) > 0
try:
assert wolfram_appid and not is_image
# TODO: Enable wolfram images for graphs
return _wolfram_api(message, wolfram_appid)
except Exception:
try:
assert bingid
return _bing_api(message, bingid, is_image)
except Exception:
traceback.print_exc()
return random.choice(wolfram_templates['fail'])
def _bing_api(message, bingid, is_image):
print u"Hitting Bing API for: " + message
api_loc = 'Image' if is_image else 'Web'
url = 'https://api.datamarket.azure.com/Bing/Search/v1/' + api_loc
auth = ('', bingid)
message = message.replace("'", "''") # Escape single quotes
params = {'Query': u"'{0}'".format(message), '$format': 'json', '$top': 1, 'Adult': "'Strict'"}
response = requests.get(url, auth=auth, params=params)
#print response.content
response = response.json()
if is_image:
quote = response['d']['results'][0]['MediaUrl']
# If we get a Giphy, ensure we are using the animated one, not the static ones
quote = re.sub(r'(giphy\.com\/.*)\/.+_s\.(?:jpe?g|gif)', r'\1/giphy.gif', quote)
else:
# Removing the protocol ensures the link doesn't expand in the messages
link = response['d']['results'][0]['Url'].replace('https://', '').replace('http://', '')
quote = response['d']['results'][0]['Description'] + u" " + link
assert len(quote) > 1
return quote
def _wolfram_api(message, appid):
print u"Hitting Wolfram|Alpha for: " + message
params = {'appid': appid, 'input': message, 'format': 'plaintext'}
response = requests.get('http://api.wolframalpha.com/v2/query', params=params)
xml_response = ET.fromstring(response.content)
interpretation = xml_response.findall('pod')[0].find('subpod').find('plaintext').text
answer = xml_response.findall('pod')[1].find('subpod').find('plaintext').text
quote = _wolfram_format_quote(interpretation, answer)
return quote
def _wolfram_format_quote(interpretation, answer):
# Try to get more conversational version of the input interpretation
# Example input is "Canada | population"
# Make sure we got a valid answer, or else we should just try something else
assert answer
assert answer != '(data not available)'
answer = _wolfram_decode(answer)
interpretation = _wolfram_decode(interpretation)
parts = interpretation.split(' | ')
if len(parts) == 0:
return interpretation + ":" + answer
elif len(parts) == 1:
template = random.choice(wolfram_templates['single'])
return template.format(input=interpretation, answer=answer)
elif len(parts) == 2:
template = random.choice(wolfram_templates['double'])
return template.format(i1=parts[0], i2=parts[1], answer=answer)
elif len(parts) == 3:
template = random.choice(wolfram_templates['triple'])
return template.format(i1=parts[0], i2=parts[1], i3=parts[2], answer=answer)
else:
template = random.choice(wolfram_templates['many'])
return template.format(input=interpretation, answer=answer)
def _wolfram_decode(text):
# Wolfram Alpha uses unicode private use characters. I can't find a reference, but I've seen them in results.
text = text.replace(u'\uf7d9', '=')
return text