mirror of https://github.com/velour/catbase.git
wip
This commit is contained in:
parent
fafbd2ce64
commit
748e39c290
|
@ -10,7 +10,7 @@ jobs:
|
||||||
- name: Set up Go 1.16
|
- name: Set up Go 1.16
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v2
|
||||||
with:
|
with:
|
||||||
go-version: '^1.18'
|
go-version: '^1.17'
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Check out code into the Go module directory
|
- name: Check out code into the Go module directory
|
||||||
|
|
|
@ -308,18 +308,18 @@ func (b *bot) SetQuiet(status bool) {
|
||||||
b.quiet = status
|
b.quiet = status
|
||||||
}
|
}
|
||||||
|
|
||||||
type blacklistItem struct {
|
type BlacklistItem struct {
|
||||||
Channel string
|
Channel string
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
type whitelistItem struct {
|
type WhitelistItem struct {
|
||||||
Name string
|
Name string
|
||||||
}
|
}
|
||||||
|
|
||||||
// RefreshPluginBlacklist loads data for which plugins are disabled for particular channels
|
// RefreshPluginBlacklist loads data for which plugins are disabled for particular channels
|
||||||
func (b *bot) RefreshPluginBlacklist() error {
|
func (b *bot) RefreshPluginBlacklist() error {
|
||||||
blacklistItems := []blacklistItem{}
|
blacklistItems := []BlacklistItem{}
|
||||||
if err := b.Store().Find(&blacklistItems, &bh.Query{}); err != nil {
|
if err := b.Store().Find(&blacklistItems, &bh.Query{}); err != nil {
|
||||||
return fmt.Errorf("%w", err)
|
return fmt.Errorf("%w", err)
|
||||||
}
|
}
|
||||||
|
@ -333,7 +333,7 @@ func (b *bot) RefreshPluginBlacklist() error {
|
||||||
|
|
||||||
// RefreshPluginWhitelist loads data for which plugins are enabled
|
// RefreshPluginWhitelist loads data for which plugins are enabled
|
||||||
func (b *bot) RefreshPluginWhitelist() error {
|
func (b *bot) RefreshPluginWhitelist() error {
|
||||||
whitelistItems := []whitelistItem{
|
whitelistItems := []WhitelistItem{
|
||||||
{Name: "admin"}, // we must always ensure admin is on!
|
{Name: "admin"}, // we must always ensure admin is on!
|
||||||
}
|
}
|
||||||
if err := b.Store().Find(&whitelistItems, &bh.Query{}); err != nil {
|
if err := b.Store().Find(&whitelistItems, &bh.Query{}); err != nil {
|
||||||
|
|
22
bot/mock.go
22
bot/mock.go
|
@ -4,12 +4,14 @@ package bot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
bh "github.com/timshannon/bolthold"
|
||||||
|
"io/ioutil"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
"github.com/stretchr/testify/mock"
|
"github.com/stretchr/testify/mock"
|
||||||
"github.com/velour/catbase/bot/msg"
|
"github.com/velour/catbase/bot/msg"
|
||||||
|
@ -19,17 +21,19 @@ import (
|
||||||
|
|
||||||
type MockBot struct {
|
type MockBot struct {
|
||||||
mock.Mock
|
mock.Mock
|
||||||
db *sqlx.DB
|
store *bh.Store
|
||||||
|
|
||||||
Cfg *config.Config
|
Cfg *config.Config
|
||||||
|
|
||||||
Messages []string
|
Messages []string
|
||||||
Actions []string
|
Actions []string
|
||||||
Reactions []string
|
Reactions []string
|
||||||
|
|
||||||
|
storeFile *os.File
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mb *MockBot) Config() *config.Config { return mb.Cfg }
|
func (mb *MockBot) Config() *config.Config { return mb.Cfg }
|
||||||
func (mb *MockBot) DB() *sqlx.DB { return mb.Cfg.DB() }
|
func (mb *MockBot) Store() *bh.Store { return mb.Cfg.Store() }
|
||||||
func (mb *MockBot) Who(string) []user.User { return []user.User{} }
|
func (mb *MockBot) Who(string) []user.User { return []user.User{} }
|
||||||
func (mb *MockBot) WhoAmI() string { return "tester" }
|
func (mb *MockBot) WhoAmI() string { return "tester" }
|
||||||
func (mb *MockBot) DefaultConnector() Connector { return nil }
|
func (mb *MockBot) DefaultConnector() Connector { return nil }
|
||||||
|
@ -107,11 +111,17 @@ func (mb *MockBot) GetEmojiList() map[string]string { return make
|
||||||
func (mb *MockBot) RegisterFilter(s string, f func(string) string) {}
|
func (mb *MockBot) RegisterFilter(s string, f func(string) string) {}
|
||||||
|
|
||||||
func NewMockBot() *MockBot {
|
func NewMockBot() *MockBot {
|
||||||
cfg := config.ReadConfig("file::memory:?mode=memory&cache=shared")
|
storeFile, err := ioutil.TempFile(os.TempDir(), "prefix-")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
cfg := config.ReadConfig("file::memory:?mode=memory&cache=shared", storeFile.Name())
|
||||||
b := MockBot{
|
b := MockBot{
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
Messages: make([]string, 0),
|
Messages: make([]string, 0),
|
||||||
Actions: make([]string, 0),
|
Actions: make([]string, 0),
|
||||||
|
storeFile: storeFile,
|
||||||
|
store: cfg.Store(),
|
||||||
}
|
}
|
||||||
// If any plugin registered a route, we need to reset those before any new test
|
// If any plugin registered a route, we need to reset those before any new test
|
||||||
http.DefaultServeMux = new(http.ServeMux)
|
http.DefaultServeMux = new(http.ServeMux)
|
||||||
|
@ -127,3 +137,7 @@ func (mb *MockBot) URLFormat(title, url string) string { return title
|
||||||
func (mb *MockBot) CheckPassword(secret, password string) bool { return true }
|
func (mb *MockBot) CheckPassword(secret, password string) bool { return true }
|
||||||
func (mb *MockBot) ListenAndServe() {}
|
func (mb *MockBot) ListenAndServe() {}
|
||||||
func (mb *MockBot) PubToASub(subject string, payload interface{}) {}
|
func (mb *MockBot) PubToASub(subject string, payload interface{}) {}
|
||||||
|
func (mb *MockBot) TearDown() error {
|
||||||
|
mb.store.Close()
|
||||||
|
return os.Remove(mb.storeFile.Name())
|
||||||
|
}
|
||||||
|
|
|
@ -31,9 +31,9 @@ type Config struct {
|
||||||
// Value is a config value that is loaded permanently and not ever displayed
|
// Value is a config value that is loaded permanently and not ever displayed
|
||||||
type Value struct {
|
type Value struct {
|
||||||
// Key is the key field of the table
|
// Key is the key field of the table
|
||||||
Key string `db:"key"`
|
Key string `db:"key" json:"key"`
|
||||||
// Value represents the secret that must not be shared
|
// Value represents the secret that must not be shared
|
||||||
Value string `db:"value"`
|
Value string `db:"value" json:"value"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// Secret is a separate type (for storage differentiation)
|
// Secret is a separate type (for storage differentiation)
|
||||||
|
@ -159,7 +159,7 @@ func (c *Config) Set(key, value string) error {
|
||||||
key = strings.ToLower(key)
|
key = strings.ToLower(key)
|
||||||
value = strings.Trim(value, "`")
|
value = strings.Trim(value, "`")
|
||||||
|
|
||||||
err := c.store.Update(key, Value{key, value})
|
err := c.store.Upsert(key, Value{key, value})
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,12 +215,12 @@ func (c *Config) SetArray(key string, values []string) error {
|
||||||
//}
|
//}
|
||||||
|
|
||||||
// Readconfig loads the config data out of a JSON file located in cfile
|
// Readconfig loads the config data out of a JSON file located in cfile
|
||||||
func ReadConfig(dbpath string) *Config {
|
func ReadConfig(dbpath, storepath string) *Config {
|
||||||
if dbpath == "" {
|
if dbpath == "" {
|
||||||
dbpath = "catbase.db"
|
dbpath = "catbase.db"
|
||||||
}
|
}
|
||||||
|
|
||||||
store, err := bh.Open(strings.ReplaceAll(dbpath, ".db", ".store"), 0666, nil)
|
store, err := bh.Open(storepath, 0666, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal().Err(err).Msgf("could not open bolthold")
|
log.Fatal().Err(err).Msgf("could not open bolthold")
|
||||||
}
|
}
|
||||||
|
|
6
main.go
6
main.go
|
@ -7,6 +7,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"os"
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/velour/catbase/bot/msg"
|
"github.com/velour/catbase/bot/msg"
|
||||||
|
@ -46,7 +47,6 @@ import (
|
||||||
"github.com/velour/catbase/plugins/fact"
|
"github.com/velour/catbase/plugins/fact"
|
||||||
"github.com/velour/catbase/plugins/first"
|
"github.com/velour/catbase/plugins/first"
|
||||||
"github.com/velour/catbase/plugins/git"
|
"github.com/velour/catbase/plugins/git"
|
||||||
"github.com/velour/catbase/plugins/impossible"
|
|
||||||
"github.com/velour/catbase/plugins/inventory"
|
"github.com/velour/catbase/plugins/inventory"
|
||||||
"github.com/velour/catbase/plugins/leftpad"
|
"github.com/velour/catbase/plugins/leftpad"
|
||||||
"github.com/velour/catbase/plugins/nerdepedia"
|
"github.com/velour/catbase/plugins/nerdepedia"
|
||||||
|
@ -92,7 +92,7 @@ func main() {
|
||||||
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||||
}
|
}
|
||||||
|
|
||||||
c := config.ReadConfig(*dbpath)
|
c := config.ReadConfig(*dbpath, strings.ReplaceAll(*dbpath, ".db", ".store"))
|
||||||
|
|
||||||
if *key != "" && *val != "" {
|
if *key != "" && *val != "" {
|
||||||
c.Set(*key, *val)
|
c.Set(*key, *val)
|
||||||
|
@ -159,7 +159,7 @@ func main() {
|
||||||
b.AddPlugin(newsbid.New(b))
|
b.AddPlugin(newsbid.New(b))
|
||||||
b.AddPlugin(twitter.New(b))
|
b.AddPlugin(twitter.New(b))
|
||||||
b.AddPlugin(git.New(b))
|
b.AddPlugin(git.New(b))
|
||||||
b.AddPlugin(impossible.New(b))
|
//b.AddPlugin(impossible.New(b))
|
||||||
b.AddPlugin(cli.New(b))
|
b.AddPlugin(cli.New(b))
|
||||||
b.AddPlugin(aoc.New(b))
|
b.AddPlugin(aoc.New(b))
|
||||||
b.AddPlugin(meme.New(b))
|
b.AddPlugin(meme.New(b))
|
||||||
|
|
|
@ -349,49 +349,33 @@ func (p *AdminPlugin) help(conn bot.Connector, kind bot.Kind, m msg.Message, arg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *AdminPlugin) addWhitelist(plugin string) error {
|
func (p *AdminPlugin) addWhitelist(plugin string) error {
|
||||||
return p.modList(`insert or replace into pluginWhitelist values (?)`, "", plugin)
|
defer p.bot.RefreshPluginWhitelist()
|
||||||
|
return p.store.Upsert(plugin, bot.WhitelistItem{plugin})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *AdminPlugin) rmWhitelist(plugin string) error {
|
func (p *AdminPlugin) rmWhitelist(plugin string) error {
|
||||||
if plugin == "admin" {
|
if plugin == "admin" {
|
||||||
return fmt.Errorf("you cannot disable the admin plugin")
|
return fmt.Errorf("you cannot disable the admin plugin")
|
||||||
}
|
}
|
||||||
return p.modList(`delete from pluginWhitelist where name=?`, "", plugin)
|
defer p.bot.RefreshPluginWhitelist()
|
||||||
|
return p.store.Delete(plugin, bot.WhitelistItem{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *AdminPlugin) addBlacklist(channel, plugin string) error {
|
func (p *AdminPlugin) addBlacklist(channel, plugin string) error {
|
||||||
if plugin == "admin" {
|
if plugin == "admin" {
|
||||||
return fmt.Errorf("you cannot disable the admin plugin")
|
return fmt.Errorf("you cannot disable the admin plugin")
|
||||||
}
|
}
|
||||||
return p.modList(`insert or replace into pluginBlacklist values (?, ?)`, channel, plugin)
|
defer p.bot.RefreshPluginBlacklist()
|
||||||
|
return p.store.Upsert(channel+plugin, bot.BlacklistItem{
|
||||||
|
Channel: channel,
|
||||||
|
Name: plugin,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *AdminPlugin) rmBlacklist(channel, plugin string) error {
|
func (p *AdminPlugin) rmBlacklist(channel, plugin string) error {
|
||||||
return p.modList(`delete from pluginBlacklist where channel=? and name=?`, channel, plugin)
|
defer p.bot.RefreshPluginBlacklist()
|
||||||
}
|
return p.store.Delete(channel+plugin, bot.BlacklistItem{
|
||||||
|
Channel: channel,
|
||||||
func (p *AdminPlugin) modList(query, channel, plugin string) error {
|
Name: plugin,
|
||||||
if channel == "" && plugin != "" {
|
})
|
||||||
channel = plugin // hack
|
|
||||||
}
|
|
||||||
plugins := p.bot.GetPluginNames()
|
|
||||||
for _, pp := range plugins {
|
|
||||||
if pp == plugin {
|
|
||||||
// todo: yikes
|
|
||||||
//if _, err := p.db.Exec(query, channel, plugin); err != nil {
|
|
||||||
// return fmt.Errorf("%w", err)
|
|
||||||
//}
|
|
||||||
err := p.bot.RefreshPluginWhitelist()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%w", err)
|
|
||||||
}
|
|
||||||
err = p.bot.RefreshPluginBlacklist()
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("%w", err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
err := fmt.Errorf("unknown plugin named '%s'", plugin)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,7 @@ type BabblerPlugin struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Babbler struct {
|
type Babbler struct {
|
||||||
BabblerId int64 `db:"id" boltholdid:"BabblerId"`
|
BabblerID int64 `db:"id" boltholdid:"BabblerID"`
|
||||||
Name string `db:"babbler"`
|
Name string `db:"babbler"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,8 +44,8 @@ func getBabbler(store *bh.Store, id int64) (*Babbler, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type BabblerWord struct {
|
type BabblerWord struct {
|
||||||
WordId int64 `db:"id" boltholdid:"WordId"`
|
WordID int64 `db:"ID" boltholdid:"WordID"`
|
||||||
Word string `db:"word"`
|
Word string `db:"Word"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func getWord(store *bh.Store, id int64) (*BabblerWord, error) {
|
func getWord(store *bh.Store, id int64) (*BabblerWord, error) {
|
||||||
|
@ -55,11 +55,11 @@ func getWord(store *bh.Store, id int64) (*BabblerWord, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type BabblerNode struct {
|
type BabblerNode struct {
|
||||||
NodeId int64 `db:"id" boltholdid:"NodeId"`
|
NodeId int64 `db:"ID" boltholdid:"NodeId"`
|
||||||
BabblerId int64 `db:"babblerId"`
|
BabblerID int64 `db:"BabblerID"`
|
||||||
WordId int64 `db:"wordId"`
|
WordID int64 `db:"WordID"`
|
||||||
Root int64 `db:"root"`
|
Root int64 `db:"Root"`
|
||||||
RootFrequency int64 `db:"rootFrequency"`
|
RootFrequency int64 `db:"RootFrequency"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func getNode(store *bh.Store, id int64) (*BabblerNode, error) {
|
func getNode(store *bh.Store, id int64) (*BabblerNode, error) {
|
||||||
|
@ -69,10 +69,10 @@ func getNode(store *bh.Store, id int64) (*BabblerNode, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
type BabblerArc struct {
|
type BabblerArc struct {
|
||||||
ArcId int64 `db:"id" boltholdid:"ArcId"`
|
ArcId int64 `db:"ID" boltholdid:"ArcId"`
|
||||||
FromNodeId int64 `db:"fromNodeId"`
|
FromNodeId int64 `db:"FromNodeId"`
|
||||||
ToNodeId int64 `db:"toNodeId"`
|
ToNodeId int64 `db:"ToNodeId"`
|
||||||
Frequency int64 `db:"frequency"`
|
Frequency int64 `db:"Frequency"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func getArc(store *bh.Store, id int64) (*BabblerArc, error) {
|
func getArc(store *bh.Store, id int64) (*BabblerArc, error) {
|
||||||
|
@ -200,7 +200,7 @@ func (p *BabblerPlugin) makeBabbler(name string) (*Babbler, error) {
|
||||||
|
|
||||||
func (p *BabblerPlugin) getBabbler(name string) (*Babbler, error) {
|
func (p *BabblerPlugin) getBabbler(name string) (*Babbler, error) {
|
||||||
var bblr Babbler
|
var bblr Babbler
|
||||||
err := p.store.FindOne(&bblr, bh.Where("babbler").Eq(name))
|
err := p.store.FindOne(&bblr, bh.Where("Babbler").Eq(name))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == sql.ErrNoRows {
|
if err == sql.ErrNoRows {
|
||||||
log.Error().Msg("failed to find babbler")
|
log.Error().Msg("failed to find babbler")
|
||||||
|
@ -233,7 +233,7 @@ func (p *BabblerPlugin) getOrCreateBabbler(name string) (*Babbler, error) {
|
||||||
|
|
||||||
func (p *BabblerPlugin) getWord(word string) (*BabblerWord, error) {
|
func (p *BabblerPlugin) getWord(word string) (*BabblerWord, error) {
|
||||||
var w BabblerWord
|
var w BabblerWord
|
||||||
err := p.store.FindOne(&w, bh.Where("word").Eq(word).Limit(1))
|
err := p.store.FindOne(&w, bh.Where("Word").Eq(word).Limit(1))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == bh.ErrNotFound {
|
if err == bh.ErrNotFound {
|
||||||
return nil, NEVER_SAID
|
return nil, NEVER_SAID
|
||||||
|
@ -271,7 +271,7 @@ func (p *BabblerPlugin) getBabblerNode(babbler *Babbler, word string) (*BabblerN
|
||||||
}
|
}
|
||||||
|
|
||||||
var node BabblerNode
|
var node BabblerNode
|
||||||
err = p.store.FindOne(&node, bh.Where("babblerId").Eq(babbler.BabblerId).And("wordId").Eq(w.WordId))
|
err = p.store.FindOne(&node, bh.Where("BabblerID").Eq(babbler.BabblerID).And("WordID").Eq(w.WordID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == bh.ErrNotFound {
|
if err == bh.ErrNotFound {
|
||||||
return nil, NEVER_SAID
|
return nil, NEVER_SAID
|
||||||
|
@ -289,7 +289,7 @@ func (p *BabblerPlugin) createBabblerNode(babbler *Babbler, word string) (*Babbl
|
||||||
}
|
}
|
||||||
|
|
||||||
bn := &BabblerNode{
|
bn := &BabblerNode{
|
||||||
WordId: w.WordId,
|
WordID: w.WordID,
|
||||||
Root: 0,
|
Root: 0,
|
||||||
RootFrequency: 0,
|
RootFrequency: 0,
|
||||||
}
|
}
|
||||||
|
@ -317,7 +317,7 @@ func (p *BabblerPlugin) incrementRootWordFrequency(babbler *Babbler, word string
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
err = p.store.UpdateMatching(BabblerNode{}, bh.Where("id").Eq(node.NodeId), func(record interface{}) error {
|
err = p.store.UpdateMatching(BabblerNode{}, bh.Where("ID").Eq(node.NodeId), func(record interface{}) error {
|
||||||
r := record.(BabblerNode)
|
r := record.(BabblerNode)
|
||||||
r.RootFrequency += 1
|
r.RootFrequency += 1
|
||||||
r.Root = 1
|
r.Root = 1
|
||||||
|
@ -333,7 +333,7 @@ func (p *BabblerPlugin) incrementRootWordFrequency(babbler *Babbler, word string
|
||||||
|
|
||||||
func (p *BabblerPlugin) getBabblerArc(fromNode, toNode *BabblerNode) (*BabblerArc, error) {
|
func (p *BabblerPlugin) getBabblerArc(fromNode, toNode *BabblerNode) (*BabblerArc, error) {
|
||||||
var arc BabblerArc
|
var arc BabblerArc
|
||||||
err := p.store.FindOne(&arc, bh.Where("fromNodeId").Eq(fromNode.NodeId).And("toNodeId").Eq(toNode.NodeId))
|
err := p.store.FindOne(&arc, bh.Where("FromNodeID").Eq(fromNode.NodeId).And("ToNodeID").Eq(toNode.NodeId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == bh.ErrNotFound {
|
if err == bh.ErrNotFound {
|
||||||
return nil, NEVER_SAID
|
return nil, NEVER_SAID
|
||||||
|
@ -346,7 +346,7 @@ func (p *BabblerPlugin) getBabblerArc(fromNode, toNode *BabblerNode) (*BabblerAr
|
||||||
func (p *BabblerPlugin) incrementWordArc(fromNode, toNode *BabblerNode) (*BabblerArc, error) {
|
func (p *BabblerPlugin) incrementWordArc(fromNode, toNode *BabblerNode) (*BabblerArc, error) {
|
||||||
affectedRows := 0
|
affectedRows := 0
|
||||||
err := p.store.UpdateMatching(BabblerArc{},
|
err := p.store.UpdateMatching(BabblerArc{},
|
||||||
bh.Where("fromNodeId").Eq(fromNode.NodeId).And("toNodeId").Eq(toNode.NodeId),
|
bh.Where("FromNodeId").Eq(fromNode.NodeId).And("ToNodeId").Eq(toNode.NodeId),
|
||||||
func(record interface{}) error {
|
func(record interface{}) error {
|
||||||
affectedRows++
|
affectedRows++
|
||||||
r := record.(BabblerArc)
|
r := record.(BabblerArc)
|
||||||
|
@ -414,7 +414,7 @@ func (p *BabblerPlugin) addToMarkovChain(babbler *Babbler, phrase string) error
|
||||||
|
|
||||||
func (p *BabblerPlugin) getWeightedRootNode(babbler *Babbler) (*BabblerNode, *BabblerWord, error) {
|
func (p *BabblerPlugin) getWeightedRootNode(babbler *Babbler) (*BabblerNode, *BabblerWord, error) {
|
||||||
rootNodes := []*BabblerNode{}
|
rootNodes := []*BabblerNode{}
|
||||||
err := p.store.Find(&rootNodes, bh.Where("babblerId").Eq(babbler.BabblerId).And("root").Eq(1))
|
err := p.store.Find(&rootNodes, bh.Where("BabblerID").Eq(babbler.BabblerID).And("Root").Eq(1))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -435,7 +435,7 @@ func (p *BabblerPlugin) getWeightedRootNode(babbler *Babbler) (*BabblerNode, *Ba
|
||||||
for _, node := range rootNodes {
|
for _, node := range rootNodes {
|
||||||
total += node.RootFrequency
|
total += node.RootFrequency
|
||||||
if total >= which {
|
if total >= which {
|
||||||
w, err := getWord(p.store, node.WordId)
|
w, err := getWord(p.store, node.WordID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -450,7 +450,7 @@ func (p *BabblerPlugin) getWeightedRootNode(babbler *Babbler) (*BabblerNode, *Ba
|
||||||
|
|
||||||
func (p *BabblerPlugin) getWeightedNextWord(fromNode *BabblerNode) (*BabblerNode, *BabblerWord, error) {
|
func (p *BabblerPlugin) getWeightedNextWord(fromNode *BabblerNode) (*BabblerNode, *BabblerWord, error) {
|
||||||
arcs := []BabblerArc{}
|
arcs := []BabblerArc{}
|
||||||
err := p.store.Find(&arcs, bh.Where("fromNodeId").Eq(fromNode.NodeId))
|
err := p.store.Find(&arcs, bh.Where("FromNodeID").Eq(fromNode.NodeId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -477,7 +477,7 @@ func (p *BabblerPlugin) getWeightedNextWord(fromNode *BabblerNode) (*BabblerNode
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
w, err := getWord(p.store, node.WordId)
|
w, err := getWord(p.store, node.WordID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
return nil, nil, err
|
return nil, nil, err
|
||||||
|
@ -492,7 +492,7 @@ func (p *BabblerPlugin) getWeightedNextWord(fromNode *BabblerNode) (*BabblerNode
|
||||||
|
|
||||||
func (p *BabblerPlugin) getWeightedPreviousWord(toNode *BabblerNode) (*BabblerNode, *BabblerWord, bool, error) {
|
func (p *BabblerPlugin) getWeightedPreviousWord(toNode *BabblerNode) (*BabblerNode, *BabblerWord, bool, error) {
|
||||||
arcs := []*BabblerArc{}
|
arcs := []*BabblerArc{}
|
||||||
err := p.store.Find(&arcs, bh.Where("toNodeId").Eq(toNode.NodeId))
|
err := p.store.Find(&arcs, bh.Where("ToNodeID").Eq(toNode.NodeId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
return nil, nil, false, err
|
return nil, nil, false, err
|
||||||
|
@ -525,7 +525,7 @@ func (p *BabblerPlugin) getWeightedPreviousWord(toNode *BabblerNode) (*BabblerNo
|
||||||
return nil, nil, false, err
|
return nil, nil, false, err
|
||||||
}
|
}
|
||||||
|
|
||||||
w, err := getWord(p.store, node.WordId)
|
w, err := getWord(p.store, node.WordID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
return nil, nil, false, err
|
return nil, nil, false, err
|
||||||
|
@ -625,7 +625,7 @@ func (p *BabblerPlugin) mergeBabblers(intoBabbler, otherBabbler *Babbler, intoNa
|
||||||
mapping := map[int64]*BabblerNode{}
|
mapping := map[int64]*BabblerNode{}
|
||||||
|
|
||||||
nodes := []*BabblerNode{}
|
nodes := []*BabblerNode{}
|
||||||
err = p.store.Find(&nodes, bh.Where("babblerId").Eq(otherBabbler.BabblerId))
|
err = p.store.Find(&nodes, bh.Where("BabblerID").Eq(otherBabbler.BabblerID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
return err
|
return err
|
||||||
|
@ -633,31 +633,31 @@ func (p *BabblerPlugin) mergeBabblers(intoBabbler, otherBabbler *Babbler, intoNa
|
||||||
|
|
||||||
for _, node := range nodes {
|
for _, node := range nodes {
|
||||||
if node.NodeId == otherNode.NodeId {
|
if node.NodeId == otherNode.NodeId {
|
||||||
node.WordId = intoNode.WordId
|
node.WordID = intoNode.WordID
|
||||||
}
|
}
|
||||||
|
|
||||||
affected := 0
|
affected := 0
|
||||||
if node.Root > 0 {
|
if node.Root > 0 {
|
||||||
err = p.store.UpdateMatching(BabblerNode{},
|
err = p.store.UpdateMatching(BabblerNode{},
|
||||||
bh.Where("babblerId").Eq(intoBabbler.BabblerId).And("wordId").Eq(node.WordId),
|
bh.Where("BabblerID").Eq(intoBabbler.BabblerID).And("WordID").Eq(node.WordID),
|
||||||
func(record interface{}) error {
|
func(record interface{}) error {
|
||||||
affected++
|
affected++
|
||||||
r := record.(BabblerNode)
|
r := record.(BabblerNode)
|
||||||
r.RootFrequency += node.RootFrequency
|
r.RootFrequency += node.RootFrequency
|
||||||
r.Root = 1
|
r.Root = 1
|
||||||
return p.store.Update(r.BabblerId, r)
|
return p.store.Update(r.BabblerID, r)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
err = p.store.UpdateMatching(BabblerNode{},
|
err = p.store.UpdateMatching(BabblerNode{},
|
||||||
bh.Where("babblerId").Eq(intoBabbler.BabblerId).And("wordId").Eq(node.WordId),
|
bh.Where("BabblerID").Eq(intoBabbler.BabblerID).And("WordID").Eq(node.WordID),
|
||||||
func(record interface{}) error {
|
func(record interface{}) error {
|
||||||
affected++
|
affected++
|
||||||
r := record.(BabblerNode)
|
r := record.(BabblerNode)
|
||||||
r.RootFrequency += node.RootFrequency
|
r.RootFrequency += node.RootFrequency
|
||||||
return p.store.Update(r.BabblerId, r)
|
return p.store.Update(r.BabblerID, r)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
|
@ -665,7 +665,7 @@ func (p *BabblerPlugin) mergeBabblers(intoBabbler, otherBabbler *Babbler, intoNa
|
||||||
}
|
}
|
||||||
|
|
||||||
if err != nil || affected == 0 {
|
if err != nil || affected == 0 {
|
||||||
node.BabblerId = intoBabbler.BabblerId
|
node.BabblerID = intoBabbler.BabblerID
|
||||||
err = p.store.Insert(bh.NextSequence(), &node)
|
err = p.store.Insert(bh.NextSequence(), &node)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
|
@ -675,7 +675,7 @@ func (p *BabblerPlugin) mergeBabblers(intoBabbler, otherBabbler *Babbler, intoNa
|
||||||
|
|
||||||
var updatedNode BabblerNode
|
var updatedNode BabblerNode
|
||||||
err = p.store.FindOne(&updatedNode,
|
err = p.store.FindOne(&updatedNode,
|
||||||
bh.Where("babblerId").Eq(intoBabbler.BabblerId).And("wordId").Eq(node.WordId))
|
bh.Where("BabblerID").Eq(intoBabbler.BabblerID).And("WordID").Eq(node.WordID))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
return err
|
return err
|
||||||
|
@ -686,7 +686,7 @@ func (p *BabblerPlugin) mergeBabblers(intoBabbler, otherBabbler *Babbler, intoNa
|
||||||
|
|
||||||
for oldNodeId, newNode := range mapping {
|
for oldNodeId, newNode := range mapping {
|
||||||
arcs := []*BabblerArc{}
|
arcs := []*BabblerArc{}
|
||||||
err = p.store.Find(&arcs, bh.Where("fromNodeId").Eq(oldNodeId))
|
err = p.store.Find(&arcs, bh.Where("FromNodeID").Eq(oldNodeId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -749,7 +749,7 @@ func (p *BabblerPlugin) babbleSeedSuffix(babblerName string, seed []string) (str
|
||||||
|
|
||||||
func (p *BabblerPlugin) getNextArcs(babblerNodeId int64) ([]*BabblerArc, error) {
|
func (p *BabblerPlugin) getNextArcs(babblerNodeId int64) ([]*BabblerArc, error) {
|
||||||
arcs := []*BabblerArc{}
|
arcs := []*BabblerArc{}
|
||||||
err := p.store.Find(&arcs, bh.Where("fromNodeId").Eq(babblerNodeId))
|
err := p.store.Find(&arcs, bh.Where("FromNodeID").Eq(babblerNodeId))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
return arcs, err
|
return arcs, err
|
||||||
|
@ -845,7 +845,7 @@ func (p *BabblerPlugin) babbleSeedBookends(babblerName string, start, end []stri
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
w, err := getWord(p.store, cur.WordId)
|
w, err := getWord(p.store, cur.WordID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
return "", err
|
return "", err
|
||||||
|
|
|
@ -216,7 +216,7 @@ func (p *BeersPlugin) help(c bot.Connector, kind bot.Kind, message msg.Message,
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func getUserBeers(store *bh.Store, user, id, itemName string) counter.Item {
|
func getUserBeers(store *bh.Store, user, id, itemName string) *counter.Item {
|
||||||
// TODO: really ought to have an ID here
|
// TODO: really ought to have an ID here
|
||||||
booze, _ := counter.GetUserItem(store, user, id, itemName)
|
booze, _ := counter.GetUserItem(store, user, id, itemName)
|
||||||
return booze
|
return booze
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
bh "github.com/timshannon/bolthold"
|
bh "github.com/timshannon/bolthold"
|
||||||
|
"math"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -25,9 +26,10 @@ type CounterPlugin struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Item struct {
|
type Item struct {
|
||||||
*bh.Store
|
store *bh.Store
|
||||||
|
created bool
|
||||||
|
|
||||||
ID int64
|
ID uint64 `boltholdKey:"ID"`
|
||||||
Nick string
|
Nick string
|
||||||
Item string
|
Item string
|
||||||
Count int
|
Count int
|
||||||
|
@ -35,11 +37,12 @@ type Item struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type alias struct {
|
type alias struct {
|
||||||
*bh.Store
|
store *bh.Store
|
||||||
|
created bool
|
||||||
|
|
||||||
ID int64
|
ID uint64 `boltholdKey:"ID"`
|
||||||
Item string
|
Item string
|
||||||
PointsTo string `db:"points_to"`
|
PointsTo string `db:"PointsTo"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetItems returns all counters
|
// GetItems returns all counters
|
||||||
|
@ -51,7 +54,7 @@ func GetAllItems(store *bh.Store) ([]Item, error) {
|
||||||
}
|
}
|
||||||
// Don't forget to embed the db into all of that shiz
|
// Don't forget to embed the db into all of that shiz
|
||||||
for i := range items {
|
for i := range items {
|
||||||
items[i].Store = store
|
items[i].store = store
|
||||||
}
|
}
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
@ -62,16 +65,16 @@ func GetItems(store *bh.Store, nick, id string) ([]Item, error) {
|
||||||
var err error
|
var err error
|
||||||
q := &bh.Query{}
|
q := &bh.Query{}
|
||||||
if id != "" {
|
if id != "" {
|
||||||
q = bh.Where("userid").Eq(id)
|
q = bh.Where("UserID").Eq(id)
|
||||||
} else {
|
} else {
|
||||||
q = bh.Where("nick").Eq(nick)
|
q = bh.Where("Nick").Eq(nick)
|
||||||
}
|
}
|
||||||
if err = store.Find(&items, q); err != nil {
|
if err = store.Find(&items, q); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
// Don't forget to embed the db into all of that shiz
|
// Don't forget to embed the db into all of that shiz
|
||||||
for i := range items {
|
for i := range items {
|
||||||
items[i].Store = store
|
items[i].store = store
|
||||||
}
|
}
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
@ -86,7 +89,7 @@ func LeaderAll(store *bh.Store) ([]Item, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for i := range items {
|
for i := range items {
|
||||||
items[i].Store = store
|
items[i].store = store
|
||||||
}
|
}
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
@ -96,27 +99,32 @@ func Leader(store *bh.Store, itemName string) ([]Item, error) {
|
||||||
//s := `select * from counter where item=? order by count desc`
|
//s := `select * from counter where item=? order by count desc`
|
||||||
// todo: remove that when we verify this works
|
// todo: remove that when we verify this works
|
||||||
var items []Item
|
var items []Item
|
||||||
err := store.Find(&items, bh.Where("item").Eq(itemName).SortBy("count").Reverse())
|
err := store.Find(&items, bh.Where("Item").Eq(itemName).SortBy("Count").Reverse())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
for i := range items {
|
for i := range items {
|
||||||
items[i].Store = store
|
items[i].store = store
|
||||||
}
|
}
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func RmAlias(store *bh.Store, aliasName string) error {
|
func RmAlias(store *bh.Store, aliasName string) error {
|
||||||
return store.Delete(alias{}, aliasName)
|
a := &alias{}
|
||||||
|
if err := store.FindOne(a, bh.Where("Item").Eq(aliasName)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return store.Delete(a.ID, alias{})
|
||||||
}
|
}
|
||||||
|
|
||||||
func MkAlias(store *bh.Store, aliasName, pointsTo string) (*alias, error) {
|
func MkAlias(store *bh.Store, aliasName, pointsTo string) (*alias, error) {
|
||||||
aliasName = strings.ToLower(aliasName)
|
aliasName = strings.ToLower(aliasName)
|
||||||
pointsTo = strings.ToLower(pointsTo)
|
pointsTo = strings.ToLower(pointsTo)
|
||||||
alias := &alias{
|
alias := &alias{
|
||||||
Store: store,
|
store: store,
|
||||||
Item: aliasName,
|
Item: aliasName,
|
||||||
PointsTo: pointsTo,
|
PointsTo: pointsTo,
|
||||||
|
created: true,
|
||||||
}
|
}
|
||||||
err := store.Insert(bh.NextSequence(), alias)
|
err := store.Insert(bh.NextSequence(), alias)
|
||||||
return alias, err
|
return alias, err
|
||||||
|
@ -127,13 +135,13 @@ func GetItem(store *bh.Store, itemName string) ([]Item, error) {
|
||||||
itemName = trimUnicode(itemName)
|
itemName = trimUnicode(itemName)
|
||||||
var items []Item
|
var items []Item
|
||||||
var a alias
|
var a alias
|
||||||
if err := store.FindOne(&a, bh.Where("item").Eq(itemName)); err == nil {
|
if err := store.FindOne(&a, bh.Where("Item").Eq(itemName)); err == nil {
|
||||||
itemName = a.PointsTo
|
itemName = a.PointsTo
|
||||||
} else {
|
} else {
|
||||||
log.Error().Err(err).Interface("alias", a)
|
log.Error().Err(err).Interface("alias", a)
|
||||||
}
|
}
|
||||||
|
|
||||||
err := store.Find(&items, bh.Where("item").Eq(itemName))
|
err := store.Find(&items, bh.Where("Item").Eq(itemName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -142,32 +150,45 @@ func GetItem(store *bh.Store, itemName string) ([]Item, error) {
|
||||||
Interface("items", items).
|
Interface("items", items).
|
||||||
Msg("got item")
|
Msg("got item")
|
||||||
for _, i := range items {
|
for _, i := range items {
|
||||||
i.Store = store
|
i.store = store
|
||||||
}
|
}
|
||||||
return items, nil
|
return items, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetUserItem returns a specific counter for a subject
|
// GetUserItem returns a specific counter for a subject
|
||||||
func GetUserItem(store *bh.Store, nick, id, itemName string) (Item, error) {
|
func GetUserItem(store *bh.Store, nick, id, itemName string) (*Item, error) {
|
||||||
itemName = trimUnicode(itemName)
|
itemName = trimUnicode(itemName)
|
||||||
var item Item
|
item := &Item{}
|
||||||
item.Store = store
|
item.Nick = nick
|
||||||
|
item.Item = itemName
|
||||||
|
item.UserID = id
|
||||||
var a alias
|
var a alias
|
||||||
if err := store.FindOne(&a, bh.Where("item").Eq(itemName)); err == nil {
|
err := store.FindOne(&a, bh.Where("Item").Eq(itemName))
|
||||||
|
if err == nil {
|
||||||
|
log.Debug().Msgf("itemName now is %s", a.PointsTo)
|
||||||
itemName = a.PointsTo
|
itemName = a.PointsTo
|
||||||
|
item.Item = itemName
|
||||||
} else {
|
} else {
|
||||||
log.Error().Err(err).Interface("alias", a)
|
log.Error().Err(err).Interface("alias", a).Msgf("error finding alias")
|
||||||
}
|
}
|
||||||
|
|
||||||
var err error
|
|
||||||
q := bh.Where("nick").Eq(nick).And("item").Eq(itemName)
|
|
||||||
if id != "" {
|
if id != "" {
|
||||||
q = bh.Where("userid").Eq(id).And("item").Eq(itemName)
|
err = store.FindOne(item, bh.Where("UserID").Eq(id).And("Item").Eq(itemName))
|
||||||
|
} else {
|
||||||
|
err = store.FindOne(item, bh.Where("Nick").Eq(nick).And("Item").Eq(itemName))
|
||||||
}
|
}
|
||||||
err = store.FindOne(&item, q)
|
if err != nil && err == bh.ErrNotFound {
|
||||||
if err != nil {
|
log.Debug().Msgf("We gotta create this item: %v", item)
|
||||||
return Item{}, err
|
item.store = store
|
||||||
|
if err := item.Create(); err != nil {
|
||||||
|
return nil, err
|
||||||
}
|
}
|
||||||
|
return item, nil
|
||||||
|
} else if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
item.store = store
|
||||||
|
item.created = true
|
||||||
log.Debug().
|
log.Debug().
|
||||||
Str("nick", nick).
|
Str("nick", nick).
|
||||||
Str("id", id).
|
Str("id", id).
|
||||||
|
@ -180,7 +201,10 @@ func GetUserItem(store *bh.Store, nick, id, itemName string) (Item, error) {
|
||||||
// GetUserItem returns a specific counter for a subject
|
// 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 {
|
||||||
err := i.Store.Insert(bh.NextSequence(), i)
|
log.Debug().Msgf("i %v, store %v", i, i.store)
|
||||||
|
err := i.store.Insert(bh.NextSequence(), i)
|
||||||
|
i.created = true
|
||||||
|
log.Debug().Msgf("we just inserted an item, %v", i)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -188,17 +212,19 @@ func (i *Item) Create() error {
|
||||||
// This will create or delete the item if necessary
|
// This will create or delete the item if necessary
|
||||||
func (i *Item) Update(r *bot.Request, value int) error {
|
func (i *Item) Update(r *bot.Request, value int) error {
|
||||||
i.Count = value
|
i.Count = value
|
||||||
if i.Count == 0 && i.ID != -1 {
|
if i.Count == 0 && i.created {
|
||||||
return i.Delete()
|
return i.Delete()
|
||||||
}
|
}
|
||||||
if i.ID == -1 {
|
if !i.created {
|
||||||
i.Create()
|
if err := i.Create(); err != nil {
|
||||||
|
log.Error().Err(err).Msg("could not create")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
log.Debug().
|
log.Debug().
|
||||||
Interface("i", i).
|
Interface("i", i).
|
||||||
Int("value", value).
|
Int("value", value).
|
||||||
Msg("Updating item")
|
Msg("Updating item")
|
||||||
err := i.Store.Update(i.ID, i)
|
err := i.store.Update(i.ID, i)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
sendUpdate(r, i.Nick, i.Item, i.Count)
|
sendUpdate(r, i.Nick, i.Item, i.Count)
|
||||||
}
|
}
|
||||||
|
@ -214,8 +240,9 @@ func (i *Item) UpdateDelta(r *bot.Request, delta int) error {
|
||||||
|
|
||||||
// Delete removes a counter from the database
|
// Delete removes a counter from the database
|
||||||
func (i *Item) Delete() error {
|
func (i *Item) Delete() error {
|
||||||
err := i.Store.Delete(i.ID, Item{})
|
err := i.store.Delete(i.ID, Item{})
|
||||||
i.ID = -1
|
i.created = false
|
||||||
|
i.ID = math.MaxUint64
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,11 +336,13 @@ func (p *CounterPlugin) mkAliasCmd(r bot.Request) bool {
|
||||||
p.b.Send(r.Conn, bot.Message, fmt.Sprintf("You must provide all fields for an alias: %s", mkAliasRegex))
|
p.b.Send(r.Conn, bot.Message, fmt.Sprintf("You must provide all fields for an alias: %s", mkAliasRegex))
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if _, err := MkAlias(p.store, what, to); err != nil {
|
alias, err := MkAlias(p.store, what, to)
|
||||||
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("Could not mkalias")
|
log.Error().Err(err).Msg("Could not mkalias")
|
||||||
p.b.Send(r.Conn, bot.Message, r.Msg.Channel, "We're gonna need too much db space to make an alias for your mom.")
|
p.b.Send(r.Conn, bot.Message, r.Msg.Channel, "We're gonna need too much db space to make an alias for your mom.")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
log.Debug().Msgf("alias created: %v", alias)
|
||||||
p.b.Send(r.Conn, bot.Message, r.Msg.Channel, fmt.Sprintf("Created alias %s -> %s",
|
p.b.Send(r.Conn, bot.Message, r.Msg.Channel, fmt.Sprintf("Created alias %s -> %s",
|
||||||
what, to))
|
what, to))
|
||||||
return true
|
return true
|
||||||
|
@ -416,6 +445,8 @@ func (p *CounterPlugin) inspectCmd(r bot.Request) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
log.Debug().Msgf("items: %v", items)
|
||||||
|
|
||||||
resp := fmt.Sprintf("%s has the following counters:", nick)
|
resp := fmt.Sprintf("%s has the following counters:", nick)
|
||||||
count := 0
|
count := 0
|
||||||
for _, it := range items {
|
for _, it := range items {
|
||||||
|
@ -483,7 +514,6 @@ func (p *CounterPlugin) countCmd(r bot.Request) bool {
|
||||||
nick, id = p.resolveUser(r, r.Values["who"])
|
nick, id = p.resolveUser(r, r.Values["who"])
|
||||||
}
|
}
|
||||||
|
|
||||||
var item Item
|
|
||||||
item, err := GetUserItem(p.store, nick, id, itemName)
|
item, err := GetUserItem(p.store, nick, id, itemName)
|
||||||
switch {
|
switch {
|
||||||
case err == sql.ErrNoRows:
|
case err == sql.ErrNoRows:
|
||||||
|
@ -515,7 +545,8 @@ func (p *CounterPlugin) incrementCmd(r bot.Request) bool {
|
||||||
channel := r.Msg.Channel
|
channel := r.Msg.Channel
|
||||||
// ++ those fuckers
|
// ++ those fuckers
|
||||||
item, err := GetUserItem(p.store, nick, id, itemName)
|
item, err := GetUserItem(p.store, nick, id, itemName)
|
||||||
if err != nil {
|
log.Debug().Msgf("GetUserItem: %v", item)
|
||||||
|
if err != nil && err != bh.ErrNotFound {
|
||||||
log.Error().
|
log.Error().
|
||||||
Err(err).
|
Err(err).
|
||||||
Str("nick", nick).
|
Str("nick", nick).
|
||||||
|
|
|
@ -17,13 +17,16 @@ import (
|
||||||
"github.com/velour/catbase/bot/user"
|
"github.com/velour/catbase/bot/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
func setup(t *testing.T) (*bot.MockBot, *CounterPlugin) {
|
func setup(t *testing.T) (*bot.MockBot, *CounterPlugin, func()) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
c := New(mb)
|
c := New(mb)
|
||||||
mb.DB().MustExec(`delete from counter; delete from counter_alias;`)
|
_, err := MkAlias(mb.Store(), "tea", ":tea:")
|
||||||
_, err := MkAlias(mb.DB(), "tea", ":tea:")
|
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
return mb, c
|
return mb, c, func() {
|
||||||
|
if err := mb.TearDown(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeMessage(payload string, r *regexp.Regexp) bot.Request {
|
func makeMessage(payload string, r *regexp.Regexp) bot.Request {
|
||||||
|
@ -44,126 +47,139 @@ func makeMessage(payload string, r *regexp.Regexp) bot.Request {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMkAlias(t *testing.T) {
|
func TestMkAlias(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.mkAliasCmd(makeMessage("mkalias fuck mornings", mkAliasRegex))
|
c.mkAliasCmd(makeMessage("mkalias fuck mornings", mkAliasRegex))
|
||||||
c.incrementCmd(makeMessage("fuck++", incrementRegex))
|
c.incrementCmd(makeMessage("fuck++", incrementRegex))
|
||||||
item, err := GetUserItem(mb.DB(), "tester", "id", "mornings")
|
item, err := GetUserItem(mb.Store(), "tester", "id", "mornings")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, 1, item.Count)
|
assert.Equal(t, 1, item.Count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRmAlias(t *testing.T) {
|
func TestRmAlias(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.mkAliasCmd(makeMessage("mkalias fuck mornings", mkAliasRegex))
|
c.mkAliasCmd(makeMessage("mkalias fuck mornings", mkAliasRegex))
|
||||||
c.rmAliasCmd(makeMessage("rmalias fuck", rmAliasRegex))
|
c.rmAliasCmd(makeMessage("rmalias fuck", rmAliasRegex))
|
||||||
c.incrementCmd(makeMessage("fuck++", incrementRegex))
|
c.incrementCmd(makeMessage("fuck++", incrementRegex))
|
||||||
item, err := GetUserItem(mb.DB(), "tester", "id", "mornings")
|
item, err := GetUserItem(mb.Store(), "tester", "id", "mornings")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, 0, item.Count)
|
assert.Equal(t, 0, item.Count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestThreeSentencesExists(t *testing.T) {
|
func TestThreeSentencesExists(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.incrementCmd(makeMessage(":beer:++", incrementRegex))
|
c.incrementCmd(makeMessage(":beer:++", incrementRegex))
|
||||||
c.teaMatchCmd(makeMessage(":beer:. Earl Grey. Hot.", teaRegex))
|
c.teaMatchCmd(makeMessage(":beer:. Earl Grey. Hot.", teaRegex))
|
||||||
item, err := GetUserItem(mb.DB(), "tester", "id", ":beer:")
|
item, err := GetUserItem(mb.Store(), "tester", "id", ":beer:")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, 2, item.Count)
|
assert.Equal(t, 2, item.Count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestThreeSentencesNotExists(t *testing.T) {
|
func TestThreeSentencesNotExists(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
item, err := GetUserItem(mb.DB(), "tester", "id", ":beer:")
|
item, err := GetUserItem(mb.Store(), "tester", "id", ":beer:")
|
||||||
c.teaMatchCmd(makeMessage(":beer:. Earl Grey. Hot.", teaRegex))
|
c.teaMatchCmd(makeMessage(":beer:. Earl Grey. Hot.", teaRegex))
|
||||||
item, err = GetUserItem(mb.DB(), "tester", "id", ":beer:")
|
item, err = GetUserItem(mb.Store(), "tester", "id", ":beer:")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, 0, item.Count)
|
assert.Equal(t, 0, item.Count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTeaEarlGreyHot(t *testing.T) {
|
func TestTeaEarlGreyHot(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.teaMatchCmd(makeMessage("Tea. Earl Grey. Hot.", teaRegex))
|
c.teaMatchCmd(makeMessage("Tea. Earl Grey. Hot.", teaRegex))
|
||||||
c.teaMatchCmd(makeMessage("Tea. Earl Grey. Hot.", teaRegex))
|
c.teaMatchCmd(makeMessage("Tea. Earl Grey. Hot.", teaRegex))
|
||||||
item, err := GetUserItem(mb.DB(), "tester", "id", ":tea:")
|
item, err := GetUserItem(mb.Store(), "tester", "id", ":tea:")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, 2, item.Count)
|
assert.Equal(t, 2, item.Count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTeaTwoPeriods(t *testing.T) {
|
func TestTeaTwoPeriods(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.teaMatchCmd(makeMessage("Tea. Earl Grey.", teaRegex))
|
c.teaMatchCmd(makeMessage("Tea. Earl Grey.", teaRegex))
|
||||||
c.teaMatchCmd(makeMessage("Tea. Earl Grey.", teaRegex))
|
c.teaMatchCmd(makeMessage("Tea. Earl Grey.", teaRegex))
|
||||||
item, err := GetUserItem(mb.DB(), "tester", "id", ":tea:")
|
item, err := GetUserItem(mb.Store(), "tester", "id", ":tea:")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, 0, item.Count)
|
assert.Equal(t, 0, item.Count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTeaMultiplePeriods(t *testing.T) {
|
func TestTeaMultiplePeriods(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.teaMatchCmd(makeMessage("Tea. Earl Grey. Spiked. Hot.", teaRegex))
|
c.teaMatchCmd(makeMessage("Tea. Earl Grey. Spiked. Hot.", teaRegex))
|
||||||
c.teaMatchCmd(makeMessage("Tea. Earl Grey. Spiked. Hot.", teaRegex))
|
c.teaMatchCmd(makeMessage("Tea. Earl Grey. Spiked. Hot.", teaRegex))
|
||||||
item, err := GetUserItem(mb.DB(), "tester", "id", ":tea:")
|
item, err := GetUserItem(mb.Store(), "tester", "id", ":tea:")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, 2, item.Count)
|
assert.Equal(t, 2, item.Count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTeaGreenHot(t *testing.T) {
|
func TestTeaGreenHot(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.teaMatchCmd(makeMessage("Tea. Green. Hot.", teaRegex))
|
c.teaMatchCmd(makeMessage("Tea. Green. Hot.", teaRegex))
|
||||||
c.teaMatchCmd(makeMessage("Tea. Green. Hot", teaRegex))
|
c.teaMatchCmd(makeMessage("Tea. Green. Hot", teaRegex))
|
||||||
c.teaMatchCmd(makeMessage("Tea. Green. Iced.", teaRegex))
|
c.teaMatchCmd(makeMessage("Tea. Green. Iced.", teaRegex))
|
||||||
item, err := GetUserItem(mb.DB(), "tester", "id", ":tea:")
|
item, err := GetUserItem(mb.Store(), "tester", "id", ":tea:")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, 3, item.Count)
|
assert.Equal(t, 3, item.Count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTeaUnrelated(t *testing.T) {
|
func TestTeaUnrelated(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.teaMatchCmd(makeMessage("Tea.", teaRegex))
|
c.teaMatchCmd(makeMessage("Tea.", teaRegex))
|
||||||
c.teaMatchCmd(makeMessage("Tea. It's great.", teaRegex))
|
c.teaMatchCmd(makeMessage("Tea. It's great.", teaRegex))
|
||||||
item, err := GetUserItem(mb.DB(), "tester", "id", ":tea:")
|
item, err := GetUserItem(mb.Store(), "tester", "id", ":tea:")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, 0, item.Count)
|
assert.Equal(t, 0, item.Count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTeaSkieselQuote(t *testing.T) {
|
func TestTeaSkieselQuote(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.teaMatchCmd(makeMessage("blah, this is a whole page of explanation where \"we did local search and used a tabu list\" would have sufficed", teaRegex))
|
c.teaMatchCmd(makeMessage("blah, this is a whole page of explanation where \"we did local search and used a tabu list\" would have sufficed", teaRegex))
|
||||||
item, err := GetUserItem(mb.DB(), "tester", "id", ":tea:")
|
item, err := GetUserItem(mb.Store(), "tester", "id", ":tea:")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, 0, item.Count)
|
assert.Equal(t, 0, item.Count)
|
||||||
}
|
}
|
||||||
func TestTeaUnicodeJapanese(t *testing.T) {
|
func TestTeaUnicodeJapanese(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.teaMatchCmd(makeMessage("Tea. おちや. Hot.", teaRegex))
|
c.teaMatchCmd(makeMessage("Tea. おちや. Hot.", teaRegex))
|
||||||
item, err := GetUserItem(mb.DB(), "tester", "id", ":tea:")
|
item, err := GetUserItem(mb.Store(), "tester", "id", ":tea:")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Equal(t, 1, item.Count)
|
assert.Equal(t, 1, item.Count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResetMe(t *testing.T) {
|
func TestResetMe(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.incrementCmd(makeMessage("test++", incrementRegex))
|
c.incrementCmd(makeMessage("test++", incrementRegex))
|
||||||
c.resetCmd(makeMessage("!reset me", resetRegex))
|
c.resetCmd(makeMessage("!reset me", resetRegex))
|
||||||
items, err := GetItems(mb.DB(), "tester", "id")
|
items, err := GetItems(mb.Store(), "tester", "id")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
assert.Len(t, items, 0)
|
assert.Len(t, items, 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCounterOne(t *testing.T) {
|
func TestCounterOne(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.incrementCmd(makeMessage("test++", incrementRegex))
|
c.incrementCmd(makeMessage("test++", incrementRegex))
|
||||||
assert.Len(t, mb.Messages, 1)
|
assert.Len(t, mb.Messages, 1)
|
||||||
|
@ -171,7 +187,8 @@ func TestCounterOne(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCounterOneWithSpace(t *testing.T) {
|
func TestCounterOneWithSpace(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.incrementCmd(makeMessage(":test: ++", incrementRegex))
|
c.incrementCmd(makeMessage(":test: ++", incrementRegex))
|
||||||
assert.Len(t, mb.Messages, 1)
|
assert.Len(t, mb.Messages, 1)
|
||||||
|
@ -179,7 +196,8 @@ func TestCounterOneWithSpace(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCounterFour(t *testing.T) {
|
func TestCounterFour(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
c.incrementCmd(makeMessage("test++", incrementRegex))
|
c.incrementCmd(makeMessage("test++", incrementRegex))
|
||||||
|
@ -189,7 +207,8 @@ func TestCounterFour(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCounterDecrement(t *testing.T) {
|
func TestCounterDecrement(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
c.incrementCmd(makeMessage("test++", incrementRegex))
|
c.incrementCmd(makeMessage("test++", incrementRegex))
|
||||||
|
@ -201,7 +220,8 @@ func TestCounterDecrement(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFriendCounterDecrement(t *testing.T) {
|
func TestFriendCounterDecrement(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
c.incrementCmd(makeMessage("other.test++", incrementRegex))
|
c.incrementCmd(makeMessage("other.test++", incrementRegex))
|
||||||
|
@ -213,7 +233,8 @@ func TestFriendCounterDecrement(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestDecrementZero(t *testing.T) {
|
func TestDecrementZero(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
c.incrementCmd(makeMessage("test++", incrementRegex))
|
c.incrementCmd(makeMessage("test++", incrementRegex))
|
||||||
|
@ -230,7 +251,8 @@ func TestDecrementZero(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestClear(t *testing.T) {
|
func TestClear(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
c.incrementCmd(makeMessage("test++", incrementRegex))
|
c.incrementCmd(makeMessage("test++", incrementRegex))
|
||||||
|
@ -243,7 +265,8 @@ func TestClear(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCount(t *testing.T) {
|
func TestCount(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
c.incrementCmd(makeMessage("test++", incrementRegex))
|
c.incrementCmd(makeMessage("test++", incrementRegex))
|
||||||
|
@ -257,7 +280,8 @@ func TestCount(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestInspectMe(t *testing.T) {
|
func TestInspectMe(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
for i := 0; i < 4; i++ {
|
for i := 0; i < 4; i++ {
|
||||||
c.incrementCmd(makeMessage("test++", incrementRegex))
|
c.incrementCmd(makeMessage("test++", incrementRegex))
|
||||||
|
@ -278,7 +302,8 @@ func TestInspectMe(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHelp(t *testing.T) {
|
func TestHelp(t *testing.T) {
|
||||||
mb, c := setup(t)
|
mb, c, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.help(&cli.CliPlugin{}, bot.Help, msg.Message{Channel: "channel"}, []string{})
|
c.help(&cli.CliPlugin{}, bot.Help, msg.Message{Channel: "channel"}, []string{})
|
||||||
assert.Greater(t, len(mb.Messages), 1)
|
assert.Greater(t, len(mb.Messages), 1)
|
||||||
|
|
|
@ -50,7 +50,7 @@ func (a *alias) resolve(store *bh.Store) (*Factoid, error) {
|
||||||
// todo: remove this query
|
// todo: remove this query
|
||||||
//q := `select fact, next from factoid_alias where fact=?`
|
//q := `select fact, next from factoid_alias where fact=?`
|
||||||
var next alias
|
var next alias
|
||||||
err := store.FindOne(&next, bh.Where("fact").Eq(a.Next))
|
err := store.FindOne(&next, bh.Where("Fact").Eq(a.Next))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
// we hit the end of the chain, get a factoid named Next
|
// we hit the end of the chain, get a factoid named Next
|
||||||
fact, err := GetSingleFact(store, a.Next)
|
fact, err := GetSingleFact(store, a.Next)
|
||||||
|
@ -67,7 +67,7 @@ func findAlias(store *bh.Store, fact string) (bool, *Factoid) {
|
||||||
// todo: remove this query
|
// todo: remove this query
|
||||||
//q := `select * from factoid_alias where fact=?`
|
//q := `select * from factoid_alias where fact=?`
|
||||||
var a alias
|
var a alias
|
||||||
err := store.FindOne(&a, bh.Where("fact").Eq(fact))
|
err := store.FindOne(&a, bh.Where("Fact").Eq(fact))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
|
@ -78,7 +78,7 @@ func findAlias(store *bh.Store, fact string) (bool, *Factoid) {
|
||||||
func (a *alias) save(store *bh.Store) error {
|
func (a *alias) save(store *bh.Store) error {
|
||||||
//q := `select * from factoid_alias where fact=?`
|
//q := `select * from factoid_alias where fact=?`
|
||||||
var offender alias
|
var offender alias
|
||||||
err := store.FindOne(&offender, bh.Where("fact").Eq(a.Next))
|
err := store.FindOne(&offender, bh.Where("Fact").Eq(a.Next))
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return fmt.Errorf("DANGER: an opposite alias already exists")
|
return fmt.Errorf("DANGER: an opposite alias already exists")
|
||||||
}
|
}
|
||||||
|
@ -123,7 +123,7 @@ func (f *Factoid) delete(store *bh.Store) error {
|
||||||
|
|
||||||
func getFacts(store *bh.Store, fact string, tidbit string) ([]*Factoid, error) {
|
func getFacts(store *bh.Store, fact string, tidbit string) ([]*Factoid, error) {
|
||||||
var fs []*Factoid
|
var fs []*Factoid
|
||||||
err := store.Find(&fs, bh.Where("fact").Contains(fact).And("tidbit").Contains(tidbit))
|
err := store.Find(&fs, bh.Where("Fact").Contains(fact).And("Tidbit").Contains(tidbit))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("Error regexping for facts")
|
log.Error().Err(err).Msg("Error regexping for facts")
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -142,9 +142,12 @@ func GetSingle(store *bh.Store) (*Factoid, error) {
|
||||||
|
|
||||||
func GetSingleFact(store *bh.Store, fact string) (*Factoid, error) {
|
func GetSingleFact(store *bh.Store, fact string) (*Factoid, error) {
|
||||||
var allMatching []Factoid
|
var allMatching []Factoid
|
||||||
if err := store.Find(&allMatching, bh.Where("fact").Contains(fact)); err != nil {
|
if err := store.Find(&allMatching, bh.Where("Fact").Contains(fact)); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
if len(allMatching) == 0 {
|
||||||
|
return nil, fmt.Errorf("no entries")
|
||||||
|
}
|
||||||
f := allMatching[rand.Intn(len(allMatching))]
|
f := allMatching[rand.Intn(len(allMatching))]
|
||||||
return &f, nil
|
return &f, nil
|
||||||
}
|
}
|
||||||
|
@ -232,7 +235,7 @@ func (p *FactoidPlugin) learnFact(message msg.Message, fact, verb, tidbit string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
count, err := p.store.Count(Factoid{}, bh.Where("fact").Eq(fact).And("verb").Eq(verb).And("tidbit").Eq(tidbit))
|
count, err := p.store.Count(Factoid{}, bh.Where("Fact").Eq(fact).And("Verb").Eq(verb).And("Tidbit").Eq(tidbit))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("Error counting facts")
|
log.Error().Err(err).Msg("Error counting facts")
|
||||||
return fmt.Errorf("What?")
|
return fmt.Errorf("What?")
|
||||||
|
|
|
@ -27,13 +27,13 @@ type FirstPlugin struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type FirstEntry struct {
|
type FirstEntry struct {
|
||||||
id int64
|
ID uint64 `boltholdKey:"ID"`
|
||||||
day time.Time
|
Day time.Time
|
||||||
time time.Time
|
Time time.Time
|
||||||
channel string
|
Channel string
|
||||||
body string
|
Body string
|
||||||
nick string
|
Nick string
|
||||||
saved bool
|
Saved bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Insert or update the first entry
|
// Insert or update the first entry
|
||||||
|
@ -42,12 +42,12 @@ func (fe *FirstEntry) save(store *bh.Store) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (fe *FirstEntry) delete(store *bh.Store) error {
|
func (fe *FirstEntry) delete(store *bh.Store) error {
|
||||||
return store.Delete(fe.id, FirstEntry{})
|
return store.Delete(fe.ID, FirstEntry{})
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewFirstPlugin creates a new FirstPlugin with the Plugin interface
|
// NewFirstPlugin creates a new FirstPlugin with the Plugin interface
|
||||||
func New(b bot.Bot) *FirstPlugin {
|
func New(b bot.Bot) *FirstPlugin {
|
||||||
log.Info().Msgf("First plugin initialized with day: %s",
|
log.Info().Msgf("First plugin initialized with Day: %s",
|
||||||
Midnight(time.Now()))
|
Midnight(time.Now()))
|
||||||
|
|
||||||
fp := &FirstPlugin{
|
fp := &FirstPlugin{
|
||||||
|
@ -63,11 +63,11 @@ func New(b bot.Bot) *FirstPlugin {
|
||||||
|
|
||||||
func getLastFirst(store *bh.Store, channel string) (*FirstEntry, error) {
|
func getLastFirst(store *bh.Store, channel string) (*FirstEntry, error) {
|
||||||
fe := &FirstEntry{}
|
fe := &FirstEntry{}
|
||||||
err := store.FindOne(fe, bh.Where("channel").Eq(channel))
|
err := store.FindOne(fe, bh.Where("Channel").Eq(channel))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
log.Debug().Msgf("id: %v day %v time %v body %v nick %v", fe)
|
log.Debug().Msgf("ID: %v Day %v Time %v Body %v Nick %v", fe)
|
||||||
return fe, nil
|
return fe, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -80,7 +80,7 @@ func (p *FirstPlugin) isNotToday(f *FirstEntry) bool {
|
||||||
if f == nil {
|
if f == nil {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
t := f.time
|
t := f.Time
|
||||||
t0 := Midnight(t)
|
t0 := Midnight(t)
|
||||||
jitter := time.Duration(p.config.GetInt("first.jitter", 0))
|
jitter := time.Duration(p.config.GetInt("first.jitter", 0))
|
||||||
t0 = t0.Add(jitter * time.Millisecond)
|
t0 = t0.Add(jitter * time.Millisecond)
|
||||||
|
@ -138,7 +138,7 @@ func (p *FirstPlugin) register() {
|
||||||
log.Debug().Msgf("Re-enabled first")
|
log.Debug().Msgf("Re-enabled first")
|
||||||
}()
|
}()
|
||||||
p.bot.Send(r.Conn, bot.Message, r.Msg.Channel,
|
p.bot.Send(r.Conn, bot.Message, r.Msg.Channel,
|
||||||
fmt.Sprintf("Deleted first entry: '%s' and set a random timer for when first will happen next.", fe.body))
|
fmt.Sprintf("Deleted first entry: '%s' and set a random timer for when first will happen next.", fe.Body))
|
||||||
return true
|
return true
|
||||||
}},
|
}},
|
||||||
{Kind: bot.Message, IsCmd: false,
|
{Kind: bot.Message, IsCmd: false,
|
||||||
|
@ -161,7 +161,7 @@ func (p *FirstPlugin) register() {
|
||||||
|
|
||||||
if (first == nil || p.isNotToday(first)) && p.allowed(r.Msg) {
|
if (first == nil || p.isNotToday(first)) && p.allowed(r.Msg) {
|
||||||
log.Debug().
|
log.Debug().
|
||||||
Str("body", r.Msg.Body).
|
Str("Body", r.Msg.Body).
|
||||||
Interface("t0", first).
|
Interface("t0", first).
|
||||||
Time("t1", time.Now()).
|
Time("t1", time.Now()).
|
||||||
Msg("Recording first")
|
Msg("Recording first")
|
||||||
|
@ -196,7 +196,7 @@ func (p *FirstPlugin) allowed(message msg.Message) bool {
|
||||||
if match {
|
if match {
|
||||||
log.Info().
|
log.Info().
|
||||||
Str("user", message.User.Name).
|
Str("user", message.User.Name).
|
||||||
Str("body", message.Body).
|
Str("Body", message.Body).
|
||||||
Msg("Disallowing first")
|
Msg("Disallowing first")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -205,7 +205,7 @@ func (p *FirstPlugin) allowed(message msg.Message) bool {
|
||||||
if host == message.Host {
|
if host == message.Host {
|
||||||
log.Info().
|
log.Info().
|
||||||
Str("user", message.User.Name).
|
Str("user", message.User.Name).
|
||||||
Str("body", message.Body).
|
Str("Body", message.Body).
|
||||||
Msg("Disallowing first")
|
Msg("Disallowing first")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -214,7 +214,7 @@ func (p *FirstPlugin) allowed(message msg.Message) bool {
|
||||||
if nick == message.User.Name {
|
if nick == message.User.Name {
|
||||||
log.Info().
|
log.Info().
|
||||||
Str("user", message.User.Name).
|
Str("user", message.User.Name).
|
||||||
Str("body", message.Body).
|
Str("Body", message.Body).
|
||||||
Msg("Disallowing first")
|
Msg("Disallowing first")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
@ -224,18 +224,18 @@ func (p *FirstPlugin) allowed(message msg.Message) bool {
|
||||||
|
|
||||||
func (p *FirstPlugin) recordFirst(c bot.Connector, message msg.Message) {
|
func (p *FirstPlugin) recordFirst(c bot.Connector, message msg.Message) {
|
||||||
log.Info().
|
log.Info().
|
||||||
Str("channel", message.Channel).
|
Str("Channel", message.Channel).
|
||||||
Str("user", message.User.Name).
|
Str("user", message.User.Name).
|
||||||
Str("body", message.Body).
|
Str("Body", message.Body).
|
||||||
Msg("Recording first")
|
Msg("Recording first")
|
||||||
first := &FirstEntry{
|
first := &FirstEntry{
|
||||||
day: Midnight(time.Now()),
|
Day: Midnight(time.Now()),
|
||||||
time: time.Now(),
|
Time: time.Now(),
|
||||||
channel: message.Channel,
|
Channel: message.Channel,
|
||||||
body: message.Body,
|
Body: message.Body,
|
||||||
nick: message.User.Name,
|
Nick: message.User.Name,
|
||||||
}
|
}
|
||||||
log.Info().Msgf("recordFirst: %+v", first.day)
|
log.Info().Msgf("recordFirst: %+v", first.Day)
|
||||||
err := first.save(p.store)
|
err := first.save(p.store)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("Error saving first entry")
|
log.Error().Err(err).Msg("Error saving first entry")
|
||||||
|
@ -246,13 +246,13 @@ func (p *FirstPlugin) recordFirst(c bot.Connector, message msg.Message) {
|
||||||
|
|
||||||
func (p *FirstPlugin) leaderboard(c bot.Connector, ch string) error {
|
func (p *FirstPlugin) leaderboard(c bot.Connector, ch string) error {
|
||||||
// todo: remove this once we verify stuff
|
// todo: remove this once we verify stuff
|
||||||
//q := `select max(channel) channel, max(nick) nick, count(id) count
|
//q := `select max(Channel) Channel, max(Nick) Nick, count(ID) count
|
||||||
// from first
|
// from first
|
||||||
// group by channel, nick
|
// group by Channel, Nick
|
||||||
// having channel = ?
|
// having Channel = ?
|
||||||
// order by count desc
|
// order by count desc
|
||||||
// limit 3`
|
// limit 3`
|
||||||
groups, err := p.store.FindAggregate(FirstEntry{}, bh.Where("channel").Eq(ch), "channel", "nick")
|
groups, err := p.store.FindAggregate(FirstEntry{}, bh.Where("Channel").Eq(ch), "Channel", "Nick")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -274,9 +274,9 @@ func (p *FirstPlugin) leaderboard(c bot.Connector, ch string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *FirstPlugin) announceFirst(c bot.Connector, first *FirstEntry) {
|
func (p *FirstPlugin) announceFirst(c bot.Connector, first *FirstEntry) {
|
||||||
ch := first.channel
|
ch := first.Channel
|
||||||
p.bot.Send(c, bot.Message, ch, fmt.Sprintf("%s had first at %s with the message: \"%s\"",
|
p.bot.Send(c, bot.Message, ch, fmt.Sprintf("%s had first at %s with the message: \"%s\"",
|
||||||
first.nick, first.time.Format("15:04"), first.body))
|
first.Nick, first.Time.Format("15:04"), first.Body))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Help responds to help requests. Every plugin must implement a help function.
|
// Help responds to help requests. Every plugin must implement a help function.
|
||||||
|
|
|
@ -237,7 +237,7 @@ func parseCmd(r *regexp.Regexp, body string) cmd {
|
||||||
}
|
}
|
||||||
|
|
||||||
type goal struct {
|
type goal struct {
|
||||||
ID int64 `boltholdid:"ID"`
|
ID uint64 `boltholdid:"ID"`
|
||||||
Kind string
|
Kind string
|
||||||
Who string
|
Who string
|
||||||
What string
|
What string
|
||||||
|
@ -246,9 +246,9 @@ type goal struct {
|
||||||
gp *GoalsPlugin
|
gp *GoalsPlugin
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GoalsPlugin) newGoal(kind, who, what string, amount int) goal {
|
func (p *GoalsPlugin) newGoal(kind, who, what string, amount int) *goal {
|
||||||
return goal{
|
return &goal{
|
||||||
ID: -1,
|
ID: 0,
|
||||||
Kind: kind,
|
Kind: kind,
|
||||||
Who: who,
|
Who: who,
|
||||||
What: what,
|
What: what,
|
||||||
|
@ -259,7 +259,7 @@ func (p *GoalsPlugin) newGoal(kind, who, what string, amount int) goal {
|
||||||
|
|
||||||
func (p *GoalsPlugin) getGoal(who, what string) ([]*goal, error) {
|
func (p *GoalsPlugin) getGoal(who, what string) ([]*goal, error) {
|
||||||
gs := []*goal{}
|
gs := []*goal{}
|
||||||
err := p.store.Find(&gs, bh.Where("who").Eq(who).And("what").Eq(what))
|
err := p.store.Find(&gs, bh.Where("Who").Eq(who).And("What").Eq(what))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -271,7 +271,7 @@ func (p *GoalsPlugin) getGoal(who, what string) ([]*goal, error) {
|
||||||
|
|
||||||
func (p *GoalsPlugin) getGoalKind(kind, who, what string) (*goal, error) {
|
func (p *GoalsPlugin) getGoalKind(kind, who, what string) (*goal, error) {
|
||||||
g := &goal{gp: p}
|
g := &goal{gp: p}
|
||||||
err := p.store.FindOne(&g, bh.Where("kind").Eq(kind).And("who").Eq(who).And("what").Eq(what))
|
err := p.store.FindOne(g, bh.Where("Kind").Eq(kind).And("Who").Eq(who).And("What").Eq(what))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -279,7 +279,7 @@ func (p *GoalsPlugin) getGoalKind(kind, who, what string) (*goal, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g *goal) Save() error {
|
func (g *goal) Save() error {
|
||||||
err := g.gp.store.Insert(bh.NextSequence(), &g)
|
err := g.gp.store.Insert(bh.NextSequence(), g)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -287,7 +287,7 @@ func (g *goal) Save() error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (g goal) Delete() error {
|
func (g goal) Delete() error {
|
||||||
if g.ID == -1 {
|
if g.ID == 0 {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
err := g.gp.store.Delete(goal{}, g.ID)
|
err := g.gp.store.Delete(goal{}, g.ID)
|
||||||
|
@ -313,7 +313,7 @@ func (p *GoalsPlugin) update(r bot.Request, u counter.Update) {
|
||||||
|
|
||||||
var now = time.Now
|
var now = time.Now
|
||||||
|
|
||||||
func (p *GoalsPlugin) calculateRemaining(i counter.Item, g *goal) int {
|
func (p *GoalsPlugin) calculateRemaining(i *counter.Item, g *goal) int {
|
||||||
today := float64(now().YearDay())
|
today := float64(now().YearDay())
|
||||||
thisYear := time.Date(now().Year(), 0, 0, 0, 0, 0, 0, time.UTC)
|
thisYear := time.Date(now().Year(), 0, 0, 0, 0, 0, 0, time.UTC)
|
||||||
nextYear := time.Date(now().Year()+1, 0, 0, 0, 0, 0, 0, time.UTC)
|
nextYear := time.Date(now().Year()+1, 0, 0, 0, 0, 0, 0, time.UTC)
|
||||||
|
@ -328,7 +328,7 @@ func (p *GoalsPlugin) calculateRemaining(i counter.Item, g *goal) int {
|
||||||
return diff
|
return diff
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *GoalsPlugin) remainingText(i counter.Item, g *goal) string {
|
func (p *GoalsPlugin) remainingText(i *counter.Item, g *goal) string {
|
||||||
remaining := p.calculateRemaining(i, g)
|
remaining := p.calculateRemaining(i, g)
|
||||||
txt := ""
|
txt := ""
|
||||||
if remaining < 0 {
|
if remaining < 0 {
|
||||||
|
|
|
@ -1,6 +1,11 @@
|
||||||
package goals
|
package goals
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"github.com/velour/catbase/bot/msg"
|
||||||
|
"github.com/velour/catbase/bot/user"
|
||||||
|
"github.com/velour/catbase/plugins/cli"
|
||||||
|
"regexp"
|
||||||
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -10,11 +15,46 @@ import (
|
||||||
"github.com/velour/catbase/plugins/counter"
|
"github.com/velour/catbase/plugins/counter"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func setup(t *testing.T) (*bot.MockBot, *GoalsPlugin, func()) {
|
||||||
|
mb := bot.NewMockBot()
|
||||||
|
c := New(mb)
|
||||||
|
return mb, c, func() {
|
||||||
|
if err := mb.TearDown(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeMessage(payload string, r *regexp.Regexp) bot.Request {
|
||||||
|
isCmd := strings.HasPrefix(payload, "!")
|
||||||
|
if isCmd {
|
||||||
|
payload = payload[1:]
|
||||||
|
}
|
||||||
|
values := bot.ParseValues(r, payload)
|
||||||
|
return bot.Request{
|
||||||
|
Conn: &cli.CliPlugin{},
|
||||||
|
Msg: msg.Message{
|
||||||
|
User: &user.User{Name: "tester", ID: "id"},
|
||||||
|
Body: payload,
|
||||||
|
Command: isCmd,
|
||||||
|
},
|
||||||
|
Values: values,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendMessage(gp *GoalsPlugin, message string) {
|
||||||
|
for _, h := range gp.handlers {
|
||||||
|
r := makeMessage(message, h.Regex)
|
||||||
|
if h.Regex.MatchString(message) {
|
||||||
|
h.Handler(r)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRemainingSomeToGo(t *testing.T) {
|
func TestRemainingSomeToGo(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
|
|
||||||
i := counter.Item{
|
i := &counter.Item{
|
||||||
DB: mb.DB(),
|
|
||||||
ID: 0,
|
ID: 0,
|
||||||
Nick: "",
|
Nick: "",
|
||||||
Item: "",
|
Item: "",
|
||||||
|
@ -45,8 +85,7 @@ func TestRemainingSomeToGo(t *testing.T) {
|
||||||
func TestRemainingAheadOfCurve(t *testing.T) {
|
func TestRemainingAheadOfCurve(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
|
|
||||||
i := counter.Item{
|
i := &counter.Item{
|
||||||
DB: mb.DB(),
|
|
||||||
ID: 0,
|
ID: 0,
|
||||||
Nick: "",
|
Nick: "",
|
||||||
Item: "",
|
Item: "",
|
||||||
|
@ -73,3 +112,10 @@ func TestRemainingAheadOfCurve(t *testing.T) {
|
||||||
|
|
||||||
assert.Equal(t, expected, actual)
|
assert.Equal(t, expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRegister(t *testing.T) {
|
||||||
|
_, gp, td := setup(t)
|
||||||
|
defer td()
|
||||||
|
|
||||||
|
sendMessage(gp, "register goal :tea: 5")
|
||||||
|
}
|
||||||
|
|
|
@ -154,7 +154,7 @@ func (p *InventoryPlugin) getAll() []string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *InventoryPlugin) exists(i string) bool {
|
func (p *InventoryPlugin) exists(i string) bool {
|
||||||
count, err := p.Store.Count(Item{}, bh.Where("item").Eq(i))
|
count, err := p.Store.Count(Item{}, bh.Where("Item").Eq(i))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("Error checking for item")
|
log.Error().Err(err).Msg("Error checking for item")
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -135,7 +135,7 @@ func (p *LastPlugin) yesterdaysLast(ch string) (last, error) {
|
||||||
midnight := first.Midnight(time.Now())
|
midnight := first.Midnight(time.Now())
|
||||||
q := `select * from last where channel = ? and day < ? and day >= ? order by day limit 1`
|
q := `select * from last where channel = ? and day < ? and day >= ? order by day limit 1`
|
||||||
log.Debug().Str("q", q).Msgf("yesterdaysLast: %d to %d", midnight.Unix(), midnight.Add(-24*time.Hour).Unix())
|
log.Debug().Str("q", q).Msgf("yesterdaysLast: %d to %d", midnight.Unix(), midnight.Add(-24*time.Hour).Unix())
|
||||||
err := p.store.FindOne(&l, bh.Where("channel").Eq(ch).And("day").Lt(midnight.Unix()).And("day").Ge(midnight.Add(-24*time.Hour).Unix()))
|
err := p.store.FindOne(&l, bh.Where("Channel").Eq(ch).And("Day").Lt(midnight.Unix()).And("Day").Ge(midnight.Add(-24*time.Hour).Unix()))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return last{}, err
|
return last{}, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -78,7 +78,7 @@ func (w *Webshit) Check(last int64) ([]WeeklyResult, int64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
var bids []Bid
|
var bids []Bid
|
||||||
if err = w.store.Find(&bids, bh.Where("processed").Eq(false)); err != nil {
|
if err = w.store.Find(&bids, bh.Where("Processed").Eq(false)); err != nil {
|
||||||
return nil, 0, err
|
return nil, 0, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -106,7 +106,7 @@ func (w *Webshit) Check(last int64) ([]WeeklyResult, int64, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete all those bids
|
// Delete all those bids
|
||||||
if err = w.store.UpdateMatching(Bid{}, bh.Where("processed").Eq(false), func(record interface{}) error {
|
if err = w.store.UpdateMatching(Bid{}, bh.Where("Processed").Eq(false), func(record interface{}) error {
|
||||||
r := record.(*Bid)
|
r := record.(*Bid)
|
||||||
r.Processed = true
|
r.Processed = true
|
||||||
return w.store.Update(r.ID, r)
|
return w.store.Update(r.ID, r)
|
||||||
|
@ -234,7 +234,7 @@ func (w *Webshit) GetBalance(user string) Balance {
|
||||||
|
|
||||||
func (w *Webshit) GetAllBids() ([]Bid, error) {
|
func (w *Webshit) GetAllBids() ([]Bid, error) {
|
||||||
var bids []Bid
|
var bids []Bid
|
||||||
err := w.store.Find(&bids, bh.Where("processed").Eq(false))
|
err := w.store.Find(&bids, bh.Where("Processed").Eq(false))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -117,7 +117,7 @@ func (p *RememberPlugin) randQuote() string {
|
||||||
// AllQuotesFrom delivers quotes out of the db from who.
|
// AllQuotesFrom delivers quotes out of the db from who.
|
||||||
func AllQuotesFrom(store *bh.Store, who string) []fact.Factoid {
|
func AllQuotesFrom(store *bh.Store, who string) []fact.Factoid {
|
||||||
allQuotes := []fact.Factoid{}
|
allQuotes := []fact.Factoid{}
|
||||||
err := store.Find(&allQuotes, bh.Where("fact").Eq(who+" quotes"))
|
err := store.Find(&allQuotes, bh.Where("Fact").Eq(who+" quotes"))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("Error getting quotes")
|
log.Error().Err(err).Msg("Error getting quotes")
|
||||||
return []fact.Factoid{}
|
return []fact.Factoid{}
|
||||||
|
@ -130,7 +130,7 @@ func AllQuotesFrom(store *bh.Store, who string) []fact.Factoid {
|
||||||
// expanded to have this function execute a quote for a particular channel
|
// expanded to have this function execute a quote for a particular channel
|
||||||
func RandQuote(store *bh.Store) string {
|
func RandQuote(store *bh.Store) string {
|
||||||
allQuotes := []fact.Factoid{}
|
allQuotes := []fact.Factoid{}
|
||||||
err := store.Find(&allQuotes, bh.Where("fact").RegExp(regexp.MustCompile(`.+ quotes$`)))
|
err := store.Find(&allQuotes, bh.Where("Fact").RegExp(regexp.MustCompile(`.+ quotes$`)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err).Msg("Error getting quotes")
|
log.Error().Err(err).Msg("Error getting quotes")
|
||||||
return "I had a problem getting your quote."
|
return "I had a problem getting your quote."
|
||||||
|
|
|
@ -37,12 +37,12 @@ type ReminderPlugin struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
type Reminder struct {
|
type Reminder struct {
|
||||||
id int64
|
ID uint64 `boltholdKey:"ID"`
|
||||||
from string
|
From string
|
||||||
who string
|
Who string
|
||||||
what string
|
What string
|
||||||
when time.Time
|
When time.Time
|
||||||
channel string
|
Channel string
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(b bot.Bot) *ReminderPlugin {
|
func New(b bot.Bot) *ReminderPlugin {
|
||||||
|
@ -108,22 +108,21 @@ func (p *ReminderPlugin) message(c bot.Connector, kind bot.Kind, message msg.Mes
|
||||||
|
|
||||||
if operator == "in" || operator == "at" || operator == "on" {
|
if operator == "in" || operator == "at" || operator == "on" {
|
||||||
//one off reminder
|
//one off reminder
|
||||||
//remind who in dur blah
|
//remind Who in dur blah
|
||||||
when := time.Now().UTC().Add(dur)
|
when := time.Now().UTC().Add(dur)
|
||||||
what := strings.Join(parts[4:], " ")
|
what := strings.Join(parts[4:], " ")
|
||||||
|
|
||||||
p.addReminder(&Reminder{
|
p.addReminder(&Reminder{
|
||||||
id: -1,
|
From: from,
|
||||||
from: from,
|
Who: who,
|
||||||
who: who,
|
What: what,
|
||||||
what: what,
|
When: when,
|
||||||
when: when,
|
Channel: channel,
|
||||||
channel: channel,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
} else if operator == "every" && strings.ToLower(parts[4]) == "for" {
|
} else if operator == "every" && strings.ToLower(parts[4]) == "for" {
|
||||||
//batch add, especially for reminding msherms to buy a kit
|
//batch add, especially for reminding msherms to buy a kit
|
||||||
//remind who every dur for dur2 blah
|
//remind Who every dur for dur2 blah
|
||||||
dur2, err = time.ParseDuration(parts[5])
|
dur2, err = time.ParseDuration(parts[5])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
|
@ -144,18 +143,17 @@ func (p *ReminderPlugin) message(c bot.Connector, kind bot.Kind, message msg.Mes
|
||||||
}
|
}
|
||||||
|
|
||||||
p.addReminder(&Reminder{
|
p.addReminder(&Reminder{
|
||||||
id: int64(-1),
|
From: from,
|
||||||
from: from,
|
Who: who,
|
||||||
who: who,
|
What: what,
|
||||||
what: what,
|
When: when,
|
||||||
when: when,
|
Channel: channel,
|
||||||
channel: channel,
|
|
||||||
})
|
})
|
||||||
|
|
||||||
when = when.Add(dur)
|
when = when.Add(dur)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
p.bot.Send(c, bot.Message, channel, "Easy cowboy, not sure I comprehend what you're asking.")
|
p.bot.Send(c, bot.Message, channel, "Easy cowboy, not sure I comprehend What you're asking.")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -177,7 +175,7 @@ func (p *ReminderPlugin) message(c bot.Connector, kind bot.Kind, message msg.Mes
|
||||||
} else if len(parts) == 4 {
|
} else if len(parts) == 4 {
|
||||||
if strings.ToLower(parts[2]) == "to" {
|
if strings.ToLower(parts[2]) == "to" {
|
||||||
response, err = p.getAllRemindersToMeFormatted(channel, strings.ToLower(parts[3]))
|
response, err = p.getAllRemindersToMeFormatted(channel, strings.ToLower(parts[3]))
|
||||||
} else if strings.ToLower(parts[2]) == "from" {
|
} else if strings.ToLower(parts[2]) == "From" {
|
||||||
response, err = p.getAllRemindersFromMeFormatted(channel, strings.ToLower(parts[3]))
|
response, err = p.getAllRemindersFromMeFormatted(channel, strings.ToLower(parts[3]))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -188,9 +186,9 @@ func (p *ReminderPlugin) message(c bot.Connector, kind bot.Kind, message msg.Mes
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
} else if len(parts) == 3 && strings.ToLower(parts[0]) == "cancel" && strings.ToLower(parts[1]) == "reminder" {
|
} else if len(parts) == 3 && strings.ToLower(parts[0]) == "cancel" && strings.ToLower(parts[1]) == "reminder" {
|
||||||
id, err := strconv.ParseInt(parts[2], 10, 64)
|
id, err := strconv.ParseUint(parts[2], 10, 64)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
p.bot.Send(c, bot.Message, channel, fmt.Sprintf("couldn't parse id: %s", parts[2]))
|
p.bot.Send(c, bot.Message, channel, fmt.Sprintf("couldn't parse ID: %s", parts[2]))
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
err := p.deleteReminder(id)
|
err := p.deleteReminder(id)
|
||||||
|
@ -221,7 +219,11 @@ func (p *ReminderPlugin) getNextReminder() *Reminder {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
res[0].Max("remindWhen", &reminder)
|
if len(res) == 0 {
|
||||||
|
log.Error().Msg("No next reminder in system.")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
res[0].Max("RemindWhen", &reminder)
|
||||||
|
|
||||||
return &reminder
|
return &reminder
|
||||||
}
|
}
|
||||||
|
@ -231,12 +233,13 @@ func (p *ReminderPlugin) addReminder(reminder *Reminder) error {
|
||||||
defer p.mutex.Unlock()
|
defer p.mutex.Unlock()
|
||||||
err := p.store.Insert(bh.NextSequence(), reminder)
|
err := p.store.Insert(bh.NextSequence(), reminder)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err).Msgf("error creating reminder")
|
||||||
}
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
func (p *ReminderPlugin) deleteReminder(id int64) error {
|
func (p *ReminderPlugin) deleteReminder(id uint64) error {
|
||||||
p.mutex.Lock()
|
p.mutex.Lock()
|
||||||
defer p.mutex.Unlock()
|
defer p.mutex.Unlock()
|
||||||
err := p.store.Delete(id, Reminder{})
|
err := p.store.Delete(id, Reminder{})
|
||||||
|
@ -264,14 +267,14 @@ func (p *ReminderPlugin) getRemindersFormatted(filter, who string) (string, erro
|
||||||
}
|
}
|
||||||
|
|
||||||
reminders := []Reminder{}
|
reminders := []Reminder{}
|
||||||
err = p.store.Find(&reminders, q.SortBy("id").Limit(max))
|
err = p.store.Find(&reminders, q.SortBy("ID").Limit(max))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error().Err(err)
|
log.Error().Err(err)
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
txt := ""
|
txt := ""
|
||||||
for counter, reminder := range reminders {
|
for counter, reminder := range reminders {
|
||||||
txt += fmt.Sprintf("%d) %s -> %s :: %s @ %s (%d)\n", counter, reminder.from, reminder.who, reminder.what, reminder.when, reminder.id)
|
txt += fmt.Sprintf("%d) %s -> %s :: %s @ %s (%d)\n", counter, reminder.From, reminder.Who, reminder.What, reminder.When, reminder.ID)
|
||||||
counter++
|
counter++
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -288,18 +291,18 @@ func (p *ReminderPlugin) getAllRemindersFormatted(channel string) (string, error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ReminderPlugin) getAllRemindersFromMeFormatted(channel, me string) (string, error) {
|
func (p *ReminderPlugin) getAllRemindersFromMeFormatted(channel, me string) (string, error) {
|
||||||
return p.getRemindersFormatted("fromWho", me)
|
return p.getRemindersFormatted("FromWho", me)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ReminderPlugin) getAllRemindersToMeFormatted(channel, me string) (string, error) {
|
func (p *ReminderPlugin) getAllRemindersToMeFormatted(channel, me string) (string, error) {
|
||||||
return p.getRemindersFormatted("toWho", me)
|
return p.getRemindersFormatted("ToWho", me)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *ReminderPlugin) queueUpNextReminder() {
|
func (p *ReminderPlugin) queueUpNextReminder() {
|
||||||
nextReminder := p.getNextReminder()
|
nextReminder := p.getNextReminder()
|
||||||
|
|
||||||
if nextReminder != nil {
|
if nextReminder != nil {
|
||||||
p.timer.Reset(nextReminder.when.Sub(time.Now().UTC()))
|
p.timer.Reset(nextReminder.When.Sub(time.Now().UTC()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -309,24 +312,24 @@ func reminderer(c bot.Connector, p *ReminderPlugin) {
|
||||||
|
|
||||||
reminder := p.getNextReminder()
|
reminder := p.getNextReminder()
|
||||||
|
|
||||||
if reminder != nil && time.Now().UTC().After(reminder.when) {
|
if reminder != nil && time.Now().UTC().After(reminder.When) {
|
||||||
var message string
|
var message string
|
||||||
if reminder.from == reminder.who {
|
if reminder.From == reminder.Who {
|
||||||
reminder.from = "you"
|
reminder.From = "you"
|
||||||
message = fmt.Sprintf("Hey %s, you wanted to be reminded: %s", reminder.who, reminder.what)
|
message = fmt.Sprintf("Hey %s, you wanted to be reminded: %s", reminder.Who, reminder.What)
|
||||||
} else {
|
} else {
|
||||||
message = fmt.Sprintf("Hey %s, %s wanted you to be reminded: %s", reminder.who, reminder.from, reminder.what)
|
message = fmt.Sprintf("Hey %s, %s wanted you to be reminded: %s", reminder.Who, reminder.From, reminder.What)
|
||||||
}
|
}
|
||||||
|
|
||||||
p.bot.Send(c, bot.Message, reminder.channel, message)
|
p.bot.Send(c, bot.Message, reminder.Channel, message)
|
||||||
smsPlugin := sms.New(p.bot)
|
smsPlugin := sms.New(p.bot)
|
||||||
if err := smsPlugin.Send(reminder.who, message); err != nil {
|
if err := smsPlugin.Send(reminder.Who, message); err != nil {
|
||||||
log.Error().Err(err).Msgf("could not send reminder")
|
log.Error().Err(err).Msgf("could not send reminder")
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.deleteReminder(reminder.id); err != nil {
|
if err := p.deleteReminder(reminder.ID); err != nil {
|
||||||
log.Error().
|
log.Fatal().
|
||||||
Int64("id", reminder.id).
|
Uint64("ID", reminder.ID).
|
||||||
Err(err).
|
Err(err).
|
||||||
Msg("this will cause problems, we need to stop now.")
|
Msg("this will cause problems, we need to stop now.")
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,15 +32,17 @@ func makeMessageBy(payload, by string) (bot.Connector, bot.Kind, msg.Message) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func setup(t *testing.T) (*ReminderPlugin, *bot.MockBot) {
|
func setup(t *testing.T) (*ReminderPlugin, *bot.MockBot, func()) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
r := New(mb)
|
r := New(mb)
|
||||||
mb.DB().MustExec(`delete from reminders; delete from config;`)
|
return r, mb, func() {
|
||||||
return r, mb
|
mb.TearDown()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMeReminder(t *testing.T) {
|
func TestMeReminder(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
res := c.message(makeMessage("!remind me in 1s don't fail this test"))
|
res := c.message(makeMessage("!remind me in 1s don't fail this test"))
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
assert.Len(t, mb.Messages, 2)
|
assert.Len(t, mb.Messages, 2)
|
||||||
|
@ -50,7 +52,8 @@ func TestMeReminder(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReminder(t *testing.T) {
|
func TestReminder(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
res := c.message(makeMessage("!remind testuser in 1s don't fail this test"))
|
res := c.message(makeMessage("!remind testuser in 1s don't fail this test"))
|
||||||
time.Sleep(2 * time.Second)
|
time.Sleep(2 * time.Second)
|
||||||
assert.Len(t, mb.Messages, 2)
|
assert.Len(t, mb.Messages, 2)
|
||||||
|
@ -60,7 +63,8 @@ func TestReminder(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReminderReorder(t *testing.T) {
|
func TestReminderReorder(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
res := c.message(makeMessage("!remind testuser in 2s don't fail this test 2"))
|
res := c.message(makeMessage("!remind testuser in 2s don't fail this test 2"))
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
res = c.message(makeMessage("!remind testuser in 1s don't fail this test 1"))
|
res = c.message(makeMessage("!remind testuser in 1s don't fail this test 1"))
|
||||||
|
@ -74,7 +78,8 @@ func TestReminderReorder(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReminderParse(t *testing.T) {
|
func TestReminderParse(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
res := c.message(makeMessage("!remind testuser in unparseable don't fail this test"))
|
res := c.message(makeMessage("!remind testuser in unparseable don't fail this test"))
|
||||||
assert.Len(t, mb.Messages, 1)
|
assert.Len(t, mb.Messages, 1)
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
|
@ -82,7 +87,8 @@ func TestReminderParse(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEmptyList(t *testing.T) {
|
func TestEmptyList(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
res := c.message(makeMessage("!list reminders"))
|
res := c.message(makeMessage("!list reminders"))
|
||||||
assert.Len(t, mb.Messages, 1)
|
assert.Len(t, mb.Messages, 1)
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
|
@ -90,7 +96,8 @@ func TestEmptyList(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestList(t *testing.T) {
|
func TestList(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
res := c.message(makeMessage("!remind testuser in 5m don't fail this test 1"))
|
res := c.message(makeMessage("!remind testuser in 5m don't fail this test 1"))
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
res = c.message(makeMessage("!remind testuser in 5m don't fail this test 2"))
|
res = c.message(makeMessage("!remind testuser in 5m don't fail this test 2"))
|
||||||
|
@ -103,12 +110,13 @@ func TestList(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestListBy(t *testing.T) {
|
func TestListBy(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
res := c.message(makeMessageBy("!remind testuser in 5m don't fail this test 1", "testuser"))
|
res := c.message(makeMessageBy("!remind testuser in 5m don't fail this test 1", "testuser"))
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
res = c.message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
|
res = c.message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
res = c.message(makeMessage("!list reminders from testuser"))
|
res = c.message(makeMessage("!list reminders From testuser"))
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
assert.Len(t, mb.Messages, 3)
|
assert.Len(t, mb.Messages, 3)
|
||||||
assert.Contains(t, mb.Messages[2], "don't fail this test 1 @ ")
|
assert.Contains(t, mb.Messages[2], "don't fail this test 1 @ ")
|
||||||
|
@ -116,7 +124,8 @@ func TestListBy(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestListTo(t *testing.T) {
|
func TestListTo(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
res := c.message(makeMessageBy("!remind testuser2 in 5m don't fail this test 1", "testuser"))
|
res := c.message(makeMessageBy("!remind testuser2 in 5m don't fail this test 1", "testuser"))
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
res = c.message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
|
res = c.message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
|
||||||
|
@ -129,7 +138,8 @@ func TestListTo(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToEmptyList(t *testing.T) {
|
func TestToEmptyList(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
res := c.message(makeMessageBy("!remind testuser2 in 5m don't fail this test 1", "testuser"))
|
res := c.message(makeMessageBy("!remind testuser2 in 5m don't fail this test 1", "testuser"))
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
res = c.message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
|
res = c.message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
|
||||||
|
@ -141,19 +151,21 @@ func TestToEmptyList(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromEmptyList(t *testing.T) {
|
func TestFromEmptyList(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
res := c.message(makeMessageBy("!remind testuser2 in 5m don't fail this test 1", "testuser"))
|
res := c.message(makeMessageBy("!remind testuser2 in 5m don't fail this test 1", "testuser"))
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
res = c.message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
|
res = c.message(makeMessageBy("!remind testuser in 5m don't fail this test 2", "testuser2"))
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
res = c.message(makeMessage("!list reminders from test"))
|
res = c.message(makeMessage("!list reminders From test"))
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
assert.Len(t, mb.Messages, 3)
|
assert.Len(t, mb.Messages, 3)
|
||||||
assert.Contains(t, mb.Messages[2], "no pending reminders")
|
assert.Contains(t, mb.Messages[2], "no pending reminders")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBatchMax(t *testing.T) {
|
func TestBatchMax(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
c.config.Set("Reminder.MaxBatchAdd", "10")
|
c.config.Set("Reminder.MaxBatchAdd", "10")
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
res := c.message(makeMessage("!remind testuser every 1h for 24h yikes"))
|
res := c.message(makeMessage("!remind testuser every 1h for 24h yikes"))
|
||||||
|
@ -170,7 +182,8 @@ func TestBatchMax(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCancel(t *testing.T) {
|
func TestCancel(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
res := c.message(makeMessage("!remind testuser in 1m don't fail this test"))
|
res := c.message(makeMessage("!remind testuser in 1m don't fail this test"))
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
|
@ -185,7 +198,8 @@ func TestCancel(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCancelMiss(t *testing.T) {
|
func TestCancelMiss(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
res := c.message(makeMessage("!cancel reminder 1"))
|
res := c.message(makeMessage("!cancel reminder 1"))
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
|
@ -194,7 +208,8 @@ func TestCancelMiss(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestLimitList(t *testing.T) {
|
func TestLimitList(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
c.config.Set("Reminder.MaxBatchAdd", "10")
|
c.config.Set("Reminder.MaxBatchAdd", "10")
|
||||||
c.config.Set("Reminder.MaxList", "25")
|
c.config.Set("Reminder.MaxList", "25")
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
|
@ -222,8 +237,9 @@ func TestLimitList(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHelp(t *testing.T) {
|
func TestHelp(t *testing.T) {
|
||||||
c, mb := setup(t)
|
c, mb, td := setup(t)
|
||||||
|
defer td()
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.help(&cli.CliPlugin{}, bot.Help, msg.Message{Channel: "channel"}, []string{})
|
c.help(&cli.CliPlugin{}, bot.Help, msg.Message{Channel: "Channel"}, []string{})
|
||||||
assert.Len(t, mb.Messages, 1)
|
assert.Len(t, mb.Messages, 1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
bh "github.com/timshannon/bolthold"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
storePath = flag.String("store", "rathaus.store", "store file")
|
||||||
|
action = flag.String("action", "", "action to perform")
|
||||||
|
what = flag.String("what", "", "what to clean")
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
flag.Parse()
|
||||||
|
|
||||||
|
if *action == "" {
|
||||||
|
flag.Usage()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
store, err := bh.Open(*storePath, 0666, nil)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer store.Close()
|
||||||
|
|
||||||
|
if *action == "clear" && *what != "" {
|
||||||
|
tx, _ := store.Bolt().Begin(true)
|
||||||
|
err := tx.DeleteBucket([]byte(*what))
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
tx.Commit()
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue