-
Notifications
You must be signed in to change notification settings - Fork 5
/
wolfram.go
129 lines (103 loc) · 3.17 KB
/
wolfram.go
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package main
// @hipbot Wolfram me pi
// Get first 6 Wolfram search results
// return an HTML list of these results (includes embedded images)
// Wolfram (Alpha) is a search engine for computational information
// For information on Wolfram alpha search API, visit http://products.wolframalpha.com/api/
import (
"encoding/xml"
"fmt"
"net/http"
"net/url"
"os"
"strings"
)
const WOLFRAM_ENDPOINT = "http://api.wolframalpha.com/v2/query"
var (
appid = os.Getenv("WOLFRAM_API_ID")
wolframPostUrl = WOLFRAM_ENDPOINT +
"?format=html" +
"&appid=" + appid
)
type WolframResult struct {
XMLName xml.Name `xml:"queryresult"`
Pods []Pod `xml:"pod"`
Didyoumeans []Didyoumean `xml:"didyoumeans"`
}
// A pod is just a wrapper for one kind of response information
// ie. "Definition", "Synonyms", "Graph", "Usage", etc.
type Pod struct {
Markup string `xml:"markup"`
}
type Value struct {
Name string `xml:"name,attr"`
Desc string `xml:"desc,attr"`
}
type Didyoumean struct {
Didyoumean string `xml:"didyoumean"`
}
func wolframSearch(query string) string {
// Set request input (query) for Wolfram alpha search
// Send GET request, collect response
resp, err := http.Get(wolframPostUrl + "&input=" + url.QueryEscape(query))
if err != nil {
fmt.Printf("Error in HTTP GET: %s", err)
return "error"
}
defer resp.Body.Close()
// Decode XML response
decoder := xml.NewDecoder(resp.Body)
results := new(WolframResult)
decoder.Decode(results)
return fullResponse(*results)
}
// Returns a formatted HTML response with embedded images IF results exists
// Also, returns some "Did you mean.." text IF there are alternative suggestions
func fullResponse(results WolframResult) string {
output := ""
pods := (results).Pods
didyoumeans := (results).Didyoumeans
output += htmlWolframRespose(pods)
if len(didyoumeans) > 0 {
output += didYouMeanText(didyoumeans)
}
return output
}
// Formats the response pods as HTML in a nice, easy to read way
func htmlWolframRespose(pods []Pod) string {
// Check for no pod results
if len(pods) == 0 {
return "I found nothing! So sorry. Your query may be too general. <br>"
}
// Format pods in an unordered list
output := "<ul>"
// Remove the xml wrapper ("<![CDATA[" and "]]")
// Put images on a new line with a 3-space indentation
replacer := strings.NewReplacer("<![CDATA[", "", "]]>", "", "<img", "<br> <img")
// If there is too much text, Hipchat will reject the POST
// Since Wolfram can return a huge number of result pods, we cut them off at 6
for i := range pods {
if i > 5 {
break
}
output += "<li>" + replacer.Replace(pods[i].Markup) + "</li>"
}
output += "</ul>"
return output
}
// didyoumeans are suggestions that relate to the <query>
// Usually didyoumeans correspond with no pod results, but NOT ALWAYS!
func didYouMeanText(didyoumeans []Didyoumean) string {
if len(didyoumeans) == 0 {
return ""
}
// Header text for didyoumeans
output := "Why don't you try one of the following: <br>"
// Format didyoumeans in an unordered list
output += "<ul>"
for i := range didyoumeans {
output += "<li>" + didyoumeans[i].Didyoumean + "</li>"
}
output += "</ul>"
return output
}