-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathxkcd.go
99 lines (93 loc) · 2.81 KB
/
xkcd.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
package module
import (
"fmt"
"github.com/davidscholberg/irkbot/lib/configure"
"github.com/davidscholberg/irkbot/lib/message"
"github.com/nishanths/go-xkcd"
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
"strconv"
"strings"
"time"
)
const apiUrlFmtDefine = "https://relevantxkcd.appspot.com/process?%s"
func helpxkcd() []string {
s := "xkcd <search> - find a xkcd comic relevant to the search term"
return []string{s}
}
//Perform the actual GET and return the resulting body as a string.
//This function closes the response body.
func getComicString(response *http.Response, responseSizeLimit int64) (string, error) {
defer response.Body.Close()
bodyBytes, err := ioutil.ReadAll(io.LimitReader(response.Body, responseSizeLimit))
if err != nil {
return "", err
}
bodyString := string(bodyBytes)
return bodyString, nil
}
//Parse the body string for the comic number we want
func parseString(bodyString string) (string, error) {
bodyStrings := strings.Split(bodyString, "\n")
if len(bodyStrings) < 3 {
return "", fmt.Errorf("error in parsing string: splitting body by line failed")
}
spacedStrings := strings.Fields(bodyStrings[2])
if len(spacedStrings) < 1 {
return "", fmt.Errorf("error in parsing string: accessing substring of bodyStrings failed")
}
return spacedStrings[0], nil
}
//Method called on xkcd command, named funky so as not to collide with xkcd-go
func getXKCD(cfg *configure.Config, in *message.InboundMsg, actions *actions) {
comicMsg := "enter a search term plz"
//If no search term, gently remind the user to input one
if len(in.MsgArgs[1:]) == 0 {
actions.say(comicMsg)
return
}
query := url.Values{}
query.Add("action", "xkcd")
search := strings.Join(in.MsgArgs[1:], " ")
query.Add("query", search)
apiUrl := fmt.Sprintf(apiUrlFmtDefine, query.Encode())
response, err := actions.httpGet(apiUrl)
if err != nil {
fmt.Fprintln(os.Stderr, err)
actions.say("something borked, try again")
return
}
comicString, comicErr := getComicString(response, cfg.Http.ResponseSizeLimit)
if comicErr != nil {
fmt.Fprintln(os.Stderr, comicErr)
actions.say("something borked, try again")
return
}
comicNum, parseErr := parseString(comicString)
if parseErr != nil {
fmt.Fprintln(os.Stderr, parseErr)
actions.say("something borked, try again")
return
}
client := &xkcd.Client{
HTTPClient: &http.Client{Timeout: time.Duration(cfg.Http.Timeout) * time.Second},
Config: xkcd.Config{UseHTTPS: true},
}
i, strconvErr := strconv.Atoi(comicNum)
if strconvErr != nil {
fmt.Fprintln(os.Stderr, strconvErr)
actions.say("something borked, try again")
return
}
comicGet, err := client.Get(i)
if err != nil {
fmt.Fprintln(os.Stderr, err)
actions.say("something borked, try again")
return
}
comicMsg = fmt.Sprintf("%s - https://xkcd.com/%s/", comicGet.Title, comicNum)
actions.say(comicMsg)
}