From 07651ae4a79c6949c9333df6b72d46b134e6ed6c Mon Sep 17 00:00:00 2001 From: Christine Dodrill Date: Fri, 25 Aug 2017 07:46:50 -0700 Subject: [PATCH] move bot to cmd/ --- .gitignore | 1 - cmd/vyvanse/.DS_Store | Bin 0 -> 6148 bytes cmd/vyvanse/.dockerignore | 1 + cmd/vyvanse/dice.go | 27 ++++++++ cmd/vyvanse/gops.go | 13 ++++ cmd/vyvanse/hipster.go | 52 +++++++++++++++ cmd/vyvanse/main.go | 127 +++++++++++++++++++++++++++++++++++++ cmd/vyvanse/printerfact.go | 47 ++++++++++++++ cmd/vyvanse/spla2n.go | 114 +++++++++++++++++++++++++++++++++ docker-compose.yml | 21 ++++++ 10 files changed, 402 insertions(+), 1 deletion(-) create mode 100644 cmd/vyvanse/.DS_Store create mode 100644 cmd/vyvanse/.dockerignore create mode 100644 cmd/vyvanse/dice.go create mode 100644 cmd/vyvanse/gops.go create mode 100644 cmd/vyvanse/hipster.go create mode 100644 cmd/vyvanse/main.go create mode 100644 cmd/vyvanse/printerfact.go create mode 100644 cmd/vyvanse/spla2n.go diff --git a/.gitignore b/.gitignore index d7e2efa..4c49bd7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1 @@ .env -vyvanse diff --git a/cmd/vyvanse/.DS_Store b/cmd/vyvanse/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T0 lastXKCD { + sp.LogFields(otlog.String("image.url", comic.ImageURL), otlog.String("target", *pesterChannel)) + + req, err := http.NewRequest(http.MethodGet, comic.ImageURL, nil) + if err != nil { + ln.Error(ctx, err, ln.F{"action": "make request"}) + sp.LogFields(otlog.Error(err)) + return + } + + resp, err := http.DefaultClient.Do(req) + if err != nil { + ln.Error(ctx, err, ln.F{"action": "http get", "url": comic.ImageURL}) + sp.LogFields(otlog.Error(err)) + return + } + + fname := fmt.Sprintf("%d - %s.png", comic.Number, comic.Title) + msg := fmt.Sprintf("New XKCD comic uploaded: %d - %s\n\n*%s*", comic.Number, comic.Title, comic.Alt) + _, err = dg.ChannelFileSendWithMessage(*pesterChannel, msg, fname, resp.Body) + if err != nil { + ln.Error(ctx, err, ln.F{"action": "send xkcd upload", "to": *pesterChannel}) + sp.LogFields(otlog.Error(err)) + return + } + + lastXKCD = comic.Number + } + }) + + c.Start() + + if *zipkinURL != "" { + collector, err := zipkin.NewHTTPCollector(*zipkinURL) + if err != nil { + ln.FatalErr(context.Background(), err) + } + tracer, err := zipkin.NewTracer( + zipkin.NewRecorder(collector, false, "vyvanse:5000", "vyvanse")) + if err != nil { + ln.FatalErr(context.Background(), err) + } + + opentracing.SetGlobalTracer(tracer) + } + + cs := bot.NewCommandSet() + cs.Prefix = ">" + + cs.AddCmd("hipster", "generates hipster-sounding text", bot.NoPermissions, hipster) + cs.AddCmd("printerfact", "facts about printers", bot.NoPermissions, printerFact) + cs.AddCmd("dice", "roll the dice", bot.NoPermissions, roll) + cs.AddCmd("splattus", "splatoon 2 map rotation status", bot.NoPermissions, spla2nMaps) + + dg.AddHandler(func(s *discordgo.Session, m *discordgo.MessageCreate) { + err := cs.Run(s, m.Message) + if err != nil { + ln.Error(context.Background(), err, ln.F{"action": "run commandSet on message"}) + } + }) + + // Open the websocket and begin listening. + err = dg.Open() + if err != nil { + fmt.Println("error opening connection,", err) + return + } + + fmt.Println("Bot is now running. Press CTRL-C to exit.") + // Simple way to keep program running until CTRL-C is pressed. + <-make(chan struct{}) + return +} diff --git a/cmd/vyvanse/printerfact.go b/cmd/vyvanse/printerfact.go new file mode 100644 index 0000000..f7c505b --- /dev/null +++ b/cmd/vyvanse/printerfact.go @@ -0,0 +1,47 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + + "github.com/bwmarrin/discordgo" + opentracing "github.com/opentracing/opentracing-go" +) + +func printerFact(ctx context.Context, s *discordgo.Session, m *discordgo.Message, parv []string) error { + sp, ctx := opentracing.StartSpanFromContext(ctx, "printer.fact") + defer sp.Finish() + + fact, err := getPrinterFact() + if err != nil { + return err + } + + s.ChannelMessageSend(m.ChannelID, fact) + return nil +} + +func getPrinterFact() (string, error) { + resp, err := http.Get("https://xena.stdlib.com/printerfacts") + if err != nil { + return "", err + } + + factStruct := &struct { + Facts []string `json:"facts"` + }{} + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return "", err + } + + json.Unmarshal(body, factStruct) + + text := fmt.Sprintf("%s", factStruct.Facts[0]) + + return text, nil +} diff --git a/cmd/vyvanse/spla2n.go b/cmd/vyvanse/spla2n.go new file mode 100644 index 0000000..e9981bd --- /dev/null +++ b/cmd/vyvanse/spla2n.go @@ -0,0 +1,114 @@ +package main + +import ( + "context" + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "strings" + "time" + + "github.com/bwmarrin/discordgo" + opentracing "github.com/opentracing/opentracing-go" + otlog "github.com/opentracing/opentracing-go/log" +) + +func spla2nMaps(ctx context.Context, s *discordgo.Session, msg *discordgo.Message, parv []string) error { + sp, ctx := opentracing.StartSpanFromContext(ctx, "spla2nMaps") + defer sp.Finish() + + resp, err := http.Get("https://splatoon.ink/schedule2") + if err != nil { + sp.LogFields(otlog.Error(err), otlog.String("step", "http get")) + return err + } + + st := &splattus{} + + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + sp.LogFields(otlog.Error(err), otlog.String("step", "http response read")) + return err + } + + json.Unmarshal(body, st) + + var modeInfo []string + + for _, mode := range st.Modes.Regular { + if mode.Active() { + modeInfo = append(modeInfo, mode.String()) + } + } + + for _, mode := range st.Modes.Gachi { + if mode.Active() { + modeInfo = append(modeInfo, mode.String()) + } + } + + for _, mode := range st.Modes.League { + if mode.Active() { + modeInfo = append(modeInfo, mode.String()) + } + } + + text := strings.Join(modeInfo, "\n") + + _, err = s.ChannelMessageSend(msg.ChannelID, text) + return err +} + +type splatoonMode struct { + StartTime int64 `json:"startTime"` + EndTime int64 `json:"endTime"` + Maps []string `json:"maps"` + Rule splatoonRule `json:"rule"` + Mode splatoonGameMode `json:"mode"` +} + +func (sm splatoonMode) Active() bool { + beg := time.Unix(sm.StartTime, 0) + end := time.Unix(sm.EndTime, 0) + now := time.Now() + + return now.After(beg) && now.Before(end) +} + +func (sm splatoonMode) String() string { + maps := strings.Join(sm.Maps, ", ") + end := time.Unix(sm.EndTime, 0) + now := time.Now() + diff := end.Sub(now) + + return fmt.Sprintf("%s:\nRotation ends at %s (in %s)\nMaps: %s\nRule: %s\n", sm.Mode, end.Format(time.RFC3339), diff, maps, sm.Rule) +} + +type splatoonGameMode struct { + Key string `json:"key"` + Name string `json:"name"` +} + +func (sgm splatoonGameMode) String() string { + return sgm.Name +} + +type splatoonRule struct { + Key string `json:"key"` + MultilineName string `json:"multiline_name"` + Name string `json:"name"` +} + +func (sr splatoonRule) String() string { + return sr.Name +} + +type splattus struct { + UpdateTime int64 `json:"updateTime"` + Modes struct { + League []splatoonMode `json:"league"` + Regular []splatoonMode `json:"regular"` + Gachi []splatoonMode `json:"gachi"` + } `json:"modes"` +} diff --git a/docker-compose.yml b/docker-compose.yml index c14a478..316e33e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,6 +1,9 @@ version: "3" services: + # Persistence layers and dev tools + + # http://127.0.0.1:9411 zipkin: image: openzipkin/zipkin environment: @@ -8,8 +11,26 @@ services: ports: - "9411:9411" + # message queue + mq: + image: drone/mq + + # database + rqlite: + restart: always + image: rqlite/rqlite:4.0.2 + volumes: + - rqlite:/rqlite/file + command: -on-disk -http-adv-addr rqlite:4001 + + # the bot and event sourcing ingress vyvanse: image: xena/vyvanse env_file: ./.env depends_on: - zipkin + - mq + - rqlite + +volumes: + rqlite: