working beer plugin, also run tests in plugins dir

This commit is contained in:
Aaron Bieber 2020-02-01 20:45:42 -07:00
parent ca8a9d0b19
commit 05d078e7e9
3 changed files with 110 additions and 24 deletions

View File

@ -8,4 +8,4 @@ sources:
tasks: tasks:
- test_mcchunkie: | - test_mcchunkie: |
cd mcchunkie cd mcchunkie
go test go test ./...

View File

@ -5,9 +5,11 @@ import (
"fmt" "fmt"
"io/ioutil" "io/ioutil"
"log" "log"
"math/rand"
"net/http" "net/http"
"net/url" "net/url"
"regexp" "regexp"
"time"
"github.com/matrix-org/gomatrix" "github.com/matrix-org/gomatrix"
) )
@ -16,27 +18,61 @@ import (
type Beer struct { type Beer struct {
} }
// BeerRecord is the parent beer type // BeerResp represents our response from the api
type BeerRecord struct { type BeerResp struct {
DatasetID string `json:"datasetid"` Nhits int `json:"nhits"`
RecordID string `json:"recordid"` Parameters Parameters `json:"parameters"`
Fields BeerFields `json:"fields"` Records []Records `json:"records"`
} }
// BeerFields ar the fields we care about for any given beer // Parameters are the meta information
type BeerFields struct { type Parameters struct {
Website string `json:"website"` Dataset []string `json:"dataset"`
City string `json:"city"` Timezone string `json:"timezone"`
Name string `json:"name"` Q string `json:"q"`
Country string `json:"country"` Rows int `json:"rows"`
Descr string `json:"descript"` Format string `json:"format"`
Style string `json:"style_name"`
IBU int `json:"ibu"`
BreweryName string `json:"name_breweries"`
} }
// BeerRecords are a collection of responses // Fields are the bits of info we care about
type BeerRecords []BeerRecord type Fields struct {
Website string `json:"website"`
City string `json:"city"`
StyleID string `json:"style_id"`
Name string `json:"name"`
Country string `json:"country"`
CatID string `json:"cat_id"`
BreweryID string `json:"brewery_id"`
Descript string `json:"descript"`
Upc int `json:"upc"`
Coordinates []float64 `json:"coordinates"`
Ibu int `json:"ibu"`
CatName string `json:"cat_name"`
LastMod time.Time `json:"last_mod"`
State string `json:"state"`
StyleName string `json:"style_name"`
Abv float64 `json:"abv"`
Address1 string `json:"address1"`
NameBreweries string `json:"name_breweries"`
Srm int `json:"srm"`
ID string `json:"id"`
AddUser string `json:"add_user"`
}
// Geometry is basically useless
type Geometry struct {
Type string `json:"type"`
Coordinates []float64 `json:"coordinates"`
}
// Records holds our fileds
type Records struct {
Datasetid string `json:"datasetid"`
Recordid string `json:"recordid"`
Fields Fields `json:"fields"`
Geometry Geometry `json:"geometry"`
RecordTimestamp time.Time `json:"record_timestamp"`
}
func (h *Beer) fix(msg string) string { func (h *Beer) fix(msg string) string {
re := regexp.MustCompile(`(?i)^beer: `) re := regexp.MustCompile(`(?i)^beer: `)
@ -48,10 +84,9 @@ func (h *Beer) match(msg string) bool {
return re.MatchString(msg) return re.MatchString(msg)
} }
func (h *Beer) get(beer string) (*BeerRecords, error) { func (h *Beer) get(beer string) (*BeerResp, error) {
u := "https://data.opendatasoft.com/api/records/1.0/search?dataset=open-beer-database%40public-us&q=" u := "https://data.opendatasoft.com/api/records/1.0/search?dataset=open-beer-database%40public-us&q="
u = fmt.Sprintf("%s%s", u, url.PathEscape(beer)) u = fmt.Sprintf("%s%s", u, url.PathEscape(beer))
log.Println(u)
resp, err := http.Get(u) resp, err := http.Get(u)
if err != nil { if err != nil {
return nil, err return nil, err
@ -64,12 +99,36 @@ func (h *Beer) get(beer string) (*BeerRecords, error) {
return nil, err return nil, err
} }
beers := &BeerRecords{} var beers = &BeerResp{}
_ = json.Unmarshal([]byte(body), beers) err = json.Unmarshal([]byte(body), beers)
if err != nil {
return nil, err
}
return beers, nil return beers, nil
} }
func (h *Beer) pretty(b BeerResp, random bool) string {
idx := 0
if random {
rand.Seed(time.Now().Unix())
idx = rand.Intn(len(b.Records))
}
return fmt.Sprintf("%s (%s) by %s from %s, %s - IBU: %d, ABV: %.1f %s\n%s",
b.Records[idx].Fields.Name,
b.Records[idx].Fields.StyleName,
b.Records[idx].Fields.NameBreweries,
b.Records[idx].Fields.City,
b.Records[idx].Fields.State,
b.Records[idx].Fields.Ibu,
b.Records[idx].Fields.Abv,
b.Records[idx].Fields.Website,
b.Records[idx].Fields.Descript,
)
}
// Respond to hi events // Respond to hi events
func (h *Beer) Respond(c *gomatrix.Client, ev *gomatrix.Event, user string) { func (h *Beer) Respond(c *gomatrix.Client, ev *gomatrix.Event, user string) {
if mtype, ok := ev.MessageType(); ok { if mtype, ok := ev.MessageType(); ok {
@ -80,11 +139,19 @@ func (h *Beer) Respond(c *gomatrix.Client, ev *gomatrix.Event, user string) {
beer := h.fix(post) beer := h.fix(post)
if beer != "" { if beer != "" {
log.Printf("%s: responding to '%s'", h.Name(), ev.Sender) log.Printf("%s: responding to '%s'", h.Name(), ev.Sender)
j, err := h.get(beer) brr, err := h.get(beer)
if err != nil { if err != nil {
SendMessage(c, ev.RoomID, fmt.Sprintf("sorry %s, I can't look for beer. (%s)", ev.Sender, err)) SendMessage(c, ev.RoomID, fmt.Sprintf("sorry %s, I can't look for beer. (%s)", ev.Sender, err))
} }
SendMessage(c, ev.RoomID, fmt.Sprintf("%v", j))
switch {
case brr.Nhits == 0:
SendMessage(c, ev.RoomID, "¯\\_(ツ)_/¯")
case brr.Nhits == 1:
SendMessage(c, ev.RoomID, fmt.Sprintf("%s", h.pretty(*brr, false)))
case brr.Nhits > 1:
SendMessage(c, ev.RoomID, fmt.Sprintf("Found %d beers, here is a random one:\n%s", brr.Nhits, h.pretty(*brr, true)))
}
} }
} }
} }

19
plugins/beer_test.go Normal file
View File

@ -0,0 +1,19 @@
package plugins
import (
"fmt"
"testing"
)
func TestBeer(t *testing.T) {
beer := &Beer{}
b, err := beer.get("oskar blues")
if err != nil {
t.Errorf("%+v\n", err)
}
if b.Nhits == 0 {
t.Errorf("Expected 7 results; got %d\n", b.Nhits)
}
fmt.Printf("%+v", b)
}