goals: mostly done, time to try it

This commit is contained in:
Chris Sexton 2020-05-26 11:38:55 -04:00 committed by Chris Sexton
parent b1f46d6517
commit ccfdb5a715
6 changed files with 175 additions and 84 deletions

View File

@ -11,7 +11,7 @@ import (
"github.com/velour/catbase/plugins/achievements" "github.com/velour/catbase/plugins/achievements"
"github.com/velour/catbase/plugins/aoc" "github.com/velour/catbase/plugins/aoc"
"github.com/velour/catbase/plugins/counter/goals" "github.com/velour/catbase/plugins/goals"
"github.com/velour/catbase/plugins/meme" "github.com/velour/catbase/plugins/meme"
"github.com/velour/catbase/plugins/sms" "github.com/velour/catbase/plugins/sms"
"github.com/velour/catbase/plugins/twitter" "github.com/velour/catbase/plugins/twitter"

View File

@ -75,6 +75,12 @@ func New(b bot.Bot) *BeersPlugin {
p.registerWeb() p.registerWeb()
token := p.c.Get("Untappd.Token", "NONE")
if token == "NONE" || token == "" {
log.Error().Msgf("No untappd token. Checking disabled.")
return p
}
for _, channel := range p.c.GetArray("Untappd.Channels", []string{}) { for _, channel := range p.c.GetArray("Untappd.Channels", []string{}) {
go p.untappdLoop(b.DefaultConnector(), channel) go p.untappdLoop(b.DefaultConnector(), channel)
} }
@ -229,7 +235,7 @@ func (p *BeersPlugin) help(c bot.Connector, kind bot.Kind, message msg.Message,
} }
func getUserBeers(db *sqlx.DB, user string) counter.Item { func getUserBeers(db *sqlx.DB, user string) counter.Item {
booze, _ := counter.GetItem(db, user, itemName) booze, _ := counter.GetUserItem(db, user, itemName)
return booze return booze
} }

View File

@ -3,10 +3,11 @@
package beers package beers
import ( import (
"github.com/velour/catbase/plugins/cli"
"strings" "strings"
"testing" "testing"
"github.com/velour/catbase/plugins/cli"
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/velour/catbase/bot" "github.com/velour/catbase/bot"
"github.com/velour/catbase/bot/msg" "github.com/velour/catbase/bot/msg"
@ -40,7 +41,7 @@ func makeBeersPlugin(t *testing.T) (*BeersPlugin, *bot.MockBot) {
func TestCounter(t *testing.T) { func TestCounter(t *testing.T) {
_, mb := makeBeersPlugin(t) _, mb := makeBeersPlugin(t)
i, err := counter.GetItem(mb.DB(), "tester", "test") i, err := counter.GetUserItem(mb.DB(), "tester", "test")
if !assert.Nil(t, err) { if !assert.Nil(t, err) {
t.Log(err) t.Log(err)
t.Fatal() t.Fatal()
@ -55,7 +56,7 @@ func TestImbibe(t *testing.T) {
assert.Len(t, mb.Messages, 1) assert.Len(t, mb.Messages, 1)
b.message(makeMessage("!imbibe")) b.message(makeMessage("!imbibe"))
assert.Len(t, mb.Messages, 2) assert.Len(t, mb.Messages, 2)
it, err := counter.GetItem(mb.DB(), "tester", itemName) it, err := counter.GetUserItem(mb.DB(), "tester", itemName)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 2, it.Count) assert.Equal(t, 2, it.Count)
} }
@ -63,7 +64,7 @@ func TestEq(t *testing.T) {
b, mb := makeBeersPlugin(t) b, mb := makeBeersPlugin(t)
b.message(makeMessage("!beers = 3")) b.message(makeMessage("!beers = 3"))
assert.Len(t, mb.Messages, 1) assert.Len(t, mb.Messages, 1)
it, err := counter.GetItem(mb.DB(), "tester", itemName) it, err := counter.GetUserItem(mb.DB(), "tester", itemName)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 3, it.Count) assert.Equal(t, 3, it.Count)
} }
@ -72,7 +73,7 @@ func TestEqNeg(t *testing.T) {
b, mb := makeBeersPlugin(t) b, mb := makeBeersPlugin(t)
b.message(makeMessage("!beers = -3")) b.message(makeMessage("!beers = -3"))
assert.Len(t, mb.Messages, 1) assert.Len(t, mb.Messages, 1)
it, err := counter.GetItem(mb.DB(), "tester", itemName) it, err := counter.GetUserItem(mb.DB(), "tester", itemName)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 0, it.Count) assert.Equal(t, 0, it.Count)
} }
@ -83,7 +84,7 @@ func TestEqZero(t *testing.T) {
b.message(makeMessage("!beers = 0")) b.message(makeMessage("!beers = 0"))
assert.Len(t, mb.Messages, 2) assert.Len(t, mb.Messages, 2)
assert.Contains(t, mb.Messages[1], "reversal of fortune") assert.Contains(t, mb.Messages[1], "reversal of fortune")
it, err := counter.GetItem(mb.DB(), "tester", itemName) it, err := counter.GetUserItem(mb.DB(), "tester", itemName)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 0, it.Count) assert.Equal(t, 0, it.Count)
} }
@ -94,7 +95,7 @@ func TestBeersPlusEq(t *testing.T) {
assert.Len(t, mb.Messages, 1) assert.Len(t, mb.Messages, 1)
b.message(makeMessage("beers += 5")) b.message(makeMessage("beers += 5"))
assert.Len(t, mb.Messages, 2) assert.Len(t, mb.Messages, 2)
it, err := counter.GetItem(mb.DB(), "tester", itemName) it, err := counter.GetUserItem(mb.DB(), "tester", itemName)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 10, it.Count) assert.Equal(t, 10, it.Count)
} }
@ -102,11 +103,11 @@ func TestBeersPlusEq(t *testing.T) {
func TestPuke(t *testing.T) { func TestPuke(t *testing.T) {
b, mb := makeBeersPlugin(t) b, mb := makeBeersPlugin(t)
b.message(makeMessage("beers += 5")) b.message(makeMessage("beers += 5"))
it, err := counter.GetItem(mb.DB(), "tester", itemName) it, err := counter.GetUserItem(mb.DB(), "tester", itemName)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 5, it.Count) assert.Equal(t, 5, it.Count)
b.message(makeMessage("puke")) b.message(makeMessage("puke"))
it, err = counter.GetItem(mb.DB(), "tester", itemName) it, err = counter.GetUserItem(mb.DB(), "tester", itemName)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 0, it.Count) assert.Equal(t, 0, it.Count)
} }
@ -114,7 +115,7 @@ func TestPuke(t *testing.T) {
func TestBeersReport(t *testing.T) { func TestBeersReport(t *testing.T) {
b, mb := makeBeersPlugin(t) b, mb := makeBeersPlugin(t)
b.message(makeMessage("beers += 5")) b.message(makeMessage("beers += 5"))
it, err := counter.GetItem(mb.DB(), "tester", itemName) it, err := counter.GetUserItem(mb.DB(), "tester", itemName)
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 5, it.Count) assert.Equal(t, 5, it.Count)
b.message(makeMessage("beers")) b.message(makeMessage("beers"))

View File

@ -139,8 +139,33 @@ func MkAlias(db *sqlx.DB, aliasName, pointsTo string) (*alias, error) {
return &alias{db, id, aliasName, pointsTo}, nil return &alias{db, id, aliasName, pointsTo}, nil
} }
// GetItem returns a specific counter for a subject // GetUserItem returns a specific counter for all subjects
func GetItem(db *sqlx.DB, nick, itemName string) (Item, error) { func GetItem(db *sqlx.DB, itemName string) ([]Item, error) {
itemName = trimUnicode(itemName)
var items []Item
var a alias
if err := db.Get(&a, `select * from counter_alias where item=?`, itemName); err == nil {
itemName = a.PointsTo
} else {
log.Error().Err(err).Interface("alias", a)
}
err := db.Select(&items, `select * from counter where item= ?`, itemName)
if err != nil {
return nil, err
}
log.Debug().
Str("itemName", itemName).
Interface("items", items).
Msg("got item")
for _, i := range items {
i.DB = db
}
return items, nil
}
// GetUserItem returns a specific counter for a subject
func GetUserItem(db *sqlx.DB, nick, itemName string) (Item, error) {
itemName = trimUnicode(itemName) itemName = trimUnicode(itemName)
var item Item var item Item
item.DB = db item.DB = db
@ -170,6 +195,7 @@ func GetItem(db *sqlx.DB, nick, itemName string) (Item, error) {
return item, nil return item, nil
} }
// GetUserItem returns a specific counter for a subject
// Create saves a counter // Create saves a counter
func (i *Item) Create() error { func (i *Item) Create() error {
res, err := i.Exec(`insert into counter (nick, item, count) values (?, ?, ?);`, res, err := i.Exec(`insert into counter (nick, item, count) values (?, ?, ?);`,
@ -376,7 +402,7 @@ func (p *CounterPlugin) message(c bot.Connector, kind bot.Kind, message msg.Mess
subject := strings.ToLower(nick) subject := strings.ToLower(nick)
itemName := strings.ToLower(parts[1]) itemName := strings.ToLower(parts[1])
it, err := GetItem(p.DB, subject, itemName) it, err := GetUserItem(p.DB, subject, itemName)
if err != nil { if err != nil {
log.Error(). log.Error().
Err(err). Err(err).
@ -417,7 +443,7 @@ func (p *CounterPlugin) message(c bot.Connector, kind bot.Kind, message msg.Mess
} }
var item Item var item Item
item, err := GetItem(p.DB, subject, itemName) item, err := GetUserItem(p.DB, subject, itemName)
switch { switch {
case err == sql.ErrNoRows: case err == sql.ErrNoRows:
p.Bot.Send(c, bot.Message, channel, fmt.Sprintf("I don't think %s has any %s.", p.Bot.Send(c, bot.Message, channel, fmt.Sprintf("I don't think %s has any %s.",
@ -455,7 +481,7 @@ func (p *CounterPlugin) message(c bot.Connector, kind bot.Kind, message msg.Mess
if strings.HasSuffix(parts[0], "++") { if strings.HasSuffix(parts[0], "++") {
// ++ those fuckers // ++ those fuckers
item, err := GetItem(p.DB, subject, itemName) item, err := GetUserItem(p.DB, subject, itemName)
if err != nil { if err != nil {
log.Error(). log.Error().
Err(err). Err(err).
@ -472,7 +498,7 @@ func (p *CounterPlugin) message(c bot.Connector, kind bot.Kind, message msg.Mess
return true return true
} else if strings.HasSuffix(parts[0], "--") { } else if strings.HasSuffix(parts[0], "--") {
// -- those fuckers // -- those fuckers
item, err := GetItem(p.DB, subject, itemName) item, err := GetUserItem(p.DB, subject, itemName)
if err != nil { if err != nil {
log.Error(). log.Error().
Err(err). Err(err).
@ -503,7 +529,7 @@ func (p *CounterPlugin) message(c bot.Connector, kind bot.Kind, message msg.Mess
if parts[1] == "+=" { if parts[1] == "+=" {
// += those fuckers // += those fuckers
item, err := GetItem(p.DB, subject, itemName) item, err := GetUserItem(p.DB, subject, itemName)
if err != nil { if err != nil {
log.Error(). log.Error().
Err(err). Err(err).
@ -521,7 +547,7 @@ func (p *CounterPlugin) message(c bot.Connector, kind bot.Kind, message msg.Mess
return true return true
} else if parts[1] == "-=" { } else if parts[1] == "-=" {
// -= those fuckers // -= those fuckers
item, err := GetItem(p.DB, subject, itemName) item, err := GetUserItem(p.DB, subject, itemName)
if err != nil { if err != nil {
log.Error(). log.Error().
Err(err). Err(err).
@ -565,7 +591,7 @@ func (p *CounterPlugin) checkMatch(c bot.Connector, message msg.Message) bool {
itemName := strings.ToLower(submatches[1]) itemName := strings.ToLower(submatches[1])
// We will specifically allow :tea: to keep compatability // We will specifically allow :tea: to keep compatability
item, err := GetItem(p.DB, nick, itemName) item, err := GetUserItem(p.DB, nick, itemName)
if err != nil || (item.Count == 0 && item.Item != ":tea:") { if err != nil || (item.Count == 0 && item.Item != ":tea:") {
log.Error(). log.Error().
Err(err). Err(err).
@ -630,7 +656,7 @@ func (p *CounterPlugin) handleCounterAPI(w http.ResponseWriter, r *http.Request)
w.Write(j) w.Write(j)
return return
} }
item, err := GetItem(p.DB, info.User, info.Thing) item, err := GetUserItem(p.DB, info.User, info.Thing)
if err != nil { if err != nil {
log.Error(). log.Error().
Err(err). Err(err).

View File

@ -43,7 +43,7 @@ func TestMkAlias(t *testing.T) {
assert.NotNil(t, c) assert.NotNil(t, c)
c.message(makeMessage("mkalias fuck mornings")) c.message(makeMessage("mkalias fuck mornings"))
c.message(makeMessage("fuck++")) c.message(makeMessage("fuck++"))
item, err := GetItem(mb.DB(), "tester", "mornings") item, err := GetUserItem(mb.DB(), "tester", "mornings")
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 1, item.Count) assert.Equal(t, 1, item.Count)
} }
@ -54,7 +54,7 @@ func TestRmAlias(t *testing.T) {
c.message(makeMessage("mkalias fuck mornings")) c.message(makeMessage("mkalias fuck mornings"))
c.message(makeMessage("rmalias fuck")) c.message(makeMessage("rmalias fuck"))
c.message(makeMessage("fuck++")) c.message(makeMessage("fuck++"))
item, err := GetItem(mb.DB(), "tester", "mornings") item, err := GetUserItem(mb.DB(), "tester", "mornings")
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 0, item.Count) assert.Equal(t, 0, item.Count)
} }
@ -64,7 +64,7 @@ func TestThreeSentencesExists(t *testing.T) {
assert.NotNil(t, c) assert.NotNil(t, c)
c.message(makeMessage(":beer:++")) c.message(makeMessage(":beer:++"))
c.message(makeMessage(":beer:. Earl Grey. Hot.")) c.message(makeMessage(":beer:. Earl Grey. Hot."))
item, err := GetItem(mb.DB(), "tester", ":beer:") item, err := GetUserItem(mb.DB(), "tester", ":beer:")
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 2, item.Count) assert.Equal(t, 2, item.Count)
} }
@ -72,9 +72,9 @@ func TestThreeSentencesExists(t *testing.T) {
func TestThreeSentencesNotExists(t *testing.T) { func TestThreeSentencesNotExists(t *testing.T) {
mb, c := setup(t) mb, c := setup(t)
assert.NotNil(t, c) assert.NotNil(t, c)
item, err := GetItem(mb.DB(), "tester", ":beer:") item, err := GetUserItem(mb.DB(), "tester", ":beer:")
c.message(makeMessage(":beer:. Earl Grey. Hot.")) c.message(makeMessage(":beer:. Earl Grey. Hot."))
item, err = GetItem(mb.DB(), "tester", ":beer:") item, err = GetUserItem(mb.DB(), "tester", ":beer:")
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 0, item.Count) assert.Equal(t, 0, item.Count)
} }
@ -84,7 +84,7 @@ func TestTeaEarlGreyHot(t *testing.T) {
assert.NotNil(t, c) assert.NotNil(t, c)
c.message(makeMessage("Tea. Earl Grey. Hot.")) c.message(makeMessage("Tea. Earl Grey. Hot."))
c.message(makeMessage("Tea. Earl Grey. Hot.")) c.message(makeMessage("Tea. Earl Grey. Hot."))
item, err := GetItem(mb.DB(), "tester", ":tea:") item, err := GetUserItem(mb.DB(), "tester", ":tea:")
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 2, item.Count) assert.Equal(t, 2, item.Count)
} }
@ -94,7 +94,7 @@ func TestTeaTwoPeriods(t *testing.T) {
assert.NotNil(t, c) assert.NotNil(t, c)
c.message(makeMessage("Tea. Earl Grey.")) c.message(makeMessage("Tea. Earl Grey."))
c.message(makeMessage("Tea. Earl Grey.")) c.message(makeMessage("Tea. Earl Grey."))
item, err := GetItem(mb.DB(), "tester", ":tea:") item, err := GetUserItem(mb.DB(), "tester", ":tea:")
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 0, item.Count) assert.Equal(t, 0, item.Count)
} }
@ -104,7 +104,7 @@ func TestTeaMultiplePeriods(t *testing.T) {
assert.NotNil(t, c) assert.NotNil(t, c)
c.message(makeMessage("Tea. Earl Grey. Spiked. Hot.")) c.message(makeMessage("Tea. Earl Grey. Spiked. Hot."))
c.message(makeMessage("Tea. Earl Grey. Spiked. Hot.")) c.message(makeMessage("Tea. Earl Grey. Spiked. Hot."))
item, err := GetItem(mb.DB(), "tester", ":tea:") item, err := GetUserItem(mb.DB(), "tester", ":tea:")
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 2, item.Count) assert.Equal(t, 2, item.Count)
} }
@ -115,7 +115,7 @@ func TestTeaGreenHot(t *testing.T) {
c.message(makeMessage("Tea. Green. Hot.")) c.message(makeMessage("Tea. Green. Hot."))
c.message(makeMessage("Tea. Green. Hot")) c.message(makeMessage("Tea. Green. Hot"))
c.message(makeMessage("Tea. Green. Iced.")) c.message(makeMessage("Tea. Green. Iced."))
item, err := GetItem(mb.DB(), "tester", ":tea:") item, err := GetUserItem(mb.DB(), "tester", ":tea:")
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 3, item.Count) assert.Equal(t, 3, item.Count)
} }
@ -125,7 +125,7 @@ func TestTeaUnrelated(t *testing.T) {
assert.NotNil(t, c) assert.NotNil(t, c)
c.message(makeMessage("Tea.")) c.message(makeMessage("Tea."))
c.message(makeMessage("Tea. It's great.")) c.message(makeMessage("Tea. It's great."))
item, err := GetItem(mb.DB(), "tester", ":tea:") item, err := GetUserItem(mb.DB(), "tester", ":tea:")
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 0, item.Count) assert.Equal(t, 0, item.Count)
} }
@ -134,7 +134,7 @@ func TestTeaSkieselQuote(t *testing.T) {
mb, c := setup(t) mb, c := setup(t)
assert.NotNil(t, c) assert.NotNil(t, c)
c.message(makeMessage("blah, this is a whole page of explanation where \"we did local search and used a tabu list\" would have sufficed")) c.message(makeMessage("blah, this is a whole page of explanation where \"we did local search and used a tabu list\" would have sufficed"))
item, err := GetItem(mb.DB(), "tester", ":tea:") item, err := GetUserItem(mb.DB(), "tester", ":tea:")
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 0, item.Count) assert.Equal(t, 0, item.Count)
} }
@ -142,7 +142,7 @@ func TestTeaUnicodeJapanese(t *testing.T) {
mb, c := setup(t) mb, c := setup(t)
assert.NotNil(t, c) assert.NotNil(t, c)
c.message(makeMessage("Tea. おちや. Hot.")) c.message(makeMessage("Tea. おちや. Hot."))
item, err := GetItem(mb.DB(), "tester", ":tea:") item, err := GetUserItem(mb.DB(), "tester", ":tea:")
assert.Nil(t, err) assert.Nil(t, err)
assert.Equal(t, 1, item.Count) assert.Equal(t, 1, item.Count)
} }

View File

@ -3,6 +3,7 @@ package goals
import ( import (
"fmt" "fmt"
"regexp" "regexp"
"sort"
"strconv" "strconv"
"strings" "strings"
@ -64,97 +65,135 @@ func (p *GoalsPlugin) message(conn bot.Connector, kind bot.Kind, message msg.Mes
if registerSelf.MatchString(body) { if registerSelf.MatchString(body) {
c := parseCmd(registerSelf, body) c := parseCmd(registerSelf, body)
amount, _ := strconv.Atoi(c["amount"]) amount, _ := strconv.Atoi(c["amount"])
return p.register(conn, ch, c["type"], c["what"], who, amount) p.register(conn, ch, c["type"], c["what"], who, amount)
} } else if registerOther.MatchString(body) {
if registerOther.MatchString(body) {
c := parseCmd(registerSelf, body) c := parseCmd(registerSelf, body)
amount, _ := strconv.Atoi(c["amount"]) amount, _ := strconv.Atoi(c["amount"])
return p.register(conn, ch, c["type"], c["what"], c["who"], amount) p.register(conn, ch, c["type"], c["what"], c["who"], amount)
} } else if deRegisterSelf.MatchString(body) {
if deRegisterSelf.MatchString(body) {
c := parseCmd(deRegisterSelf, body) c := parseCmd(deRegisterSelf, body)
return p.deregister(conn, ch, c["type"], c["what"], who) p.deregister(conn, ch, c["type"], c["what"], who)
} } else if deRegisterOther.MatchString(body) {
if deRegisterOther.MatchString(body) {
c := parseCmd(deRegisterOther, body) c := parseCmd(deRegisterOther, body)
return p.deregister(conn, ch, c["type"], c["what"], c["who"]) p.deregister(conn, ch, c["type"], c["what"], c["who"])
} } else if checkSelf.MatchString(body) {
if checkSelf.MatchString(body) {
c := parseCmd(checkSelf, body) c := parseCmd(checkSelf, body)
return p.check(conn, ch, c["type"], c["what"], who) p.check(conn, ch, c["type"], c["what"], who)
} } else if checkOther.MatchString(body) {
if checkOther.MatchString(body) {
c := parseCmd(checkOther, body) c := parseCmd(checkOther, body)
return p.check(conn, ch, c["type"], c["what"], c["who"]) p.check(conn, ch, c["type"], c["what"], c["who"])
} } else {
return false return false
}
return true
} }
func (p *GoalsPlugin) register(c bot.Connector, ch, kind, what, who string, howMuch int) bool { func (p *GoalsPlugin) register(c bot.Connector, ch, kind, what, who string, howMuch int) {
p.b.Send(c, bot.Message, ch, fmt.Sprintf("registering %s %s for %s in amount %d", kind, what, who, howMuch))
if kind == "goal" && howMuch == 0 { if kind == "goal" && howMuch == 0 {
p.b.Send(c, bot.Message, ch, p.b.Send(c, bot.Message, ch,
fmt.Sprintf("%s, you need to have a goal amount if you want to have a goal for %s.", who, what)) fmt.Sprintf("%s, you need to have a goal amount if you want to have a goal for %s.", who, what))
return true return
} }
g := p.newGoal(kind, who, what, howMuch) g := p.newGoal(kind, who, what, howMuch)
err := g.Save() err := g.Save()
if err != nil { if err != nil {
log.Error().Err(err).Msgf("could not create goal") log.Error().Err(err).Msgf("could not create goal")
p.b.Send(c, bot.Message, ch, "I couldn't create that goal for some reason.") p.b.Send(c, bot.Message, ch, "I couldn't create that goal for some reason.")
return true return
} }
p.b.Send(c, bot.Message, ch, fmt.Sprintf("%s created", kind)) p.b.Send(c, bot.Message, ch, fmt.Sprintf("%s created", kind))
return true
} }
func (p *GoalsPlugin) deregister(c bot.Connector, ch, kind, what, who string) bool { func (p *GoalsPlugin) deregister(c bot.Connector, ch, kind, what, who string) {
p.b.Send(c, bot.Message, ch, fmt.Sprintf("deregistering %s for %s", what, who)) g, err := p.getGoalKind(kind, who, what)
g, err := p.getGoal(kind, who, what)
if err != nil { if err != nil {
log.Error().Err(err).Msgf("could not find goal to delete") log.Error().Err(err).Msgf("could not find goal to delete")
p.b.Send(c, bot.Message, ch, "I couldn't find that item to deregister.") p.b.Send(c, bot.Message, ch, "I couldn't find that item to deregister.")
return true return
} }
err = g.Delete() err = g.Delete()
if err != nil { if err != nil {
log.Error().Err(err).Msgf("could not delete goal") log.Error().Err(err).Msgf("could not delete goal")
p.b.Send(c, bot.Message, ch, "I couldn't deregister that.") p.b.Send(c, bot.Message, ch, "I couldn't deregister that.")
return true return
} }
p.b.Send(c, bot.Message, ch, fmt.Sprintf("%s %s deregistered", kind, what)) p.b.Send(c, bot.Message, ch, fmt.Sprintf("%s %s deregistered", kind, what))
return true
} }
func (p *GoalsPlugin) check(c bot.Connector, ch, kind, what, who string) bool { func (p *GoalsPlugin) check(c bot.Connector, ch, kind, what, who string) {
return p.checkGoal(c, ch, what, who) if kind == "goal" {
p.checkGoal(c, ch, what, who)
return
}
p.checkCompetition(c, ch, what, who)
} }
func (p *GoalsPlugin) checkCompetition(c bot.Connector, ch, what, who string) bool { func (p *GoalsPlugin) checkCompetition(c bot.Connector, ch, what, who string) {
return true items, err := counter.GetItem(p.db, what)
} if err != nil || len(items) == 0 {
p.b.Send(c, bot.Message, ch, fmt.Sprintf("I couldn't find any %s", what))
func (p *GoalsPlugin) checkGoal(c bot.Connector, ch, what, who string) bool { return
kind := "goal"
p.b.Send(c, bot.Message, ch, fmt.Sprintf("checking %s for %s", what, who))
g, err := p.getGoal(kind, who, what)
if err != nil {
p.b.Send(c, bot.Message, ch, fmt.Sprintf("I couldn't find %s %s", kind, what))
} }
item, err := counter.GetItem(p.db, who, what) sort.Slice(items, func(i, j int) bool {
if items[i].Count == items[j].Count && who == items[i].Nick {
return true
}
if items[i].Count > items[j].Count {
return true
}
return false
})
if items[0].Nick == who && len(items) > 1 && items[1].Count == items[0].Count {
p.b.Send(c, bot.Message, ch,
fmt.Sprintf("Congratulations! You're in the lead for %s with %d, but you're tied with %s",
what, items[0].Count, items[1].Nick))
return
}
if items[0].Nick == who {
p.b.Send(c, bot.Message, ch, fmt.Sprintf("Congratulations! You're in the lead for %s with %d.",
what, items[0].Count))
return
}
count := 0
for _, i := range items {
if i.Nick == who {
count = i.Count
}
}
p.b.Send(c, bot.Message, ch, fmt.Sprintf("%s is in the lead for %s with %d. You have %d to catch up.",
items[0].Nick, what, items[0].Count, items[0].Count-count))
}
func (p *GoalsPlugin) checkGoal(c bot.Connector, ch, what, who string) {
g, err := p.getGoalKind("goal", who, what)
if err != nil {
p.b.Send(c, bot.Message, ch, fmt.Sprintf("I couldn't find %s", what))
}
item, err := counter.GetUserItem(p.db, who, what)
if err != nil { if err != nil {
p.b.Send(c, bot.Message, ch, fmt.Sprintf("I couldn't find any %s", what)) p.b.Send(c, bot.Message, ch, fmt.Sprintf("I couldn't find any %s", what))
return true return
} }
perc := float64(item.Count) / float64(g.Amount) * 100.0 perc := float64(item.Count) / float64(g.Amount) * 100.0
if perc >= 100 {
p.deregister(c, ch, g.Kind, g.What, g.Who)
m := fmt.Sprintf("You made it! You have %.2f%% of %s and now it's done.", perc, what)
p.b.Send(c, bot.Message, ch, m)
} else {
m := fmt.Sprintf("You have %d out of %d for %s. You're %.2f%% of the way there!", m := fmt.Sprintf("You have %d out of %d for %s. You're %.2f%% of the way there!",
item.Count, g.Amount, what, perc) item.Count, g.Amount, what, perc)
p.b.Send(c, bot.Message, ch, m) p.b.Send(c, bot.Message, ch, m)
}
return true return
} }
func (p *GoalsPlugin) help(c bot.Connector, kind bot.Kind, message msg.Message, args ...interface{}) bool { func (p *GoalsPlugin) help(c bot.Connector, kind bot.Kind, message msg.Message, args ...interface{}) bool {
@ -205,7 +244,20 @@ func (p *GoalsPlugin) newGoal(kind, who, what string, amount int) goal {
} }
} }
func (p *GoalsPlugin) getGoal(kind, who, what string) (*goal, error) { func (p *GoalsPlugin) getGoal(who, what string) ([]*goal, error) {
gs := []*goal{}
err := p.db.Select(&gs, `select * from goals where who = ? and what = ?`,
who, what)
if err != nil {
return nil, err
}
for _, g := range gs {
g.gp = p
}
return gs, nil
}
func (p *GoalsPlugin) getGoalKind(kind, who, what string) (*goal, error) {
g := &goal{gp: p} g := &goal{gp: p}
err := p.db.Get(g, `select * from goals where kind = ? and who = ? and what = ?`, err := p.db.Get(g, `select * from goals where kind = ? and who = ? and what = ?`,
kind, who, what) kind, who, what)
@ -238,14 +290,20 @@ func (g goal) Delete() error {
func (p *GoalsPlugin) update(u counter.Update) { func (p *GoalsPlugin) update(u counter.Update) {
log.Debug().Msgf("entered update for %#v", u) log.Debug().Msgf("entered update for %#v", u)
_, err := p.getGoal("goal", u.Who, u.What) gs, err := p.getGoal(u.Who, u.What)
if err != nil { if err != nil {
log.Error().Err(err).Msgf("could not get goal for %#v", u) log.Error().Err(err).Msgf("could not get goal for %#v", u)
return return
} }
chs := p.cfg.GetArray("channels", []string{}) chs := p.cfg.GetArray("channels", []string{})
c := p.b.DefaultConnector() c := p.b.DefaultConnector()
for _, g := range gs {
for _, ch := range chs { for _, ch := range chs {
if g.Kind == "goal" {
p.checkGoal(c, ch, u.What, u.Who) p.checkGoal(c, ch, u.What, u.Who)
} else {
p.checkCompetition(c, ch, u.What, u.Who)
}
}
} }
} }