package urban import ( "encoding/json" "errors" "io/ioutil" "net/http" "net/url" "sort" ) const baseURL = `http://api.urbandictionary.com/v0/define?term=` type Answer struct { List []Entry `json:"list"` ResultType string `json:"result_type"` Sounds []string `json:"sounds"` Tags []string `json:"tags"` } type Entry struct { Author string `json:"author"` CurrentVote string `json:"current_vote"` DefID int `json:"defid"` Definition string `json:"definition"` Example string `json:"example"` Permalink string `json:"permalink"` ThumbsDown int `json:"thumbs_down"` ThumbsUp int `json:"thumbs_up"` Word string `json:"word"` } var ErrNoMatches = errors.New("no matches") type byRatio []Entry func (l byRatio) Len() int { return len(l) } func (l byRatio) Swap(i, j int) { l[i], l[j] = l[j], l[i] } func (l byRatio) Less(i, j int) bool { a := float64(l[i].ThumbsUp) / float64(l[i].ThumbsDown) b := float64(l[j].ThumbsUp) / float64(l[j].ThumbsDown) return a < b } func Query(q string) (Answer, error) { resp, err := http.Get(baseURL + url.QueryEscape(q)) if err != nil { return Answer{}, err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return Answer{}, err } a := Answer{} err = json.Unmarshal(body, &a) return a, err } func QueryTop(q string) (Entry, error) { a, err := Query(q) if err != nil { return Entry{}, err } if len(a.List) > 0 { sort.Sort(sort.Reverse(byRatio(a.List))) return a.List[0], nil } return Entry{}, ErrNoMatches }