mirror of https://github.com/velour/catbase.git
commit
396d3acec6
|
@ -29,3 +29,4 @@ vendor
|
||||||
.vscode/
|
.vscode/
|
||||||
*.code-workspace
|
*.code-workspace
|
||||||
*config.lua
|
*config.lua
|
||||||
|
modd.conf
|
||||||
|
|
63
bot/bot.go
63
bot/bot.go
|
@ -3,7 +3,6 @@
|
||||||
package bot
|
package bot
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
@ -32,13 +31,6 @@ type bot struct {
|
||||||
|
|
||||||
conn Connector
|
conn Connector
|
||||||
|
|
||||||
// SQL DB
|
|
||||||
// TODO: I think it'd be nice to use https://github.com/jmoiron/sqlx so that
|
|
||||||
// the select/update/etc statements could be simplified with struct
|
|
||||||
// marshalling.
|
|
||||||
db *sqlx.DB
|
|
||||||
dbVersion int64
|
|
||||||
|
|
||||||
logIn chan msg.Message
|
logIn chan msg.Message
|
||||||
logOut chan msg.Messages
|
logOut chan msg.Messages
|
||||||
|
|
||||||
|
@ -64,7 +56,7 @@ func New(config *config.Config, connector Connector) Bot {
|
||||||
|
|
||||||
users := []user.User{
|
users := []user.User{
|
||||||
user.User{
|
user.User{
|
||||||
Name: config.Nick,
|
Name: config.Get("Nick"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,10 +67,8 @@ func New(config *config.Config, connector Connector) Bot {
|
||||||
conn: connector,
|
conn: connector,
|
||||||
users: users,
|
users: users,
|
||||||
me: users[0],
|
me: users[0],
|
||||||
db: config.DBConn,
|
|
||||||
logIn: logIn,
|
logIn: logIn,
|
||||||
logOut: logOut,
|
logOut: logOut,
|
||||||
version: config.Version,
|
|
||||||
httpEndPoints: make(map[string]string),
|
httpEndPoints: make(map[string]string),
|
||||||
filters: make(map[string]func(string) string),
|
filters: make(map[string]func(string) string),
|
||||||
}
|
}
|
||||||
|
@ -86,10 +76,12 @@ func New(config *config.Config, connector Connector) Bot {
|
||||||
bot.migrateDB()
|
bot.migrateDB()
|
||||||
|
|
||||||
http.HandleFunc("/", bot.serveRoot)
|
http.HandleFunc("/", bot.serveRoot)
|
||||||
if config.HttpAddr == "" {
|
addr := config.Get("HttpAddr")
|
||||||
config.HttpAddr = "127.0.0.1:1337"
|
if addr == "" {
|
||||||
|
addr = "127.0.0.1:1337"
|
||||||
|
config.Set("HttpAddr", addr)
|
||||||
}
|
}
|
||||||
go http.ListenAndServe(config.HttpAddr, nil)
|
go http.ListenAndServe(addr, nil)
|
||||||
|
|
||||||
connector.RegisterMessageReceived(bot.MsgReceived)
|
connector.RegisterMessageReceived(bot.MsgReceived)
|
||||||
connector.RegisterEventReceived(bot.EventReceived)
|
connector.RegisterEventReceived(bot.EventReceived)
|
||||||
|
@ -103,39 +95,15 @@ func (b *bot) Config() *config.Config {
|
||||||
return b.config
|
return b.config
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bot) DBVersion() int64 {
|
|
||||||
return b.dbVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b *bot) DB() *sqlx.DB {
|
func (b *bot) DB() *sqlx.DB {
|
||||||
return b.db
|
return b.config.DB
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create any tables if necessary based on version of DB
|
// Create any tables if necessary based on version of DB
|
||||||
// Plugins should create their own tables, these are only for official bot stuff
|
// Plugins should create their own tables, these are only for official bot stuff
|
||||||
// Note: This does not return an error. Database issues are all fatal at this stage.
|
// Note: This does not return an error. Database issues are all fatal at this stage.
|
||||||
func (b *bot) migrateDB() {
|
func (b *bot) migrateDB() {
|
||||||
_, err := b.db.Exec(`create table if not exists version (version integer);`)
|
if _, err := b.DB().Exec(`create table if not exists variables (
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Initial DB migration create version table: ", err)
|
|
||||||
}
|
|
||||||
var version sql.NullInt64
|
|
||||||
err = b.db.QueryRow("select max(version) from version").Scan(&version)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Initial DB migration get version: ", err)
|
|
||||||
}
|
|
||||||
if version.Valid {
|
|
||||||
b.dbVersion = version.Int64
|
|
||||||
log.Printf("Database version: %v\n", b.dbVersion)
|
|
||||||
} else {
|
|
||||||
log.Printf("No versions, we're the first!.")
|
|
||||||
_, err := b.db.Exec(`insert into version (version) values (1)`)
|
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Initial DB migration insert: ", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := b.db.Exec(`create table if not exists variables (
|
|
||||||
id integer primary key,
|
id integer primary key,
|
||||||
name string,
|
name string,
|
||||||
value string
|
value string
|
||||||
|
@ -204,8 +172,15 @@ func (b *bot) serveRoot(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
// Checks if message is a command and returns its curtailed version
|
// Checks if message is a command and returns its curtailed version
|
||||||
func IsCmd(c *config.Config, message string) (bool, string) {
|
func IsCmd(c *config.Config, message string) (bool, string) {
|
||||||
cmdcs := c.CommandChar
|
cmdcs := c.GetArray("CommandChar")
|
||||||
botnick := strings.ToLower(c.Nick)
|
if len(cmdcs) == 0 {
|
||||||
|
cmdcs = []string{"!"}
|
||||||
|
c.SetArray("CommandChar", cmdcs)
|
||||||
|
}
|
||||||
|
botnick := strings.ToLower(c.Get("Nick"))
|
||||||
|
if botnick == "" {
|
||||||
|
log.Fatalf(`You must run catbase -set nick -val <your bot nick>`)
|
||||||
|
}
|
||||||
iscmd := false
|
iscmd := false
|
||||||
lowerMessage := strings.ToLower(message)
|
lowerMessage := strings.ToLower(message)
|
||||||
|
|
||||||
|
@ -237,7 +212,7 @@ func IsCmd(c *config.Config, message string) (bool, string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bot) CheckAdmin(nick string) bool {
|
func (b *bot) CheckAdmin(nick string) bool {
|
||||||
for _, u := range b.Config().Admins {
|
for _, u := range b.Config().GetArray("Admins") {
|
||||||
if nick == u {
|
if nick == u {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
@ -265,7 +240,7 @@ func (b *bot) NewUser(nick string) *user.User {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *bot) checkAdmin(nick string) bool {
|
func (b *bot) checkAdmin(nick string) bool {
|
||||||
for _, u := range b.Config().Admins {
|
for _, u := range b.Config().GetArray("Admins") {
|
||||||
if nick == u {
|
if nick == u {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -192,7 +192,7 @@ func (b *bot) Filter(message msg.Message, input string) string {
|
||||||
|
|
||||||
func (b *bot) getVar(varName string) (string, error) {
|
func (b *bot) getVar(varName string) (string, error) {
|
||||||
var text string
|
var text string
|
||||||
err := b.db.Get(&text, `select value from variables where name=? order by random() limit 1`, varName)
|
err := b.DB().Get(&text, `select value from variables where name=? order by random() limit 1`, varName)
|
||||||
switch {
|
switch {
|
||||||
case err == sql.ErrNoRows:
|
case err == sql.ErrNoRows:
|
||||||
return "", fmt.Errorf("No factoid found")
|
return "", fmt.Errorf("No factoid found")
|
||||||
|
@ -204,7 +204,7 @@ func (b *bot) getVar(varName string) (string, error) {
|
||||||
|
|
||||||
func (b *bot) listVars(channel string, parts []string) {
|
func (b *bot) listVars(channel string, parts []string) {
|
||||||
var variables []string
|
var variables []string
|
||||||
err := b.db.Select(&variables, `select name from variables group by name`)
|
err := b.DB().Select(&variables, `select name from variables group by name`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
|
|
||||||
type Bot interface {
|
type Bot interface {
|
||||||
Config() *config.Config
|
Config() *config.Config
|
||||||
DBVersion() int64
|
|
||||||
DB() *sqlx.DB
|
DB() *sqlx.DB
|
||||||
Who(string) []user.User
|
Who(string) []user.User
|
||||||
AddHandler(string, Handler)
|
AddHandler(string, Handler)
|
||||||
|
|
13
bot/mock.go
13
bot/mock.go
|
@ -19,16 +19,16 @@ type MockBot struct {
|
||||||
mock.Mock
|
mock.Mock
|
||||||
db *sqlx.DB
|
db *sqlx.DB
|
||||||
|
|
||||||
Cfg config.Config
|
Cfg *config.Config
|
||||||
|
|
||||||
Messages []string
|
Messages []string
|
||||||
Actions []string
|
Actions []string
|
||||||
Reactions []string
|
Reactions []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (mb *MockBot) Config() *config.Config { return &mb.Cfg }
|
func (mb *MockBot) Config() *config.Config { return mb.Cfg }
|
||||||
func (mb *MockBot) DBVersion() int64 { return 1 }
|
func (mb *MockBot) DBVersion() int64 { return 1 }
|
||||||
func (mb *MockBot) DB() *sqlx.DB { return mb.db }
|
func (mb *MockBot) DB() *sqlx.DB { return mb.Cfg.DB }
|
||||||
func (mb *MockBot) Conn() Connector { return nil }
|
func (mb *MockBot) Conn() Connector { return nil }
|
||||||
func (mb *MockBot) Who(string) []user.User { return []user.User{} }
|
func (mb *MockBot) Who(string) []user.User { return []user.User{} }
|
||||||
func (mb *MockBot) AddHandler(name string, f Handler) {}
|
func (mb *MockBot) AddHandler(name string, f Handler) {}
|
||||||
|
@ -94,12 +94,9 @@ 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 {
|
||||||
db, err := sqlx.Open("sqlite3_custom", ":memory:")
|
cfg := config.ReadConfig("file::memory:?mode=memory&cache=shared")
|
||||||
if err != nil {
|
|
||||||
log.Fatal("Failed to open database:", err)
|
|
||||||
}
|
|
||||||
b := MockBot{
|
b := MockBot{
|
||||||
db: db,
|
Cfg: cfg,
|
||||||
Messages: make([]string, 0),
|
Messages: make([]string, 0),
|
||||||
Actions: make([]string, 0),
|
Actions: make([]string, 0),
|
||||||
}
|
}
|
||||||
|
|
210
config/config.go
210
config/config.go
|
@ -6,111 +6,118 @@ import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
|
"os"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
sqlite3 "github.com/mattn/go-sqlite3"
|
sqlite3 "github.com/mattn/go-sqlite3"
|
||||||
"github.com/yuin/gluamapper"
|
|
||||||
lua "github.com/yuin/gopher-lua"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// Config stores any system-wide startup information that cannot be easily configured via
|
// Config stores any system-wide startup information that cannot be easily configured via
|
||||||
// the database
|
// the database
|
||||||
type Config struct {
|
type Config struct {
|
||||||
DBConn *sqlx.DB
|
*sqlx.DB
|
||||||
|
|
||||||
DB struct {
|
DBFile string
|
||||||
File string
|
|
||||||
Name string
|
|
||||||
Server string
|
|
||||||
}
|
}
|
||||||
Channels []string
|
|
||||||
MainChannel string
|
// GetFloat64 returns the config value for a string key
|
||||||
Plugins []string
|
// It will first look in the env vars for the key
|
||||||
Type string
|
// It will check the DB for the key if an env DNE
|
||||||
Irc struct {
|
// Finally, it will return a zero value if the key does not exist
|
||||||
Server, Pass string
|
// It will attempt to convert the value to a float64 if it exists
|
||||||
|
func (c *Config) GetFloat64(key string) float64 {
|
||||||
|
f, err := strconv.ParseFloat(c.GetString(key), 64)
|
||||||
|
if err != nil {
|
||||||
|
return 0.0
|
||||||
}
|
}
|
||||||
Slack struct {
|
return f
|
||||||
Token string
|
|
||||||
}
|
}
|
||||||
Nick string
|
|
||||||
IconURL string
|
// GetInt returns the config value for a string key
|
||||||
FullName string
|
// It will first look in the env vars for the key
|
||||||
Version string
|
// It will check the DB for the key if an env DNE
|
||||||
CommandChar []string
|
// Finally, it will return a zero value if the key does not exist
|
||||||
RatePerSec float64
|
// It will attempt to convert the value to an int if it exists
|
||||||
LogLength int
|
func (c *Config) GetInt(key string) int {
|
||||||
Admins []string
|
i, err := strconv.Atoi(c.GetString(key))
|
||||||
HttpAddr string
|
if err != nil {
|
||||||
Untappd struct {
|
return 0
|
||||||
Token string
|
|
||||||
Freq int
|
|
||||||
Channels []string
|
|
||||||
}
|
}
|
||||||
Twitch struct {
|
return i
|
||||||
Freq int
|
|
||||||
Users map[string][]string //channel -> usernames
|
|
||||||
ClientID string
|
|
||||||
Authorization string
|
|
||||||
}
|
}
|
||||||
EnforceNicks bool
|
|
||||||
WelcomeMsgs []string
|
// Get is a shortcut for GetString
|
||||||
TwitterConsumerKey string
|
func (c *Config) Get(key string) string {
|
||||||
TwitterConsumerSecret string
|
return c.GetString(key)
|
||||||
TwitterUserKey string
|
|
||||||
TwitterUserSecret string
|
|
||||||
BadMsgs []string
|
|
||||||
Bad struct {
|
|
||||||
Msgs []string
|
|
||||||
Nicks []string
|
|
||||||
Hosts []string
|
|
||||||
}
|
}
|
||||||
Your struct {
|
|
||||||
MaxLength int
|
func envkey(key string) string {
|
||||||
Replacements []Replacement
|
key = strings.ToUpper(key)
|
||||||
|
key = strings.Replace(key, ".", "", -1)
|
||||||
|
return key
|
||||||
}
|
}
|
||||||
LeftPad struct {
|
|
||||||
MaxLen int
|
// GetString returns the config value for a string key
|
||||||
Who string
|
// It will first look in the env vars for the key
|
||||||
|
// It will check the DB for the key if an env DNE
|
||||||
|
// Finally, it will return a zero value if the key does not exist
|
||||||
|
// It will convert the value to a string if it exists
|
||||||
|
func (c *Config) GetString(key string) string {
|
||||||
|
key = strings.ToLower(key)
|
||||||
|
if v, found := os.LookupEnv(envkey(key)); found {
|
||||||
|
return v
|
||||||
}
|
}
|
||||||
Factoid struct {
|
var configValue string
|
||||||
MinLen int
|
q := `select value from config where key=?`
|
||||||
QuoteChance float64
|
err := c.DB.Get(&configValue, q, key)
|
||||||
QuoteTime int
|
if err != nil {
|
||||||
StartupFact string
|
log.Printf("WARN: Key %s is empty", key)
|
||||||
|
return ""
|
||||||
}
|
}
|
||||||
Babbler struct {
|
return configValue
|
||||||
DefaultUsers []string
|
|
||||||
}
|
}
|
||||||
Reminder struct {
|
|
||||||
MaxBatchAdd int
|
// GetArray returns the string slice config value for a string key
|
||||||
|
// It will first look in the env vars for the key with ;; separated values
|
||||||
|
// Look, I'm too lazy to do parsing to ensure that a comma is what the user meant
|
||||||
|
// It will check the DB for the key if an env DNE
|
||||||
|
// Finally, it will return a zero value if the key does not exist
|
||||||
|
// This will do no conversion.
|
||||||
|
func (c *Config) GetArray(key string) []string {
|
||||||
|
val := c.GetString(key)
|
||||||
|
if val == "" {
|
||||||
|
return []string{}
|
||||||
}
|
}
|
||||||
Stats struct {
|
return strings.Split(val, ";;")
|
||||||
DBPath string
|
|
||||||
Sightings []string
|
|
||||||
}
|
}
|
||||||
Emojify struct {
|
|
||||||
Chance float64
|
// Set changes the value for a configuration in the database
|
||||||
Scoreless []string
|
// Note, this is always a string. Use the SetArray for an array helper
|
||||||
|
func (c *Config) Set(key, value string) error {
|
||||||
|
key = strings.ToLower(key)
|
||||||
|
q := (`insert into config (key,value) values (?, ?)
|
||||||
|
on conflict(key) do update set value=?;`)
|
||||||
|
tx, err := c.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
Reaction struct {
|
_, err = tx.Exec(q, key, value, value)
|
||||||
GeneralChance float64
|
if err != nil {
|
||||||
HarrassChance float64
|
return err
|
||||||
NegativeHarrassmentMultiplier int
|
|
||||||
HarrassList []string
|
|
||||||
PositiveReactions []string
|
|
||||||
NegativeReactions []string
|
|
||||||
}
|
}
|
||||||
Inventory struct {
|
err = tx.Commit()
|
||||||
Max int
|
if err != nil {
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
Sisyphus struct {
|
return nil
|
||||||
MinDecrement int
|
|
||||||
MaxDecrement int
|
|
||||||
MinPush int
|
|
||||||
MaxPush int
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *Config) SetArray(key string, values []string) error {
|
||||||
|
vals := strings.Join(values, ";;")
|
||||||
|
return c.Set(key, vals)
|
||||||
}
|
}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
|
@ -125,38 +132,31 @@ func init() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
type Replacement struct {
|
|
||||||
This string
|
|
||||||
That string
|
|
||||||
Frequency float64
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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(version, cfile string) *Config {
|
func ReadConfig(dbpath string) *Config {
|
||||||
fmt.Printf("Using %s as config file.\n", cfile)
|
if dbpath == "" {
|
||||||
L := lua.NewState()
|
dbpath = "catbase.db"
|
||||||
if err := L.DoFile(cfile); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
|
fmt.Printf("Using %s as database file.\n", dbpath)
|
||||||
|
|
||||||
var c Config
|
sqlDB, err := sqlx.Open("sqlite3_custom", dbpath)
|
||||||
if err := gluamapper.Map(L.GetGlobal("config").(*lua.LTable), &c); err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
c.Version = version
|
|
||||||
|
|
||||||
if c.Type == "" {
|
|
||||||
c.Type = "irc"
|
|
||||||
}
|
|
||||||
|
|
||||||
fmt.Printf("godeepintir version %s running.\n", c.Version)
|
|
||||||
|
|
||||||
sqlDB, err := sqlx.Open("sqlite3_custom", c.DB.File)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
c.DBConn = sqlDB
|
c := Config{
|
||||||
|
DBFile: dbpath,
|
||||||
|
}
|
||||||
|
c.DB = sqlDB
|
||||||
|
|
||||||
|
if _, err := c.Exec(`create table if not exists config (
|
||||||
|
key string,
|
||||||
|
value string,
|
||||||
|
primary key (key)
|
||||||
|
);`); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("catbase is running.\n")
|
||||||
|
|
||||||
return &c
|
return &c
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestSetGet(t *testing.T) {
|
||||||
|
cfg := ReadConfig(":memory:")
|
||||||
|
expected := "value"
|
||||||
|
cfg.Set("test", expected)
|
||||||
|
actual := cfg.Get("test")
|
||||||
|
assert.Equal(t, expected, actual, "Config did not store values")
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSetGetArray(t *testing.T) {
|
||||||
|
cfg := ReadConfig(":memory:")
|
||||||
|
expected := []string{"a", "b", "c"}
|
||||||
|
cfg.SetArray("test", expected)
|
||||||
|
actual := cfg.GetArray("test")
|
||||||
|
assert.Equal(t, expected, actual, "Config did not store values")
|
||||||
|
}
|
|
@ -0,0 +1,57 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"html/template"
|
||||||
|
"log"
|
||||||
|
"strings"
|
||||||
|
)
|
||||||
|
|
||||||
|
var q = `
|
||||||
|
INSERT INTO config VALUES('type','slack');
|
||||||
|
INSERT INTO config VALUES('nick','{{.Nick}}');
|
||||||
|
INSERT INTO config VALUES('channels','{{.Channel}}');
|
||||||
|
INSERT INTO config VALUES('factoid.quotetime',30);
|
||||||
|
INSERT INTO config VALUES('reaction.negativereactions','bullshit;;fake;;tableflip;;vomit');
|
||||||
|
INSERT INTO config VALUES('reaction.positivereactions','+1;;authorized;;aw_yeah;;yeah_man;;joy');
|
||||||
|
INSERT INTO config VALUES('reaction.generalchance',0.01);
|
||||||
|
INSERT INTO config VALUES('reaction.harrasschance',0.05);
|
||||||
|
INSERT INTO config VALUES('commandchar','!;;¡');
|
||||||
|
INSERT INTO config VALUES('factoid.startupfact','speed test');
|
||||||
|
INSERT INTO config VALUES('factoid.quotechance',0.99);
|
||||||
|
INSERT INTO config VALUES('factoid.minlen',4);
|
||||||
|
INSERT INTO config VALUES('untappd.channels','{{.Channel}}');
|
||||||
|
INSERT INTO config VALUES('twitch.channels','{{.Channel}}');
|
||||||
|
INSERT INTO config VALUES('twitch.{{.ChannelKey}}.users','drseabass;;phlyingpenguin;;stack5;;geoffwithaj;;msherms;;eaburns;;sheltim;;rathaus;;rcuhljr');
|
||||||
|
INSERT INTO config VALUES('twitch.freq',60);
|
||||||
|
INSERT INTO config VALUES('leftpad.maxlen',50);
|
||||||
|
INSERT INTO config VALUES('untappd.freq',60);
|
||||||
|
INSERT INTO config VALUES('your.replacements.0.freq',1);
|
||||||
|
INSERT INTO config VALUES('your.replacements.0.this','fuck');
|
||||||
|
INSERT INTO config VALUES('your.replacements.0.that','duck');
|
||||||
|
INSERT INTO config VALUES('your.replacements','0;;1;;2');
|
||||||
|
INSERT INTO config VALUES('httpaddr','127.0.0.1:1337');
|
||||||
|
INSERT INTO config VALUES('your.maxlength',140);
|
||||||
|
INSERT INTO config VALUES('init',1);
|
||||||
|
`
|
||||||
|
|
||||||
|
func (c *Config) SetDefaults(mainChannel, nick string) {
|
||||||
|
if nick == mainChannel && nick == "" {
|
||||||
|
log.Fatalf("You must provide a nick and a mainChannel")
|
||||||
|
}
|
||||||
|
t := template.Must(template.New("query").Parse(q))
|
||||||
|
vals := struct {
|
||||||
|
Nick string
|
||||||
|
Channel string
|
||||||
|
ChannelKey string
|
||||||
|
}{
|
||||||
|
nick,
|
||||||
|
mainChannel,
|
||||||
|
strings.ToLower(mainChannel),
|
||||||
|
}
|
||||||
|
var buf bytes.Buffer
|
||||||
|
t.Execute(&buf, vals)
|
||||||
|
c.MustExec(`delete from config;`)
|
||||||
|
c.MustExec(buf.String())
|
||||||
|
log.Println("Configuration initialized.")
|
||||||
|
}
|
14
irc/irc.go
14
irc/irc.go
|
@ -87,7 +87,7 @@ func (i *Irc) SendMessage(channel, message string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
if throttle == nil {
|
if throttle == nil {
|
||||||
ratePerSec := i.config.RatePerSec
|
ratePerSec := i.config.GetInt("RatePerSec")
|
||||||
throttle = time.Tick(time.Second / time.Duration(ratePerSec))
|
throttle = time.Tick(time.Second / time.Duration(ratePerSec))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -136,17 +136,17 @@ func (i *Irc) Serve() error {
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
i.Client, err = irc.DialSSL(
|
i.Client, err = irc.DialSSL(
|
||||||
i.config.Irc.Server,
|
i.config.Get("Irc.Server"),
|
||||||
i.config.Nick,
|
i.config.Get("Nick"),
|
||||||
i.config.FullName,
|
i.config.Get("FullName"),
|
||||||
i.config.Irc.Pass,
|
i.config.Get("Irc.Pass"),
|
||||||
true,
|
true,
|
||||||
)
|
)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("%s", err)
|
return fmt.Errorf("%s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, c := range i.config.Channels {
|
for _, c := range i.config.GetArray("channels") {
|
||||||
i.JoinChannel(c)
|
i.JoinChannel(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -270,7 +270,7 @@ func (i *Irc) buildMessage(inMsg irc.Msg) msg.Message {
|
||||||
}
|
}
|
||||||
|
|
||||||
channel := inMsg.Args[0]
|
channel := inMsg.Args[0]
|
||||||
if channel == i.config.Nick {
|
if channel == i.config.Get("Nick") {
|
||||||
channel = inMsg.Args[0]
|
channel = inMsg.Args[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
34
main.go
34
main.go
|
@ -38,23 +38,47 @@ import (
|
||||||
"github.com/velour/catbase/slack"
|
"github.com/velour/catbase/slack"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
key = flag.String("set", "", "Configuration key to set")
|
||||||
|
val = flag.String("val", "", "Configuration value to set")
|
||||||
|
initDB = flag.Bool("init", false, "Initialize the configuration DB")
|
||||||
|
)
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
rand.Seed(time.Now().Unix())
|
rand.Seed(time.Now().Unix())
|
||||||
|
|
||||||
var cfile = flag.String("config", "config.lua",
|
var dbpath = flag.String("db", "catbase.db",
|
||||||
"Config file to load. (Defaults to config.lua)")
|
"Database file to load. (Defaults to catbase.db)")
|
||||||
flag.Parse() // parses the logging flags.
|
flag.Parse() // parses the logging flags.
|
||||||
|
|
||||||
c := config.Readconfig(Version, *cfile)
|
c := config.ReadConfig(*dbpath)
|
||||||
|
|
||||||
|
if *key != "" && *val != "" {
|
||||||
|
c.Set(*key, *val)
|
||||||
|
log.Printf("Set config %s: %s", *key, *val)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (*initDB && len(flag.Args()) != 2) || (!*initDB && c.GetInt("init") != 1) {
|
||||||
|
log.Fatal(`You must run "catbase -init <channel> <nick>"`)
|
||||||
|
} else if *initDB {
|
||||||
|
c.SetDefaults(flag.Arg(0), flag.Arg(1))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var client bot.Connector
|
var client bot.Connector
|
||||||
|
|
||||||
switch c.Type {
|
t := c.Get("type")
|
||||||
|
if t == "" {
|
||||||
|
c.Set("type", "slack")
|
||||||
|
t = "slack"
|
||||||
|
}
|
||||||
|
switch c.Get("type") {
|
||||||
case "irc":
|
case "irc":
|
||||||
client = irc.New(c)
|
client = irc.New(c)
|
||||||
case "slack":
|
case "slack":
|
||||||
client = slack.New(c)
|
client = slack.New(c)
|
||||||
default:
|
default:
|
||||||
log.Fatalf("Unknown connection type: %s", c.Type)
|
log.Fatalf("Unknown connection type: %s", c.Get("type"))
|
||||||
}
|
}
|
||||||
|
|
||||||
b := bot.New(c, client)
|
b := bot.New(c, client)
|
||||||
|
|
|
@ -13,7 +13,6 @@ import (
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
"github.com/velour/catbase/bot"
|
"github.com/velour/catbase/bot"
|
||||||
"github.com/velour/catbase/bot/msg"
|
"github.com/velour/catbase/bot/msg"
|
||||||
"github.com/velour/catbase/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -25,7 +24,6 @@ var (
|
||||||
type BabblerPlugin struct {
|
type BabblerPlugin struct {
|
||||||
Bot bot.Bot
|
Bot bot.Bot
|
||||||
db *sqlx.DB
|
db *sqlx.DB
|
||||||
config *config.Config
|
|
||||||
WithGoRoutines bool
|
WithGoRoutines bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +91,6 @@ func New(bot bot.Bot) *BabblerPlugin {
|
||||||
plugin := &BabblerPlugin{
|
plugin := &BabblerPlugin{
|
||||||
Bot: bot,
|
Bot: bot,
|
||||||
db: bot.DB(),
|
db: bot.DB(),
|
||||||
config: bot.Config(),
|
|
||||||
WithGoRoutines: true,
|
WithGoRoutines: true,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,13 +28,18 @@ func makeMessage(payload string) msg.Message {
|
||||||
func newBabblerPlugin(mb *bot.MockBot) *BabblerPlugin {
|
func newBabblerPlugin(mb *bot.MockBot) *BabblerPlugin {
|
||||||
bp := New(mb)
|
bp := New(mb)
|
||||||
bp.WithGoRoutines = false
|
bp.WithGoRoutines = false
|
||||||
|
mb.DB().MustExec(`
|
||||||
|
delete from babblers;
|
||||||
|
delete from babblerWords;
|
||||||
|
delete from babblerNodes;
|
||||||
|
delete from babblerArcs;
|
||||||
|
`)
|
||||||
return bp
|
return bp
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBabblerNoBabbler(t *testing.T) {
|
func TestBabblerNoBabbler(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
bp.Message(makeMessage("!seabass2 says"))
|
bp.Message(makeMessage("!seabass2 says"))
|
||||||
res := assert.Len(t, mb.Messages, 0)
|
res := assert.Len(t, mb.Messages, 0)
|
||||||
|
@ -45,7 +50,6 @@ func TestBabblerNoBabbler(t *testing.T) {
|
||||||
func TestBabblerNothingSaid(t *testing.T) {
|
func TestBabblerNothingSaid(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
res := bp.Message(makeMessage("initialize babbler for seabass"))
|
res := bp.Message(makeMessage("initialize babbler for seabass"))
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
|
@ -59,7 +63,6 @@ func TestBabblerNothingSaid(t *testing.T) {
|
||||||
func TestBabbler(t *testing.T) {
|
func TestBabbler(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
seabass := makeMessage("This is a message")
|
seabass := makeMessage("This is a message")
|
||||||
seabass.User = &user.User{Name: "seabass"}
|
seabass.User = &user.User{Name: "seabass"}
|
||||||
|
@ -78,7 +81,6 @@ func TestBabbler(t *testing.T) {
|
||||||
func TestBabblerSeed(t *testing.T) {
|
func TestBabblerSeed(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
seabass := makeMessage("This is a message")
|
seabass := makeMessage("This is a message")
|
||||||
seabass.User = &user.User{Name: "seabass"}
|
seabass.User = &user.User{Name: "seabass"}
|
||||||
|
@ -96,7 +98,6 @@ func TestBabblerSeed(t *testing.T) {
|
||||||
func TestBabblerMultiSeed(t *testing.T) {
|
func TestBabblerMultiSeed(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
seabass := makeMessage("This is a message")
|
seabass := makeMessage("This is a message")
|
||||||
seabass.User = &user.User{Name: "seabass"}
|
seabass.User = &user.User{Name: "seabass"}
|
||||||
|
@ -114,7 +115,6 @@ func TestBabblerMultiSeed(t *testing.T) {
|
||||||
func TestBabblerMultiSeed2(t *testing.T) {
|
func TestBabblerMultiSeed2(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
seabass := makeMessage("This is a message")
|
seabass := makeMessage("This is a message")
|
||||||
seabass.User = &user.User{Name: "seabass"}
|
seabass.User = &user.User{Name: "seabass"}
|
||||||
|
@ -132,7 +132,6 @@ func TestBabblerMultiSeed2(t *testing.T) {
|
||||||
func TestBabblerBadSeed(t *testing.T) {
|
func TestBabblerBadSeed(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
seabass := makeMessage("This is a message")
|
seabass := makeMessage("This is a message")
|
||||||
seabass.User = &user.User{Name: "seabass"}
|
seabass.User = &user.User{Name: "seabass"}
|
||||||
|
@ -149,7 +148,6 @@ func TestBabblerBadSeed(t *testing.T) {
|
||||||
func TestBabblerBadSeed2(t *testing.T) {
|
func TestBabblerBadSeed2(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
seabass := makeMessage("This is a message")
|
seabass := makeMessage("This is a message")
|
||||||
seabass.User = &user.User{Name: "seabass"}
|
seabass.User = &user.User{Name: "seabass"}
|
||||||
|
@ -166,7 +164,6 @@ func TestBabblerBadSeed2(t *testing.T) {
|
||||||
func TestBabblerSuffixSeed(t *testing.T) {
|
func TestBabblerSuffixSeed(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
seabass := makeMessage("This is message one")
|
seabass := makeMessage("This is message one")
|
||||||
seabass.User = &user.User{Name: "seabass"}
|
seabass.User = &user.User{Name: "seabass"}
|
||||||
|
@ -186,7 +183,6 @@ func TestBabblerSuffixSeed(t *testing.T) {
|
||||||
func TestBabblerBadSuffixSeed(t *testing.T) {
|
func TestBabblerBadSuffixSeed(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
seabass := makeMessage("This is message one")
|
seabass := makeMessage("This is message one")
|
||||||
seabass.User = &user.User{Name: "seabass"}
|
seabass.User = &user.User{Name: "seabass"}
|
||||||
|
@ -204,7 +200,6 @@ func TestBabblerBadSuffixSeed(t *testing.T) {
|
||||||
func TestBabblerBookendSeed(t *testing.T) {
|
func TestBabblerBookendSeed(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
seabass := makeMessage("It's easier to test with unique messages")
|
seabass := makeMessage("It's easier to test with unique messages")
|
||||||
seabass.User = &user.User{Name: "seabass"}
|
seabass.User = &user.User{Name: "seabass"}
|
||||||
|
@ -218,7 +213,6 @@ func TestBabblerBookendSeed(t *testing.T) {
|
||||||
func TestBabblerBookendSeedShort(t *testing.T) {
|
func TestBabblerBookendSeedShort(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
seabass := makeMessage("It's easier to test with unique messages")
|
seabass := makeMessage("It's easier to test with unique messages")
|
||||||
seabass.User = &user.User{Name: "seabass"}
|
seabass.User = &user.User{Name: "seabass"}
|
||||||
|
@ -232,7 +226,6 @@ func TestBabblerBookendSeedShort(t *testing.T) {
|
||||||
func TestBabblerBadBookendSeed(t *testing.T) {
|
func TestBabblerBadBookendSeed(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
seabass := makeMessage("It's easier to test with unique messages")
|
seabass := makeMessage("It's easier to test with unique messages")
|
||||||
seabass.User = &user.User{Name: "seabass"}
|
seabass.User = &user.User{Name: "seabass"}
|
||||||
|
@ -246,7 +239,6 @@ func TestBabblerBadBookendSeed(t *testing.T) {
|
||||||
func TestBabblerMiddleOutSeed(t *testing.T) {
|
func TestBabblerMiddleOutSeed(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
seabass := makeMessage("It's easier to test with unique messages")
|
seabass := makeMessage("It's easier to test with unique messages")
|
||||||
seabass.User = &user.User{Name: "seabass"}
|
seabass.User = &user.User{Name: "seabass"}
|
||||||
|
@ -260,7 +252,6 @@ func TestBabblerMiddleOutSeed(t *testing.T) {
|
||||||
func TestBabblerBadMiddleOutSeed(t *testing.T) {
|
func TestBabblerBadMiddleOutSeed(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
seabass := makeMessage("It's easier to test with unique messages")
|
seabass := makeMessage("It's easier to test with unique messages")
|
||||||
seabass.User = &user.User{Name: "seabass"}
|
seabass.User = &user.User{Name: "seabass"}
|
||||||
|
@ -274,7 +265,6 @@ func TestBabblerBadMiddleOutSeed(t *testing.T) {
|
||||||
func TestBabblerBatch(t *testing.T) {
|
func TestBabblerBatch(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
seabass := makeMessage("batch learn for seabass This is a message! This is another message. This is not a long message? This is not a message! This is not another message. This is a long message?")
|
seabass := makeMessage("batch learn for seabass This is a message! This is another message. This is not a long message? This is not a message! This is not another message. This is a long message?")
|
||||||
res := bp.Message(seabass)
|
res := bp.Message(seabass)
|
||||||
|
@ -289,7 +279,6 @@ func TestBabblerBatch(t *testing.T) {
|
||||||
func TestBabblerMerge(t *testing.T) {
|
func TestBabblerMerge(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
bp := newBabblerPlugin(mb)
|
bp := newBabblerPlugin(mb)
|
||||||
bp.config.Babbler.DefaultUsers = []string{"seabass"}
|
|
||||||
assert.NotNil(t, bp)
|
assert.NotNil(t, bp)
|
||||||
|
|
||||||
seabass := makeMessage("<seabass> This is a message")
|
seabass := makeMessage("<seabass> This is a message")
|
||||||
|
|
|
@ -39,7 +39,6 @@ type untappdUser struct {
|
||||||
|
|
||||||
// New BeersPlugin creates a new BeersPlugin with the Plugin interface
|
// New BeersPlugin creates a new BeersPlugin with the Plugin interface
|
||||||
func New(bot bot.Bot) *BeersPlugin {
|
func New(bot bot.Bot) *BeersPlugin {
|
||||||
if bot.DBVersion() == 1 {
|
|
||||||
if _, err := bot.DB().Exec(`create table if not exists untappd (
|
if _, err := bot.DB().Exec(`create table if not exists untappd (
|
||||||
id integer primary key,
|
id integer primary key,
|
||||||
untappdUser string,
|
untappdUser string,
|
||||||
|
@ -49,13 +48,11 @@ func New(bot bot.Bot) *BeersPlugin {
|
||||||
);`); err != nil {
|
);`); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
p := BeersPlugin{
|
p := BeersPlugin{
|
||||||
Bot: bot,
|
Bot: bot,
|
||||||
db: bot.DB(),
|
db: bot.DB(),
|
||||||
}
|
}
|
||||||
p.LoadData()
|
for _, channel := range bot.Config().GetArray("Untappd.Channels") {
|
||||||
for _, channel := range bot.Config().Untappd.Channels {
|
|
||||||
go p.untappdLoop(channel)
|
go p.untappdLoop(channel)
|
||||||
}
|
}
|
||||||
return &p
|
return &p
|
||||||
|
@ -198,13 +195,6 @@ func (p *BeersPlugin) Event(kind string, message msg.Message) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadData imports any configuration data into the plugin. This is not strictly necessary other
|
|
||||||
// than the fact that the Plugin interface demands it exist. This may be deprecated at a later
|
|
||||||
// date.
|
|
||||||
func (p *BeersPlugin) LoadData() {
|
|
||||||
rand.Seed(time.Now().Unix())
|
|
||||||
}
|
|
||||||
|
|
||||||
// Help responds to help requests. Every plugin must implement a help function.
|
// Help responds to help requests. Every plugin must implement a help function.
|
||||||
func (p *BeersPlugin) Help(channel string, parts []string) {
|
func (p *BeersPlugin) Help(channel string, parts []string) {
|
||||||
msg := "Beers: imbibe by using either beers +=,=,++ or with the !imbibe/drink " +
|
msg := "Beers: imbibe by using either beers +=,=,++ or with the !imbibe/drink " +
|
||||||
|
@ -316,7 +306,12 @@ type Beers struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *BeersPlugin) pullUntappd() ([]checkin, error) {
|
func (p *BeersPlugin) pullUntappd() ([]checkin, error) {
|
||||||
access_token := "?access_token=" + p.Bot.Config().Untappd.Token
|
token := p.Bot.Config().Get("Untappd.Token")
|
||||||
|
if token == "" {
|
||||||
|
return []checkin{}, fmt.Errorf("No untappd token")
|
||||||
|
}
|
||||||
|
|
||||||
|
access_token := "?access_token=" + token
|
||||||
baseUrl := "https://api.untappd.com/v4/checkin/recent/"
|
baseUrl := "https://api.untappd.com/v4/checkin/recent/"
|
||||||
|
|
||||||
url := baseUrl + access_token + "&limit=25"
|
url := baseUrl + access_token + "&limit=25"
|
||||||
|
@ -346,9 +341,9 @@ func (p *BeersPlugin) pullUntappd() ([]checkin, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *BeersPlugin) checkUntappd(channel string) {
|
func (p *BeersPlugin) checkUntappd(channel string) {
|
||||||
token := p.Bot.Config().Untappd.Token
|
token := p.Bot.Config().Get("Untappd.Token")
|
||||||
if token == "" || token == "<Your Token>" {
|
if token == "" {
|
||||||
log.Println("No Untappd token, cannot enable plugin.")
|
log.Println(`Set config value "untappd.token" if you wish to enable untappd`)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,7 +426,10 @@ func (p *BeersPlugin) checkUntappd(channel string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *BeersPlugin) untappdLoop(channel string) {
|
func (p *BeersPlugin) untappdLoop(channel string) {
|
||||||
frequency := p.Bot.Config().Untappd.Freq
|
frequency := p.Bot.Config().GetInt("Untappd.Freq")
|
||||||
|
if frequency == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
log.Println("Checking every ", frequency, " seconds")
|
log.Println("Checking every ", frequency, " seconds")
|
||||||
|
|
||||||
|
|
|
@ -29,13 +29,24 @@ func makeMessage(payload string) msg.Message {
|
||||||
func makeBeersPlugin(t *testing.T) (*BeersPlugin, *bot.MockBot) {
|
func makeBeersPlugin(t *testing.T) (*BeersPlugin, *bot.MockBot) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
counter.New(mb)
|
counter.New(mb)
|
||||||
|
mb.DB().MustExec(`delete from counter; delete from counter_alias;`)
|
||||||
b := New(mb)
|
b := New(mb)
|
||||||
assert.NotNil(t, b)
|
|
||||||
b.Message(makeMessage("!mkalias beer :beer:"))
|
b.Message(makeMessage("!mkalias beer :beer:"))
|
||||||
b.Message(makeMessage("!mkalias beers :beer:"))
|
b.Message(makeMessage("!mkalias beers :beer:"))
|
||||||
return b, mb
|
return b, mb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCounter(t *testing.T) {
|
||||||
|
_, mb := makeBeersPlugin(t)
|
||||||
|
i, err := counter.GetItem(mb.DB(), "tester", "test")
|
||||||
|
if !assert.Nil(t, err) {
|
||||||
|
t.Log(err)
|
||||||
|
t.Fatal()
|
||||||
|
}
|
||||||
|
err = i.Update(5)
|
||||||
|
assert.Nil(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
func TestImbibe(t *testing.T) {
|
func TestImbibe(t *testing.T) {
|
||||||
b, mb := makeBeersPlugin(t)
|
b, mb := makeBeersPlugin(t)
|
||||||
b.Message(makeMessage("!imbibe"))
|
b.Message(makeMessage("!imbibe"))
|
||||||
|
|
|
@ -133,6 +133,9 @@ func GetItem(db *sqlx.DB, nick, itemName string) (Item, error) {
|
||||||
func (i *Item) Create() error {
|
func (i *Item) Create() error {
|
||||||
res, err := i.Exec(`insert into counter (nick, item, count) values (?, ?, ?);`,
|
res, err := i.Exec(`insert into counter (nick, item, count) values (?, ?, ?);`,
|
||||||
i.Nick, i.Item, i.Count)
|
i.Nick, i.Item, i.Count)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
id, _ := res.LastInsertId()
|
id, _ := res.LastInsertId()
|
||||||
// hackhackhack?
|
// hackhackhack?
|
||||||
i.ID = id
|
i.ID = id
|
||||||
|
@ -170,21 +173,19 @@ func (i *Item) Delete() error {
|
||||||
|
|
||||||
// NewCounterPlugin creates a new CounterPlugin with the Plugin interface
|
// NewCounterPlugin creates a new CounterPlugin with the Plugin interface
|
||||||
func New(bot bot.Bot) *CounterPlugin {
|
func New(bot bot.Bot) *CounterPlugin {
|
||||||
if _, err := bot.DB().Exec(`create table if not exists counter (
|
tx := bot.DB().MustBegin()
|
||||||
|
bot.DB().MustExec(`create table if not exists counter (
|
||||||
id integer primary key,
|
id integer primary key,
|
||||||
nick string,
|
nick string,
|
||||||
item string,
|
item string,
|
||||||
count integer
|
count integer
|
||||||
);`); err != nil {
|
);`)
|
||||||
log.Fatal(err)
|
bot.DB().MustExec(`create table if not exists counter_alias (
|
||||||
}
|
|
||||||
if _, err := bot.DB().Exec(`create table if not exists counter_alias (
|
|
||||||
id integer PRIMARY KEY AUTOINCREMENT,
|
id integer PRIMARY KEY AUTOINCREMENT,
|
||||||
item string NOT NULL UNIQUE,
|
item string NOT NULL UNIQUE,
|
||||||
points_to string NOT NULL
|
points_to string NOT NULL
|
||||||
);`); err != nil {
|
);`)
|
||||||
log.Fatal(err)
|
tx.Commit()
|
||||||
}
|
|
||||||
return &CounterPlugin{
|
return &CounterPlugin{
|
||||||
Bot: bot,
|
Bot: bot,
|
||||||
DB: bot.DB(),
|
DB: bot.DB(),
|
||||||
|
|
|
@ -16,6 +16,7 @@ import (
|
||||||
func setup(t *testing.T) (*bot.MockBot, *CounterPlugin) {
|
func setup(t *testing.T) (*bot.MockBot, *CounterPlugin) {
|
||||||
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.DB(), "tea", ":tea:")
|
_, err := MkAlias(mb.DB(), "tea", ":tea:")
|
||||||
assert.Nil(t, err)
|
assert.Nil(t, err)
|
||||||
return mb, c
|
return mb, c
|
||||||
|
|
|
@ -34,7 +34,7 @@ func (p *DBPlugin) RegisterWeb() *string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *DBPlugin) serveQuery(w http.ResponseWriter, r *http.Request) {
|
func (p *DBPlugin) serveQuery(w http.ResponseWriter, r *http.Request) {
|
||||||
f, err := os.Open(p.bot.Config().DB.File)
|
f, err := os.Open(p.bot.Config().DBFile)
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error opening DB for web service: %s", err)
|
log.Printf("Error opening DB for web service: %s", err)
|
||||||
|
|
|
@ -107,7 +107,6 @@ func New(bot bot.Bot) *DowntimePlugin {
|
||||||
db: bot.DB(),
|
db: bot.DB(),
|
||||||
}
|
}
|
||||||
|
|
||||||
if bot.DBVersion() == 1 {
|
|
||||||
_, err := p.db.Exec(`create table if not exists downtime (
|
_, err := p.db.Exec(`create table if not exists downtime (
|
||||||
id integer primary key,
|
id integer primary key,
|
||||||
nick string,
|
nick string,
|
||||||
|
@ -116,7 +115,6 @@ func New(bot bot.Bot) *DowntimePlugin {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Error creating downtime table: ", err)
|
log.Fatal("Error creating downtime table: ", err)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return &p
|
return &p
|
||||||
}
|
}
|
||||||
|
@ -161,7 +159,7 @@ func (p *DowntimePlugin) Message(message msg.Message) bool {
|
||||||
for _, e := range entries {
|
for _, e := range entries {
|
||||||
|
|
||||||
// filter out ZNC entries and ourself
|
// filter out ZNC entries and ourself
|
||||||
if strings.HasPrefix(e.nick, "*") || strings.ToLower(p.Bot.Config().Nick) == e.nick {
|
if strings.HasPrefix(e.nick, "*") || strings.ToLower(p.Bot.Config().Get("Nick")) == e.nick {
|
||||||
p.remove(e.nick)
|
p.remove(e.nick)
|
||||||
} else {
|
} else {
|
||||||
tops = fmt.Sprintf("%s%s: %s ", tops, e.nick, time.Now().Sub(e.lastSeen))
|
tops = fmt.Sprintf("%s%s: %s ", tops, e.nick, time.Now().Sub(e.lastSeen))
|
||||||
|
@ -205,7 +203,7 @@ func (p *DowntimePlugin) Help(channel string, parts []string) {
|
||||||
// Empty event handler because this plugin does not do anything on event recv
|
// Empty event handler because this plugin does not do anything on event recv
|
||||||
func (p *DowntimePlugin) Event(kind string, message msg.Message) bool {
|
func (p *DowntimePlugin) Event(kind string, message msg.Message) bool {
|
||||||
log.Println(kind, "\t", message)
|
log.Println(kind, "\t", message)
|
||||||
if kind != "PART" && message.User.Name != p.Bot.Config().Nick {
|
if kind != "PART" && message.User.Name != p.Bot.Config().Get("Nick") {
|
||||||
// user joined, let's nail them for it
|
// user joined, let's nail them for it
|
||||||
if kind == "NICK" {
|
if kind == "NICK" {
|
||||||
p.record(strings.ToLower(message.Channel))
|
p.record(strings.ToLower(message.Channel))
|
||||||
|
|
|
@ -64,7 +64,7 @@ func (p *EmojifyMePlugin) Message(message msg.Message) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inertTokens := p.Bot.Config().Emojify.Scoreless
|
inertTokens := p.Bot.Config().GetArray("Emojify.Scoreless")
|
||||||
emojied := 0.0
|
emojied := 0.0
|
||||||
tokens := strings.Fields(strings.ToLower(message.Body))
|
tokens := strings.Fields(strings.ToLower(message.Body))
|
||||||
for i, token := range tokens {
|
for i, token := range tokens {
|
||||||
|
@ -93,7 +93,7 @@ func (p *EmojifyMePlugin) Message(message msg.Message) bool {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if emojied > 0 && rand.Float64() <= p.Bot.Config().Emojify.Chance*emojied {
|
if emojied > 0 && rand.Float64() <= p.Bot.Config().GetFloat64("Emojify.Chance")*emojied {
|
||||||
modified := strings.Join(tokens, " ")
|
modified := strings.Join(tokens, " ")
|
||||||
p.Bot.SendMessage(message.Channel, modified)
|
p.Bot.SendMessage(message.Channel, modified)
|
||||||
return true
|
return true
|
||||||
|
|
|
@ -297,13 +297,13 @@ func New(botInst bot.Bot) *Factoid {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, channel := range botInst.Config().Channels {
|
for _, channel := range botInst.Config().GetArray("channels") {
|
||||||
go p.factTimer(channel)
|
go p.factTimer(channel)
|
||||||
|
|
||||||
go func(ch string) {
|
go func(ch string) {
|
||||||
// Some random time to start up
|
// Some random time to start up
|
||||||
time.Sleep(time.Duration(15) * time.Second)
|
time.Sleep(time.Duration(15) * time.Second)
|
||||||
if ok, fact := p.findTrigger(p.Bot.Config().Factoid.StartupFact); ok {
|
if ok, fact := p.findTrigger(p.Bot.Config().Get("Factoid.StartupFact")); ok {
|
||||||
p.sayFact(msg.Message{
|
p.sayFact(msg.Message{
|
||||||
Channel: ch,
|
Channel: ch,
|
||||||
Body: "speed test", // BUG: This is defined in the config too
|
Body: "speed test", // BUG: This is defined in the config too
|
||||||
|
@ -430,7 +430,7 @@ func (p *Factoid) sayFact(message msg.Message, fact factoid) {
|
||||||
// trigger checks the message for its fitness to be a factoid and then hauls
|
// trigger checks the message for its fitness to be a factoid and then hauls
|
||||||
// the message off to sayFact for processing if it is in fact a trigger
|
// the message off to sayFact for processing if it is in fact a trigger
|
||||||
func (p *Factoid) trigger(message msg.Message) bool {
|
func (p *Factoid) trigger(message msg.Message) bool {
|
||||||
minLen := p.Bot.Config().Factoid.MinLen
|
minLen := p.Bot.Config().GetInt("Factoid.MinLen")
|
||||||
if len(message.Body) > minLen || message.Command || message.Body == "..." {
|
if len(message.Body) > minLen || message.Command || message.Body == "..." {
|
||||||
if ok, fact := p.findTrigger(message.Body); ok {
|
if ok, fact := p.findTrigger(message.Body); ok {
|
||||||
p.sayFact(message, *fact)
|
p.sayFact(message, *fact)
|
||||||
|
@ -691,7 +691,12 @@ func (p *Factoid) randomFact() *factoid {
|
||||||
|
|
||||||
// factTimer spits out a fact at a given interval and with given probability
|
// factTimer spits out a fact at a given interval and with given probability
|
||||||
func (p *Factoid) factTimer(channel string) {
|
func (p *Factoid) factTimer(channel string) {
|
||||||
duration := time.Duration(p.Bot.Config().Factoid.QuoteTime) * time.Minute
|
quoteTime := p.Bot.Config().GetInt("Factoid.QuoteTime")
|
||||||
|
if quoteTime == 0 {
|
||||||
|
quoteTime = 30
|
||||||
|
p.Bot.Config().Set("Factoid.QuoteTime", "30")
|
||||||
|
}
|
||||||
|
duration := time.Duration(quoteTime) * time.Minute
|
||||||
myLastMsg := time.Now()
|
myLastMsg := time.Now()
|
||||||
for {
|
for {
|
||||||
time.Sleep(time.Duration(5) * time.Second) // why 5?
|
time.Sleep(time.Duration(5) * time.Second) // why 5?
|
||||||
|
@ -705,7 +710,12 @@ func (p *Factoid) factTimer(channel string) {
|
||||||
tdelta := time.Since(lastmsg.Time)
|
tdelta := time.Since(lastmsg.Time)
|
||||||
earlier := time.Since(myLastMsg) > tdelta
|
earlier := time.Since(myLastMsg) > tdelta
|
||||||
chance := rand.Float64()
|
chance := rand.Float64()
|
||||||
success := chance < p.Bot.Config().Factoid.QuoteChance
|
quoteChance := p.Bot.Config().GetFloat64("Factoid.QuoteChance")
|
||||||
|
if quoteChance == 0.0 {
|
||||||
|
quoteChance = 0.99
|
||||||
|
p.Bot.Config().Set("Factoid.QuoteChance", "0.99")
|
||||||
|
}
|
||||||
|
success := chance < quoteChance
|
||||||
|
|
||||||
if success && tdelta > duration && earlier {
|
if success && tdelta > duration && earlier {
|
||||||
fact := p.randomFact()
|
fact := p.randomFact()
|
||||||
|
|
|
@ -48,7 +48,6 @@ func (fe *FirstEntry) save(db *sqlx.DB) error {
|
||||||
|
|
||||||
// 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 {
|
||||||
if b.DBVersion() == 1 {
|
|
||||||
_, err := b.DB().Exec(`create table if not exists first (
|
_, err := b.DB().Exec(`create table if not exists first (
|
||||||
id integer primary key,
|
id integer primary key,
|
||||||
day integer,
|
day integer,
|
||||||
|
@ -59,7 +58,6 @@ func New(b bot.Bot) *FirstPlugin {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatal("Could not create first table: ", err)
|
log.Fatal("Could not create first table: ", err)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
log.Println("First plugin initialized with day:", midnight(time.Now()))
|
log.Println("First plugin initialized with day:", midnight(time.Now()))
|
||||||
|
|
||||||
|
@ -152,7 +150,7 @@ func (p *FirstPlugin) Message(message msg.Message) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *FirstPlugin) allowed(message msg.Message) bool {
|
func (p *FirstPlugin) allowed(message msg.Message) bool {
|
||||||
for _, msg := range p.Bot.Config().Bad.Msgs {
|
for _, msg := range p.Bot.Config().GetArray("Bad.Msgs") {
|
||||||
match, err := regexp.MatchString(msg, strings.ToLower(message.Body))
|
match, err := regexp.MatchString(msg, strings.ToLower(message.Body))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Println("Bad regexp: ", err)
|
log.Println("Bad regexp: ", err)
|
||||||
|
@ -162,13 +160,13 @@ func (p *FirstPlugin) allowed(message msg.Message) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, host := range p.Bot.Config().Bad.Hosts {
|
for _, host := range p.Bot.Config().GetArray("Bad.Hosts") {
|
||||||
if host == message.Host {
|
if host == message.Host {
|
||||||
log.Println("Disallowing first: ", message.User.Name, ":", message.Body)
|
log.Println("Disallowing first: ", message.User.Name, ":", message.Body)
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for _, nick := range p.Bot.Config().Bad.Nicks {
|
for _, nick := range p.Bot.Config().GetArray("Bad.Nicks") {
|
||||||
if nick == message.User.Name {
|
if nick == message.User.Name {
|
||||||
log.Println("Disallowing first: ", message.User.Name, ":", message.Body)
|
log.Println("Disallowing first: ", message.User.Name, ":", message.Body)
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"log"
|
"log"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/jmoiron/sqlx"
|
"github.com/jmoiron/sqlx"
|
||||||
|
@ -26,15 +27,16 @@ type InventoryPlugin struct {
|
||||||
// New creates a new InventoryPlugin with the Plugin interface
|
// New creates a new InventoryPlugin with the Plugin interface
|
||||||
func New(bot bot.Bot) *InventoryPlugin {
|
func New(bot bot.Bot) *InventoryPlugin {
|
||||||
config := bot.Config()
|
config := bot.Config()
|
||||||
|
nick := config.Get("nick")
|
||||||
r1, err := regexp.Compile("take this (.+)")
|
r1, err := regexp.Compile("take this (.+)")
|
||||||
checkerr(err)
|
checkerr(err)
|
||||||
r2, err := regexp.Compile("have a (.+)")
|
r2, err := regexp.Compile("have a (.+)")
|
||||||
checkerr(err)
|
checkerr(err)
|
||||||
r3, err := regexp.Compile(fmt.Sprintf("puts (.+) in %s([^a-zA-Z].*)?", config.Nick))
|
r3, err := regexp.Compile(fmt.Sprintf("puts (.+) in %s([^a-zA-Z].*)?", nick))
|
||||||
checkerr(err)
|
checkerr(err)
|
||||||
r4, err := regexp.Compile(fmt.Sprintf("gives %s (.+)", config.Nick))
|
r4, err := regexp.Compile(fmt.Sprintf("gives %s (.+)", nick))
|
||||||
checkerr(err)
|
checkerr(err)
|
||||||
r5, err := regexp.Compile(fmt.Sprintf("gives (.+) to %s([^a-zA-Z].*)?", config.Nick))
|
r5, err := regexp.Compile(fmt.Sprintf("gives (.+) to %s([^a-zA-Z].*)?", nick))
|
||||||
checkerr(err)
|
checkerr(err)
|
||||||
|
|
||||||
p := InventoryPlugin{
|
p := InventoryPlugin{
|
||||||
|
@ -200,7 +202,12 @@ func (p *InventoryPlugin) addItem(m msg.Message, i string) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
var removed string
|
var removed string
|
||||||
if p.count() > p.config.Inventory.Max {
|
max := p.config.GetInt("inventory.max")
|
||||||
|
if max == 0 {
|
||||||
|
max = 10
|
||||||
|
p.config.Set("inventory.max", strconv.Itoa(max))
|
||||||
|
}
|
||||||
|
if p.count() > max {
|
||||||
removed = p.removeRandom()
|
removed = p.removeRandom()
|
||||||
}
|
}
|
||||||
_, err := p.Exec(`INSERT INTO inventory (item) values (?)`, i)
|
_, err := p.Exec(`INSERT INTO inventory (item) values (?)`, i)
|
||||||
|
|
|
@ -45,8 +45,13 @@ func (p *LeftpadPlugin) Message(message msg.Message) bool {
|
||||||
p.bot.SendMessage(message.Channel, "Invalid padding number")
|
p.bot.SendMessage(message.Channel, "Invalid padding number")
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
if length > p.config.LeftPad.MaxLen && p.config.LeftPad.MaxLen > 0 {
|
maxLen, who := p.config.GetInt("LeftPad.MaxLen"), p.config.Get("LeftPad.Who")
|
||||||
msg := fmt.Sprintf("%s would kill me if I did that.", p.config.LeftPad.Who)
|
if who == "" {
|
||||||
|
who = "Putin"
|
||||||
|
p.config.Set("LeftPad.MaxLen", who)
|
||||||
|
}
|
||||||
|
if length > maxLen && maxLen > 0 {
|
||||||
|
msg := fmt.Sprintf("%s would kill me if I did that.", p.config.Get("LeftPad.Who"))
|
||||||
p.bot.SendMessage(message.Channel, msg)
|
p.bot.SendMessage(message.Channel, msg)
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,6 +31,7 @@ func makePlugin(t *testing.T) (*LeftpadPlugin, *bot.MockBot) {
|
||||||
counter.New(mb)
|
counter.New(mb)
|
||||||
p := New(mb)
|
p := New(mb)
|
||||||
assert.NotNil(t, p)
|
assert.NotNil(t, p)
|
||||||
|
p.config.Set("LeftPad.MaxLen", "0")
|
||||||
return p, mb
|
return p, mb
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,6 +57,7 @@ func TestNotCommand(t *testing.T) {
|
||||||
|
|
||||||
func TestNoMaxLen(t *testing.T) {
|
func TestNoMaxLen(t *testing.T) {
|
||||||
p, mb := makePlugin(t)
|
p, mb := makePlugin(t)
|
||||||
|
p.config.Set("LeftPad.MaxLen", "0")
|
||||||
p.Message(makeMessage("!leftpad dicks 100 dicks"))
|
p.Message(makeMessage("!leftpad dicks 100 dicks"))
|
||||||
assert.Len(t, mb.Messages, 1)
|
assert.Len(t, mb.Messages, 1)
|
||||||
assert.Contains(t, mb.Messages[0], "dicks")
|
assert.Contains(t, mb.Messages[0], "dicks")
|
||||||
|
@ -63,7 +65,8 @@ func TestNoMaxLen(t *testing.T) {
|
||||||
|
|
||||||
func Test50Padding(t *testing.T) {
|
func Test50Padding(t *testing.T) {
|
||||||
p, mb := makePlugin(t)
|
p, mb := makePlugin(t)
|
||||||
p.config.LeftPad.MaxLen = 50
|
p.config.Set("LeftPad.MaxLen", "50")
|
||||||
|
assert.Equal(t, 50, p.config.GetInt("LeftPad.MaxLen"))
|
||||||
p.Message(makeMessage("!leftpad dicks 100 dicks"))
|
p.Message(makeMessage("!leftpad dicks 100 dicks"))
|
||||||
assert.Len(t, mb.Messages, 1)
|
assert.Len(t, mb.Messages, 1)
|
||||||
assert.Contains(t, mb.Messages[0], "kill me")
|
assert.Contains(t, mb.Messages[0], "kill me")
|
||||||
|
@ -71,7 +74,7 @@ func Test50Padding(t *testing.T) {
|
||||||
|
|
||||||
func TestUnder50Padding(t *testing.T) {
|
func TestUnder50Padding(t *testing.T) {
|
||||||
p, mb := makePlugin(t)
|
p, mb := makePlugin(t)
|
||||||
p.config.LeftPad.MaxLen = 50
|
p.config.Set("LeftPad.MaxLen", "50")
|
||||||
p.Message(makeMessage("!leftpad dicks 49 dicks"))
|
p.Message(makeMessage("!leftpad dicks 49 dicks"))
|
||||||
assert.Len(t, mb.Messages, 1)
|
assert.Len(t, mb.Messages, 1)
|
||||||
assert.Contains(t, mb.Messages[0], "dicks")
|
assert.Contains(t, mb.Messages[0], "dicks")
|
||||||
|
|
|
@ -24,23 +24,23 @@ func New(bot bot.Bot) *ReactionPlugin {
|
||||||
|
|
||||||
func (p *ReactionPlugin) Message(message msg.Message) bool {
|
func (p *ReactionPlugin) Message(message msg.Message) bool {
|
||||||
harrass := false
|
harrass := false
|
||||||
for _, nick := range p.Config.Reaction.HarrassList {
|
for _, nick := range p.Config.GetArray("Reaction.HarrassList") {
|
||||||
if message.User.Name == nick {
|
if message.User.Name == nick {
|
||||||
harrass = true
|
harrass = true
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
chance := p.Config.Reaction.GeneralChance
|
chance := p.Config.GetFloat64("Reaction.GeneralChance")
|
||||||
negativeWeight := 1
|
negativeWeight := 1
|
||||||
if harrass {
|
if harrass {
|
||||||
chance = p.Config.Reaction.HarrassChance
|
chance = p.Config.GetFloat64("Reaction.HarrassChance")
|
||||||
negativeWeight = p.Config.Reaction.NegativeHarrassmentMultiplier
|
negativeWeight = p.Config.GetInt("Reaction.NegativeHarrassmentMultiplier")
|
||||||
}
|
}
|
||||||
|
|
||||||
if rand.Float64() < chance {
|
if rand.Float64() < chance {
|
||||||
numPositiveReactions := len(p.Config.Reaction.PositiveReactions)
|
numPositiveReactions := len(p.Config.GetArray("Reaction.PositiveReactions"))
|
||||||
numNegativeReactions := len(p.Config.Reaction.NegativeReactions)
|
numNegativeReactions := len(p.Config.GetArray("Reaction.NegativeReactions"))
|
||||||
|
|
||||||
maxIndex := numPositiveReactions + numNegativeReactions*negativeWeight
|
maxIndex := numPositiveReactions + numNegativeReactions*negativeWeight
|
||||||
|
|
||||||
|
@ -49,11 +49,11 @@ func (p *ReactionPlugin) Message(message msg.Message) bool {
|
||||||
reaction := ""
|
reaction := ""
|
||||||
|
|
||||||
if index < numPositiveReactions {
|
if index < numPositiveReactions {
|
||||||
reaction = p.Config.Reaction.PositiveReactions[index]
|
reaction = p.Config.GetArray("Reaction.PositiveReactions")[index]
|
||||||
} else {
|
} else {
|
||||||
index -= numPositiveReactions
|
index -= numPositiveReactions
|
||||||
index %= numNegativeReactions
|
index %= numNegativeReactions
|
||||||
reaction = p.Config.Reaction.NegativeReactions[index]
|
reaction = p.Config.GetArray("Reaction.NegativeReactions")[index]
|
||||||
}
|
}
|
||||||
|
|
||||||
p.Bot.React(message.Channel, reaction, message)
|
p.Bot.React(message.Channel, reaction, message)
|
||||||
|
|
|
@ -40,7 +40,6 @@ type Reminder struct {
|
||||||
|
|
||||||
func New(bot bot.Bot) *ReminderPlugin {
|
func New(bot bot.Bot) *ReminderPlugin {
|
||||||
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
log.SetFlags(log.LstdFlags | log.Lshortfile)
|
||||||
if bot.DBVersion() == 1 {
|
|
||||||
if _, err := bot.DB().Exec(`create table if not exists reminders (
|
if _, err := bot.DB().Exec(`create table if not exists reminders (
|
||||||
id integer primary key,
|
id integer primary key,
|
||||||
fromWho string,
|
fromWho string,
|
||||||
|
@ -51,7 +50,6 @@ func New(bot bot.Bot) *ReminderPlugin {
|
||||||
);`); err != nil {
|
);`); err != nil {
|
||||||
log.Fatal(err)
|
log.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
dur, _ := time.ParseDuration("1h")
|
dur, _ := time.ParseDuration("1h")
|
||||||
timer := time.NewTimer(dur)
|
timer := time.NewTimer(dur)
|
||||||
|
@ -124,7 +122,12 @@ func (p *ReminderPlugin) Message(message msg.Message) bool {
|
||||||
what := strings.Join(parts[6:], " ")
|
what := strings.Join(parts[6:], " ")
|
||||||
|
|
||||||
for i := 0; when.Before(endTime); i++ {
|
for i := 0; when.Before(endTime); i++ {
|
||||||
if i >= p.config.Reminder.MaxBatchAdd {
|
max := p.config.GetInt("Reminder.MaxBatchAdd")
|
||||||
|
if max == 0 {
|
||||||
|
max = 10
|
||||||
|
p.config.Set("reminder.maxbatchadd", strconv.Itoa(max))
|
||||||
|
}
|
||||||
|
if i >= max {
|
||||||
p.Bot.SendMessage(channel, "Easy cowboy, that's a lot of reminders. I'll add some of them.")
|
p.Bot.SendMessage(channel, "Easy cowboy, that's a lot of reminders. I'll add some of them.")
|
||||||
doConfirm = false
|
doConfirm = false
|
||||||
break
|
break
|
||||||
|
|
|
@ -40,10 +40,15 @@ func makeMessageBy(payload, by string) msg.Message {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestMeReminder(t *testing.T) {
|
func setup(t *testing.T) (*ReminderPlugin, *bot.MockBot) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
c := New(mb)
|
r := New(mb)
|
||||||
assert.NotNil(t, c)
|
mb.DB().MustExec(`delete from reminders; delete from config;`)
|
||||||
|
return r, mb
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestMeReminder(t *testing.T) {
|
||||||
|
c, mb := setup(t)
|
||||||
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)
|
||||||
|
@ -53,9 +58,7 @@ func TestMeReminder(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReminder(t *testing.T) {
|
func TestReminder(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, mb := setup(t)
|
||||||
c := New(mb)
|
|
||||||
assert.NotNil(t, c)
|
|
||||||
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)
|
||||||
|
@ -65,9 +68,7 @@ func TestReminder(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReminderReorder(t *testing.T) {
|
func TestReminderReorder(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, mb := setup(t)
|
||||||
c := New(mb)
|
|
||||||
assert.NotNil(t, c)
|
|
||||||
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"))
|
||||||
|
@ -81,9 +82,7 @@ func TestReminderReorder(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReminderParse(t *testing.T) {
|
func TestReminderParse(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, mb := setup(t)
|
||||||
c := New(mb)
|
|
||||||
assert.NotNil(t, c)
|
|
||||||
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)
|
||||||
|
@ -91,9 +90,7 @@ func TestReminderParse(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEmptyList(t *testing.T) {
|
func TestEmptyList(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, mb := setup(t)
|
||||||
c := New(mb)
|
|
||||||
assert.NotNil(t, c)
|
|
||||||
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)
|
||||||
|
@ -101,9 +98,7 @@ func TestEmptyList(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestList(t *testing.T) {
|
func TestList(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, mb := setup(t)
|
||||||
c := New(mb)
|
|
||||||
assert.NotNil(t, c)
|
|
||||||
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"))
|
||||||
|
@ -116,9 +111,7 @@ func TestList(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestListBy(t *testing.T) {
|
func TestListBy(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, mb := setup(t)
|
||||||
c := New(mb)
|
|
||||||
assert.NotNil(t, c)
|
|
||||||
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"))
|
||||||
|
@ -131,9 +124,7 @@ func TestListBy(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestListTo(t *testing.T) {
|
func TestListTo(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, mb := setup(t)
|
||||||
c := New(mb)
|
|
||||||
assert.NotNil(t, c)
|
|
||||||
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"))
|
||||||
|
@ -146,9 +137,7 @@ func TestListTo(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestToEmptyList(t *testing.T) {
|
func TestToEmptyList(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, mb := setup(t)
|
||||||
c := New(mb)
|
|
||||||
assert.NotNil(t, c)
|
|
||||||
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"))
|
||||||
|
@ -160,9 +149,7 @@ func TestToEmptyList(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestFromEmptyList(t *testing.T) {
|
func TestFromEmptyList(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, mb := setup(t)
|
||||||
c := New(mb)
|
|
||||||
assert.NotNil(t, c)
|
|
||||||
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"))
|
||||||
|
@ -173,24 +160,9 @@ func TestFromEmptyList(t *testing.T) {
|
||||||
assert.Contains(t, mb.Messages[2], "no pending reminders")
|
assert.Contains(t, mb.Messages[2], "no pending reminders")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBatch(t *testing.T) {
|
|
||||||
mb := bot.NewMockBot()
|
|
||||||
c := New(mb)
|
|
||||||
c.config.Reminder.MaxBatchAdd = 50
|
|
||||||
assert.NotNil(t, c)
|
|
||||||
res := c.Message(makeMessage("!remind testuser every 1ms for 5ms yikes"))
|
|
||||||
assert.True(t, res)
|
|
||||||
time.Sleep(2 * time.Second)
|
|
||||||
assert.Len(t, mb.Messages, 6)
|
|
||||||
for i := 0; i < 5; i++ {
|
|
||||||
assert.Contains(t, mb.Messages[i+1], "Hey testuser, tester wanted you to be reminded: yikes")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBatchMax(t *testing.T) {
|
func TestBatchMax(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, mb := setup(t)
|
||||||
c := New(mb)
|
c.config.Set("Reminder.MaxBatchAdd", "10")
|
||||||
c.config.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"))
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
|
@ -206,8 +178,7 @@ func TestBatchMax(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCancel(t *testing.T) {
|
func TestCancel(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, mb := setup(t)
|
||||||
c := New(mb)
|
|
||||||
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)
|
||||||
|
@ -222,8 +193,7 @@ func TestCancel(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestCancelMiss(t *testing.T) {
|
func TestCancelMiss(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, mb := setup(t)
|
||||||
c := New(mb)
|
|
||||||
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)
|
||||||
|
@ -232,30 +202,26 @@ func TestCancelMiss(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHelp(t *testing.T) {
|
func TestHelp(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, mb := setup(t)
|
||||||
c := New(mb)
|
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
c.Help("channel", []string{})
|
c.Help("channel", []string{})
|
||||||
assert.Len(t, mb.Messages, 1)
|
assert.Len(t, mb.Messages, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestBotMessage(t *testing.T) {
|
func TestBotMessage(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, _ := setup(t)
|
||||||
c := New(mb)
|
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
assert.False(t, c.BotMessage(makeMessage("test")))
|
assert.False(t, c.BotMessage(makeMessage("test")))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestEvent(t *testing.T) {
|
func TestEvent(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, _ := setup(t)
|
||||||
c := New(mb)
|
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
assert.False(t, c.Event("dummy", makeMessage("test")))
|
assert.False(t, c.Event("dummy", makeMessage("test")))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRegisterWeb(t *testing.T) {
|
func TestRegisterWeb(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, _ := setup(t)
|
||||||
c := New(mb)
|
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
assert.Nil(t, c.RegisterWeb())
|
assert.Nil(t, c.RegisterWeb())
|
||||||
}
|
}
|
||||||
|
|
|
@ -136,7 +136,7 @@ func (p *RPGPlugin) RegisterWeb() *string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *RPGPlugin) ReplyMessage(message msg.Message, identifier string) bool {
|
func (p *RPGPlugin) ReplyMessage(message msg.Message, identifier string) bool {
|
||||||
if strings.ToLower(message.User.Name) != strings.ToLower(p.Bot.Config().Nick) {
|
if strings.ToLower(message.User.Name) != strings.ToLower(p.Bot.Config().Get("Nick")) {
|
||||||
if b, ok := p.listenFor[identifier]; ok {
|
if b, ok := p.listenFor[identifier]; ok {
|
||||||
|
|
||||||
var res int
|
var res int
|
||||||
|
|
|
@ -59,8 +59,14 @@ func (g *game) scheduleDecrement() {
|
||||||
if g.timers[0] != nil {
|
if g.timers[0] != nil {
|
||||||
g.timers[0].Stop()
|
g.timers[0].Stop()
|
||||||
}
|
}
|
||||||
minDec := g.bot.Config().Sisyphus.MinDecrement
|
minDec := g.bot.Config().GetInt("Sisyphus.MinDecrement")
|
||||||
maxDec := g.bot.Config().Sisyphus.MinDecrement
|
maxDec := g.bot.Config().GetInt("Sisyphus.MaxDecrement")
|
||||||
|
if maxDec == minDec && maxDec == 0 {
|
||||||
|
maxDec = 30
|
||||||
|
minDec = 10
|
||||||
|
g.bot.Config().Set("Sisyphus.MinDecrement", strconv.Itoa(minDec))
|
||||||
|
g.bot.Config().Set("Sisyphus.MaxDecrement", strconv.Itoa(maxDec))
|
||||||
|
}
|
||||||
g.nextDec = time.Now().Add(time.Duration((minDec + rand.Intn(maxDec))) * time.Minute)
|
g.nextDec = time.Now().Add(time.Duration((minDec + rand.Intn(maxDec))) * time.Minute)
|
||||||
go func() {
|
go func() {
|
||||||
t := time.NewTimer(g.nextDec.Sub(time.Now()))
|
t := time.NewTimer(g.nextDec.Sub(time.Now()))
|
||||||
|
@ -76,8 +82,14 @@ func (g *game) schedulePush() {
|
||||||
if g.timers[1] != nil {
|
if g.timers[1] != nil {
|
||||||
g.timers[1].Stop()
|
g.timers[1].Stop()
|
||||||
}
|
}
|
||||||
minPush := g.bot.Config().Sisyphus.MinPush
|
minPush := g.bot.Config().GetInt("Sisyphus.MinPush")
|
||||||
maxPush := g.bot.Config().Sisyphus.MaxPush
|
maxPush := g.bot.Config().GetInt("Sisyphus.MaxPush")
|
||||||
|
if minPush == maxPush && maxPush == 0 {
|
||||||
|
minPush = 1
|
||||||
|
maxPush = 10
|
||||||
|
g.bot.Config().Set("Sisyphus.MinPush", strconv.Itoa(minPush))
|
||||||
|
g.bot.Config().Set("Sisyphus.MaxPush", strconv.Itoa(maxPush))
|
||||||
|
}
|
||||||
g.nextPush = time.Now().Add(time.Duration(rand.Intn(maxPush)+minPush) * time.Minute)
|
g.nextPush = time.Now().Add(time.Duration(rand.Intn(maxPush)+minPush) * time.Minute)
|
||||||
go func() {
|
go func() {
|
||||||
t := time.NewTimer(g.nextPush.Sub(time.Now()))
|
t := time.NewTimer(g.nextPush.Sub(time.Now()))
|
||||||
|
@ -195,7 +207,7 @@ func (p *SisyphusPlugin) RegisterWeb() *string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *SisyphusPlugin) ReplyMessage(message msg.Message, identifier string) bool {
|
func (p *SisyphusPlugin) ReplyMessage(message msg.Message, identifier string) bool {
|
||||||
if strings.ToLower(message.User.Name) != strings.ToLower(p.Bot.Config().Nick) {
|
if strings.ToLower(message.User.Name) != strings.ToLower(p.Bot.Config().Get("Nick")) {
|
||||||
if g, ok := p.listenFor[identifier]; ok {
|
if g, ok := p.listenFor[identifier]; ok {
|
||||||
|
|
||||||
log.Printf("got message on %s: %+v", identifier, message)
|
log.Printf("got message on %s: %+v", identifier, message)
|
||||||
|
|
|
@ -1,279 +0,0 @@
|
||||||
// © 2016 the CatBase Authors under the WTFPL license. See AUTHORS for the list of authors.
|
|
||||||
|
|
||||||
// Stats contains the plugin that allows the bot record chat statistics
|
|
||||||
package stats
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"log"
|
|
||||||
"net/http"
|
|
||||||
"os"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/boltdb/bolt"
|
|
||||||
"github.com/velour/catbase/bot"
|
|
||||||
"github.com/velour/catbase/bot/msg"
|
|
||||||
"github.com/velour/catbase/config"
|
|
||||||
)
|
|
||||||
|
|
||||||
const (
|
|
||||||
DayFormat = "2006-01-02"
|
|
||||||
HourFormat = "2006-01-02-15"
|
|
||||||
HourBucket = "hour"
|
|
||||||
UserBucket = "user"
|
|
||||||
SightingBucket = "sighting"
|
|
||||||
)
|
|
||||||
|
|
||||||
type StatsPlugin struct {
|
|
||||||
bot bot.Bot
|
|
||||||
config *config.Config
|
|
||||||
}
|
|
||||||
|
|
||||||
// New creates a new StatsPlugin with the Plugin interface
|
|
||||||
func New(bot bot.Bot) *StatsPlugin {
|
|
||||||
p := StatsPlugin{
|
|
||||||
bot: bot,
|
|
||||||
config: bot.Config(),
|
|
||||||
}
|
|
||||||
return &p
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
type stat struct {
|
|
||||||
// date formatted: DayFormat
|
|
||||||
day string
|
|
||||||
// category
|
|
||||||
bucket string
|
|
||||||
// specific unique individual
|
|
||||||
key string
|
|
||||||
val value
|
|
||||||
}
|
|
||||||
|
|
||||||
func mkDay() string {
|
|
||||||
return time.Now().Format(DayFormat)
|
|
||||||
}
|
|
||||||
|
|
||||||
// The value type is here in the future growth case that we might want to put a
|
|
||||||
// struct of more interesting information into the DB
|
|
||||||
type value int
|
|
||||||
|
|
||||||
func (v value) Bytes() ([]byte, error) {
|
|
||||||
b, err := json.Marshal(v)
|
|
||||||
return b, err
|
|
||||||
}
|
|
||||||
|
|
||||||
func valueFromBytes(b []byte) (value, error) {
|
|
||||||
var v value
|
|
||||||
err := json.Unmarshal(b, &v)
|
|
||||||
return v, err
|
|
||||||
}
|
|
||||||
|
|
||||||
type stats []stat
|
|
||||||
|
|
||||||
// mkStat converts raw data to a stat struct
|
|
||||||
// Expected a string representation of the date formatted: DayFormat
|
|
||||||
func mkStat(day string, bucket, key, val []byte) (stat, error) {
|
|
||||||
v, err := valueFromBytes(val)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("mkStat: error getting value from bytes: %s", err)
|
|
||||||
return stat{}, err
|
|
||||||
}
|
|
||||||
return stat{
|
|
||||||
day: day,
|
|
||||||
bucket: string(bucket),
|
|
||||||
key: string(key),
|
|
||||||
val: v,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Another future-proofing function I shouldn't have written
|
|
||||||
func (v value) add(other value) value {
|
|
||||||
return v + other
|
|
||||||
}
|
|
||||||
|
|
||||||
func openDB(path string) (*bolt.DB, error) {
|
|
||||||
db, err := bolt.Open(path, 0600, &bolt.Options{
|
|
||||||
Timeout: 1 * time.Second,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Couldn't open BoltDB for stats (%s): %s", path, err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return db, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// statFromDB takes a location specification and returns the data at that path
|
|
||||||
// Expected a string representation of the date formatted: DayFormat
|
|
||||||
func statFromDB(path, day, bucket, key string) (stat, error) {
|
|
||||||
db, err := openDB(path)
|
|
||||||
if err != nil {
|
|
||||||
return stat{}, err
|
|
||||||
}
|
|
||||||
defer db.Close()
|
|
||||||
buk := []byte(bucket)
|
|
||||||
k := []byte(key)
|
|
||||||
|
|
||||||
tx, err := db.Begin(true)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("statFromDB: Error beginning the Tx")
|
|
||||||
return stat{}, err
|
|
||||||
}
|
|
||||||
defer tx.Rollback()
|
|
||||||
|
|
||||||
d, err := tx.CreateBucketIfNotExists([]byte(day))
|
|
||||||
if err != nil {
|
|
||||||
log.Println("statFromDB: Error creating the bucket")
|
|
||||||
return stat{}, err
|
|
||||||
}
|
|
||||||
b, err := d.CreateBucketIfNotExists(buk)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("statFromDB: Error creating the bucket")
|
|
||||||
return stat{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
v := b.Get(k)
|
|
||||||
|
|
||||||
if err := tx.Commit(); err != nil {
|
|
||||||
log.Println("statFromDB: Error commiting the Tx")
|
|
||||||
return stat{}, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if v == nil {
|
|
||||||
return stat{day, bucket, key, 0}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return mkStat(day, buk, k, v)
|
|
||||||
}
|
|
||||||
|
|
||||||
// toDB takes a stat and records it, adding to the value in the DB if necessary
|
|
||||||
func (s stats) toDB(path string) error {
|
|
||||||
db, err := openDB(path)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
defer db.Close()
|
|
||||||
|
|
||||||
for _, stat := range s {
|
|
||||||
err = db.Update(func(tx *bolt.Tx) error {
|
|
||||||
d, err := tx.CreateBucketIfNotExists([]byte(stat.day))
|
|
||||||
if err != nil {
|
|
||||||
log.Println("toDB: Error creating bucket")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
b, err := d.CreateBucketIfNotExists([]byte(stat.bucket))
|
|
||||||
if err != nil {
|
|
||||||
log.Println("toDB: Error creating bucket")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
valueInDB := b.Get([]byte(stat.key))
|
|
||||||
if valueInDB != nil {
|
|
||||||
val, err := valueFromBytes(valueInDB)
|
|
||||||
if err != nil {
|
|
||||||
log.Println("toDB: Error getting value from bytes")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
stat.val = stat.val.add(val)
|
|
||||||
}
|
|
||||||
|
|
||||||
v, err := stat.val.Bytes()
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if stat.key == "" {
|
|
||||||
log.Println("Keys should not be empty")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
log.Printf("Putting value in: '%s' %b, %+v", stat.key, []byte(stat.key), stat)
|
|
||||||
err = b.Put([]byte(stat.key), v)
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *StatsPlugin) record(message msg.Message) {
|
|
||||||
statGenerators := []func(msg.Message) stats{
|
|
||||||
p.mkUserStat,
|
|
||||||
p.mkHourStat,
|
|
||||||
p.mkChannelStat,
|
|
||||||
p.mkSightingStat,
|
|
||||||
}
|
|
||||||
|
|
||||||
allStats := stats{}
|
|
||||||
|
|
||||||
for _, mk := range statGenerators {
|
|
||||||
stats := mk(message)
|
|
||||||
if stats != nil {
|
|
||||||
allStats = append(allStats, stats...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
allStats.toDB(p.bot.Config().Stats.DBPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *StatsPlugin) Message(message msg.Message) bool {
|
|
||||||
p.record(message)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *StatsPlugin) Event(e string, message msg.Message) bool {
|
|
||||||
p.record(message)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *StatsPlugin) BotMessage(message msg.Message) bool {
|
|
||||||
p.record(message)
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *StatsPlugin) Help(e string, m []string) {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *StatsPlugin) serveQuery(w http.ResponseWriter, r *http.Request) {
|
|
||||||
f, err := os.Open(p.bot.Config().Stats.DBPath)
|
|
||||||
defer f.Close()
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("Error opening DB for web service: %s", err)
|
|
||||||
fmt.Fprintf(w, "Error opening DB")
|
|
||||||
return
|
|
||||||
}
|
|
||||||
http.ServeContent(w, r, "stats.db", time.Now(), f)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *StatsPlugin) RegisterWeb() *string {
|
|
||||||
http.HandleFunc("/stats", p.serveQuery)
|
|
||||||
tmp := "/stats"
|
|
||||||
return &tmp
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *StatsPlugin) mkUserStat(message msg.Message) stats {
|
|
||||||
return stats{stat{mkDay(), UserBucket, message.User.Name, 1}}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *StatsPlugin) mkHourStat(message msg.Message) stats {
|
|
||||||
hr := time.Now().Hour()
|
|
||||||
return stats{stat{mkDay(), HourBucket, strconv.Itoa(hr), 1}}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *StatsPlugin) mkSightingStat(message msg.Message) stats {
|
|
||||||
stats := stats{}
|
|
||||||
for _, name := range p.bot.Config().Stats.Sightings {
|
|
||||||
if strings.Contains(message.Body, name+" sighting") {
|
|
||||||
stats = append(stats, stat{mkDay(), SightingBucket, name, 1})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return stats
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *StatsPlugin) mkChannelStat(message msg.Message) stats {
|
|
||||||
return stats{stat{mkDay(), "channel", message.Channel, 1}}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (p *StatsPlugin) ReplyMessage(message msg.Message, identifier string) bool { return false }
|
|
|
@ -1,290 +0,0 @@
|
||||||
package stats
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"os"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/assert"
|
|
||||||
"github.com/velour/catbase/bot"
|
|
||||||
"github.com/velour/catbase/bot/msg"
|
|
||||||
"github.com/velour/catbase/bot/user"
|
|
||||||
)
|
|
||||||
|
|
||||||
var dbPath = "test.db"
|
|
||||||
|
|
||||||
func TestJSON(t *testing.T) {
|
|
||||||
expected := 5
|
|
||||||
b, err := json.Marshal(expected)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
t.Logf("%+v", expected)
|
|
||||||
t.Log(string(b))
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestValueConversion(t *testing.T) {
|
|
||||||
expected := value(5)
|
|
||||||
|
|
||||||
b, err := expected.Bytes()
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
t.Log(string(b))
|
|
||||||
|
|
||||||
actual, err := valueFromBytes(b)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, actual, expected)
|
|
||||||
}
|
|
||||||
|
|
||||||
func rmDB(t *testing.T) {
|
|
||||||
err := os.Remove(dbPath)
|
|
||||||
if err != nil && !strings.Contains(err.Error(), "no such file or directory") {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWithDB(t *testing.T) {
|
|
||||||
rmDB(t)
|
|
||||||
|
|
||||||
t.Run("TestDBReadWrite", func(t *testing.T) {
|
|
||||||
day := mkDay()
|
|
||||||
bucket := "testBucket"
|
|
||||||
key := "testKey"
|
|
||||||
|
|
||||||
expected := stats{stat{
|
|
||||||
day,
|
|
||||||
bucket,
|
|
||||||
key,
|
|
||||||
1,
|
|
||||||
}}
|
|
||||||
|
|
||||||
err := expected.toDB(dbPath)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
actual, err := statFromDB(dbPath, day, bucket, key)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, actual, expected[0])
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
rmDB(t)
|
|
||||||
|
|
||||||
t.Run("TestDBAddStatInLoop", func(t *testing.T) {
|
|
||||||
day := mkDay()
|
|
||||||
bucket := "testBucket"
|
|
||||||
key := "testKey"
|
|
||||||
expected := value(25)
|
|
||||||
|
|
||||||
statPack := stats{stat{
|
|
||||||
day,
|
|
||||||
bucket,
|
|
||||||
key,
|
|
||||||
5,
|
|
||||||
}}
|
|
||||||
|
|
||||||
for i := 0; i < 5; i++ {
|
|
||||||
err := statPack.toDB(dbPath)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
actual, err := statFromDB(dbPath, day, bucket, key)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, actual.val, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
rmDB(t)
|
|
||||||
|
|
||||||
t.Run("TestDBAddStats", func(t *testing.T) {
|
|
||||||
day := mkDay()
|
|
||||||
bucket := "testBucket"
|
|
||||||
key := "testKey"
|
|
||||||
expected := value(5)
|
|
||||||
|
|
||||||
statPack := stats{}
|
|
||||||
for i := 0; i < 5; i++ {
|
|
||||||
statPack = append(statPack, stat{
|
|
||||||
day,
|
|
||||||
bucket,
|
|
||||||
key,
|
|
||||||
1,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
err := statPack.toDB(dbPath)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
actual, err := statFromDB(dbPath, day, bucket, key)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
assert.Equal(t, actual.val, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
rmDB(t)
|
|
||||||
}
|
|
||||||
|
|
||||||
func makeMessage(payload string) msg.Message {
|
|
||||||
isCmd := strings.HasPrefix(payload, "!")
|
|
||||||
if isCmd {
|
|
||||||
payload = payload[1:]
|
|
||||||
}
|
|
||||||
return msg.Message{
|
|
||||||
User: &user.User{Name: "tester"},
|
|
||||||
Channel: "test",
|
|
||||||
Body: payload,
|
|
||||||
Command: isCmd,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testUserCounter(t *testing.T, count int) {
|
|
||||||
day := mkDay()
|
|
||||||
expected := value(count)
|
|
||||||
mb := bot.NewMockBot()
|
|
||||||
mb.Cfg.Stats.DBPath = dbPath
|
|
||||||
s := New(mb)
|
|
||||||
assert.NotNil(t, s)
|
|
||||||
|
|
||||||
for i := 0; i < count; i++ {
|
|
||||||
s.Message(makeMessage("test"))
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := os.Stat(dbPath)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
stat, err := statFromDB(mb.Config().Stats.DBPath, day, "user", "tester")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
actual := stat.val
|
|
||||||
assert.Equal(t, actual, expected)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestMessages(t *testing.T) {
|
|
||||||
_, err := os.Stat(dbPath)
|
|
||||||
assert.NotNil(t, err)
|
|
||||||
|
|
||||||
t.Run("TestOneUserCounter", func(t *testing.T) {
|
|
||||||
day := mkDay()
|
|
||||||
count := 5
|
|
||||||
expected := value(count)
|
|
||||||
mb := bot.NewMockBot()
|
|
||||||
mb.Cfg.Stats.DBPath = dbPath
|
|
||||||
s := New(mb)
|
|
||||||
assert.NotNil(t, s)
|
|
||||||
|
|
||||||
for i := 0; i < count; i++ {
|
|
||||||
s.Message(makeMessage("test"))
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := os.Stat(dbPath)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
stat, err := statFromDB(mb.Config().Stats.DBPath, day, "user", "tester")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
actual := stat.val
|
|
||||||
assert.Equal(t, actual, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
rmDB(t)
|
|
||||||
|
|
||||||
t.Run("TestTenUserCounter", func(t *testing.T) {
|
|
||||||
day := mkDay()
|
|
||||||
count := 5
|
|
||||||
expected := value(count)
|
|
||||||
mb := bot.NewMockBot()
|
|
||||||
mb.Cfg.Stats.DBPath = dbPath
|
|
||||||
s := New(mb)
|
|
||||||
assert.NotNil(t, s)
|
|
||||||
|
|
||||||
for i := 0; i < count; i++ {
|
|
||||||
s.Message(makeMessage("test"))
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := os.Stat(dbPath)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
stat, err := statFromDB(mb.Config().Stats.DBPath, day, "user", "tester")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
actual := stat.val
|
|
||||||
assert.Equal(t, actual, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
rmDB(t)
|
|
||||||
|
|
||||||
t.Run("TestChannelCounter", func(t *testing.T) {
|
|
||||||
day := mkDay()
|
|
||||||
count := 5
|
|
||||||
expected := value(count)
|
|
||||||
mb := bot.NewMockBot()
|
|
||||||
mb.Cfg.Stats.DBPath = dbPath
|
|
||||||
s := New(mb)
|
|
||||||
assert.NotNil(t, s)
|
|
||||||
|
|
||||||
for i := 0; i < count; i++ {
|
|
||||||
s.Message(makeMessage("test"))
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := os.Stat(dbPath)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
stat, err := statFromDB(mb.Config().Stats.DBPath, day, "channel", "test")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
actual := stat.val
|
|
||||||
assert.Equal(t, actual, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
rmDB(t)
|
|
||||||
|
|
||||||
t.Run("TestSightingCounter", func(t *testing.T) {
|
|
||||||
day := mkDay()
|
|
||||||
count := 5
|
|
||||||
expected := value(count)
|
|
||||||
mb := bot.NewMockBot()
|
|
||||||
|
|
||||||
mb.Cfg.Stats.DBPath = dbPath
|
|
||||||
mb.Cfg.Stats.Sightings = []string{"user", "nobody"}
|
|
||||||
|
|
||||||
s := New(mb)
|
|
||||||
assert.NotNil(t, s)
|
|
||||||
|
|
||||||
for i := 0; i < count; i++ {
|
|
||||||
s.Message(makeMessage("user sighting"))
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := os.Stat(dbPath)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
stat, err := statFromDB(mb.Config().Stats.DBPath, day, "sighting", "user")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
actual := stat.val
|
|
||||||
assert.Equal(t, actual, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
rmDB(t)
|
|
||||||
|
|
||||||
t.Run("TestSightingCounterNoResults", func(t *testing.T) {
|
|
||||||
day := mkDay()
|
|
||||||
count := 5
|
|
||||||
expected := value(0)
|
|
||||||
mb := bot.NewMockBot()
|
|
||||||
|
|
||||||
mb.Cfg.Stats.DBPath = dbPath
|
|
||||||
mb.Cfg.Stats.Sightings = []string{}
|
|
||||||
|
|
||||||
s := New(mb)
|
|
||||||
assert.NotNil(t, s)
|
|
||||||
|
|
||||||
for i := 0; i < count; i++ {
|
|
||||||
s.Message(makeMessage("user sighting"))
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := os.Stat(dbPath)
|
|
||||||
assert.Nil(t, err)
|
|
||||||
|
|
||||||
stat, err := statFromDB(mb.Config().Stats.DBPath, day, "sighting", "user")
|
|
||||||
assert.Nil(t, err)
|
|
||||||
actual := stat.val
|
|
||||||
assert.Equal(t, actual, expected)
|
|
||||||
})
|
|
||||||
|
|
||||||
rmDB(t)
|
|
||||||
}
|
|
|
@ -4,7 +4,6 @@ package talker
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/velour/catbase/bot"
|
"github.com/velour/catbase/bot"
|
||||||
|
@ -41,15 +40,12 @@ var goatse []string = []string{
|
||||||
|
|
||||||
type TalkerPlugin struct {
|
type TalkerPlugin struct {
|
||||||
Bot bot.Bot
|
Bot bot.Bot
|
||||||
enforceNicks bool
|
|
||||||
sayings []string
|
sayings []string
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(bot bot.Bot) *TalkerPlugin {
|
func New(bot bot.Bot) *TalkerPlugin {
|
||||||
return &TalkerPlugin{
|
return &TalkerPlugin{
|
||||||
Bot: bot,
|
Bot: bot,
|
||||||
enforceNicks: bot.Config().EnforceNicks,
|
|
||||||
sayings: bot.Config().WelcomeMsgs,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,13 +77,6 @@ func (p *TalkerPlugin) Message(message msg.Message) bool {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.enforceNicks && len(message.User.Name) != 9 {
|
|
||||||
msg := fmt.Sprintf("Hey %s, we really like to have 9 character nicks because we're crazy OCD and stuff.",
|
|
||||||
message.User.Name)
|
|
||||||
p.Bot.SendMessage(message.Channel, msg)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,14 +86,6 @@ func (p *TalkerPlugin) Help(channel string, parts []string) {
|
||||||
|
|
||||||
// Empty event handler because this plugin does not do anything on event recv
|
// Empty event handler because this plugin does not do anything on event recv
|
||||||
func (p *TalkerPlugin) Event(kind string, message msg.Message) bool {
|
func (p *TalkerPlugin) Event(kind string, message msg.Message) bool {
|
||||||
if kind == "JOIN" && strings.ToLower(message.User.Name) != strings.ToLower(p.Bot.Config().Nick) {
|
|
||||||
if len(p.sayings) == 0 {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
msg := fmt.Sprintf(p.sayings[rand.Intn(len(p.sayings))], message.User.Name)
|
|
||||||
p.Bot.SendMessage(message.Channel, msg)
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -74,47 +74,6 @@ func TestSayCommand(t *testing.T) {
|
||||||
assert.Contains(t, mb.Messages[0], "hello")
|
assert.Contains(t, mb.Messages[0], "hello")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNineChars(t *testing.T) {
|
|
||||||
mb := bot.NewMockBot()
|
|
||||||
c := New(mb)
|
|
||||||
c.enforceNicks = true
|
|
||||||
assert.NotNil(t, c)
|
|
||||||
res := c.Message(makeMessage("hello there"))
|
|
||||||
assert.Len(t, mb.Messages, 1)
|
|
||||||
assert.True(t, res)
|
|
||||||
assert.Contains(t, mb.Messages[0], "OCD")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestWelcome(t *testing.T) {
|
|
||||||
mb := bot.NewMockBot()
|
|
||||||
c := New(mb)
|
|
||||||
c.sayings = []string{"Hi"}
|
|
||||||
assert.NotNil(t, c)
|
|
||||||
res := c.Event("JOIN", makeMessage("hello there"))
|
|
||||||
assert.Len(t, mb.Messages, 1)
|
|
||||||
assert.True(t, res)
|
|
||||||
assert.Contains(t, mb.Messages[0], "Hi")
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNoSayings(t *testing.T) {
|
|
||||||
mb := bot.NewMockBot()
|
|
||||||
c := New(mb)
|
|
||||||
c.sayings = []string{}
|
|
||||||
assert.NotNil(t, c)
|
|
||||||
res := c.Event("JOIN", makeMessage("hello there"))
|
|
||||||
assert.Len(t, mb.Messages, 0)
|
|
||||||
assert.False(t, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestNonJoinEvent(t *testing.T) {
|
|
||||||
mb := bot.NewMockBot()
|
|
||||||
c := New(mb)
|
|
||||||
assert.NotNil(t, c)
|
|
||||||
res := c.Event("SPLURT", makeMessage("hello there"))
|
|
||||||
assert.Len(t, mb.Messages, 0)
|
|
||||||
assert.False(t, res)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestHelp(t *testing.T) {
|
func TestHelp(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
c := New(mb)
|
c := New(mb)
|
||||||
|
|
|
@ -58,8 +58,8 @@ func New(bot bot.Bot) *TwitchPlugin {
|
||||||
twitchList: map[string]*Twitcher{},
|
twitchList: map[string]*Twitcher{},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, users := range p.config.Twitch.Users {
|
for _, ch := range p.config.GetArray("Twitch.Channels") {
|
||||||
for _, twitcherName := range users {
|
for _, twitcherName := range p.config.GetArray("Twitch." + ch + ".Users") {
|
||||||
if _, ok := p.twitchList[twitcherName]; !ok {
|
if _, ok := p.twitchList[twitcherName]; !ok {
|
||||||
p.twitchList[twitcherName] = &Twitcher{
|
p.twitchList[twitcherName] = &Twitcher{
|
||||||
name: twitcherName,
|
name: twitcherName,
|
||||||
|
@ -67,10 +67,7 @@ func New(bot bot.Bot) *TwitchPlugin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
go p.twitchLoop(ch)
|
||||||
|
|
||||||
for channel := range p.config.Twitch.Users {
|
|
||||||
go p.twitchLoop(channel)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return p
|
return p
|
||||||
|
@ -120,9 +117,9 @@ func (p *TwitchPlugin) serveStreaming(w http.ResponseWriter, r *http.Request) {
|
||||||
func (p *TwitchPlugin) Message(message msg.Message) bool {
|
func (p *TwitchPlugin) Message(message msg.Message) bool {
|
||||||
if strings.ToLower(message.Body) == "twitch status" {
|
if strings.ToLower(message.Body) == "twitch status" {
|
||||||
channel := message.Channel
|
channel := message.Channel
|
||||||
if _, ok := p.config.Twitch.Users[channel]; ok {
|
if users := p.config.GetArray("Twitch." + channel + ".Users"); len(users) > 0 {
|
||||||
for _, twitcherName := range p.config.Twitch.Users[channel] {
|
for _, twitcherName := range users {
|
||||||
if _, ok = p.twitchList[twitcherName]; ok {
|
if _, ok := p.twitchList[twitcherName]; ok {
|
||||||
p.checkTwitch(channel, p.twitchList[twitcherName], true)
|
p.checkTwitch(channel, p.twitchList[twitcherName], true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,14 +144,14 @@ func (p *TwitchPlugin) Help(channel string, parts []string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *TwitchPlugin) twitchLoop(channel string) {
|
func (p *TwitchPlugin) twitchLoop(channel string) {
|
||||||
frequency := p.config.Twitch.Freq
|
frequency := p.config.GetInt("Twitch.Freq")
|
||||||
|
|
||||||
log.Println("Checking every ", frequency, " seconds")
|
log.Println("Checking every ", frequency, " seconds")
|
||||||
|
|
||||||
for {
|
for {
|
||||||
time.Sleep(time.Duration(frequency) * time.Second)
|
time.Sleep(time.Duration(frequency) * time.Second)
|
||||||
|
|
||||||
for _, twitcherName := range p.config.Twitch.Users[channel] {
|
for _, twitcherName := range p.config.GetArray("Twitch." + channel + ".Users") {
|
||||||
p.checkTwitch(channel, p.twitchList[twitcherName], false)
|
p.checkTwitch(channel, p.twitchList[twitcherName], false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -200,8 +197,8 @@ func (p *TwitchPlugin) checkTwitch(channel string, twitcher *Twitcher, alwaysPri
|
||||||
|
|
||||||
baseURL.RawQuery = query.Encode()
|
baseURL.RawQuery = query.Encode()
|
||||||
|
|
||||||
cid := p.config.Twitch.ClientID
|
cid := p.config.Get("Twitch.ClientID")
|
||||||
auth := p.config.Twitch.Authorization
|
auth := p.config.Get("Twitch.Authorization")
|
||||||
|
|
||||||
body, ok := getRequest(baseURL.String(), cid, auth)
|
body, ok := getRequest(baseURL.String(), cid, auth)
|
||||||
if !ok {
|
if !ok {
|
||||||
|
|
|
@ -28,7 +28,8 @@ func makeMessage(payload string) msg.Message {
|
||||||
func makeTwitchPlugin(t *testing.T) (*TwitchPlugin, *bot.MockBot) {
|
func makeTwitchPlugin(t *testing.T) (*TwitchPlugin, *bot.MockBot) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
c := New(mb)
|
c := New(mb)
|
||||||
c.config.Twitch.Users = map[string][]string{"test": []string{"drseabass"}}
|
c.config.SetArray("Twitch.Channels", []string{"test"})
|
||||||
|
c.config.SetArray("Twitch.test.Users", []string{"drseabass"})
|
||||||
assert.NotNil(t, c)
|
assert.NotNil(t, c)
|
||||||
|
|
||||||
c.twitchList["drseabass"] = &Twitcher{
|
c.twitchList["drseabass"] = &Twitcher{
|
||||||
|
|
|
@ -4,6 +4,7 @@ package your
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math/rand"
|
"math/rand"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/velour/catbase/bot"
|
"github.com/velour/catbase/bot"
|
||||||
|
@ -28,13 +29,21 @@ func New(bot bot.Bot) *YourPlugin {
|
||||||
// This function returns true if the plugin responds in a meaningful way to the users message.
|
// This function returns true if the plugin responds in a meaningful way to the users message.
|
||||||
// Otherwise, the function returns false and the bot continues execution of other plugins.
|
// Otherwise, the function returns false and the bot continues execution of other plugins.
|
||||||
func (p *YourPlugin) Message(message msg.Message) bool {
|
func (p *YourPlugin) Message(message msg.Message) bool {
|
||||||
if len(message.Body) > p.config.Your.MaxLength {
|
maxLen := p.config.GetInt("your.maxlength")
|
||||||
|
if maxLen == 0 {
|
||||||
|
maxLen = 140
|
||||||
|
p.config.Set("your.maxlength", strconv.Itoa(maxLen))
|
||||||
|
}
|
||||||
|
if len(message.Body) > maxLen {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
msg := message.Body
|
msg := message.Body
|
||||||
for _, replacement := range p.config.Your.Replacements {
|
for _, replacement := range p.config.GetArray("Your.Replacements") {
|
||||||
if rand.Float64() < replacement.Frequency {
|
freq := p.config.GetFloat64("your.replacements." + replacement + ".freq")
|
||||||
r := strings.NewReplacer(replacement.This, replacement.That)
|
this := p.config.Get("your.replacements." + replacement + ".this")
|
||||||
|
that := p.config.Get("your.replacements." + replacement + ".that")
|
||||||
|
if rand.Float64() < freq {
|
||||||
|
r := strings.NewReplacer(this, that)
|
||||||
msg = r.Replace(msg)
|
msg = r.Replace(msg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"github.com/velour/catbase/bot"
|
"github.com/velour/catbase/bot"
|
||||||
"github.com/velour/catbase/bot/msg"
|
"github.com/velour/catbase/bot/msg"
|
||||||
"github.com/velour/catbase/bot/user"
|
"github.com/velour/catbase/bot/user"
|
||||||
"github.com/velour/catbase/config"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func makeMessage(payload string) msg.Message {
|
func makeMessage(payload string) msg.Message {
|
||||||
|
@ -26,46 +25,41 @@ func makeMessage(payload string) msg.Message {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestReplacement(t *testing.T) {
|
func setup(t *testing.T) (*YourPlugin, *bot.MockBot) {
|
||||||
mb := bot.NewMockBot()
|
mb := bot.NewMockBot()
|
||||||
c := New(mb)
|
c := New(mb)
|
||||||
assert.NotNil(t, c)
|
mb.DB().MustExec(`delete from config;`)
|
||||||
c.config.Your.MaxLength = 1000
|
return c, mb
|
||||||
c.config.Your.Replacements = []config.Replacement{
|
|
||||||
config.Replacement{
|
|
||||||
This: "fuck",
|
|
||||||
That: "duck",
|
|
||||||
Frequency: 1.0,
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestReplacement(t *testing.T) {
|
||||||
|
c, mb := setup(t)
|
||||||
|
c.config.Set("Your.MaxLength", "1000")
|
||||||
|
c.config.SetArray("your.replacements", []string{"0"})
|
||||||
|
c.config.Set("your.replacements.0.freq", "1.0")
|
||||||
|
c.config.Set("your.replacements.0.this", "fuck")
|
||||||
|
c.config.Set("your.replacements.0.that", "duck")
|
||||||
res := c.Message(makeMessage("fuck a duck"))
|
res := c.Message(makeMessage("fuck a duck"))
|
||||||
assert.Len(t, mb.Messages, 1)
|
|
||||||
assert.True(t, res)
|
assert.True(t, res)
|
||||||
|
assert.Len(t, mb.Messages, 1)
|
||||||
assert.Contains(t, mb.Messages[0], "duck a duck")
|
assert.Contains(t, mb.Messages[0], "duck a duck")
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestNoReplacement(t *testing.T) {
|
func TestNoReplacement(t *testing.T) {
|
||||||
mb := bot.NewMockBot()
|
c, mb := setup(t)
|
||||||
c := New(mb)
|
c.config.Set("Your.MaxLength", "1000")
|
||||||
assert.NotNil(t, c)
|
c.config.SetArray("your.replacements", []string{"0", "1", "2"})
|
||||||
c.config.Your.MaxLength = 1000
|
c.config.Set("your.replacements.0.freq", "1.0")
|
||||||
c.config.Your.Replacements = []config.Replacement{
|
c.config.Set("your.replacements.0.this", "nope")
|
||||||
config.Replacement{
|
c.config.Set("your.replacements.0.that", "duck")
|
||||||
This: "nope",
|
|
||||||
That: "duck",
|
c.config.Set("your.replacements.1.freq", "1.0")
|
||||||
Frequency: 1.0,
|
c.config.Set("your.replacements.1.this", "nope")
|
||||||
},
|
c.config.Set("your.replacements.1.that", "duck")
|
||||||
config.Replacement{
|
|
||||||
This: " fuck",
|
c.config.Set("your.replacements.2.freq", "1.0")
|
||||||
That: "duck",
|
c.config.Set("your.replacements.2.this", "Fuck")
|
||||||
Frequency: 1.0,
|
c.config.Set("your.replacements.2.that", "duck")
|
||||||
},
|
|
||||||
config.Replacement{
|
|
||||||
This: "Fuck",
|
|
||||||
That: "duck",
|
|
||||||
Frequency: 1.0,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
c.Message(makeMessage("fuck a duck"))
|
c.Message(makeMessage("fuck a duck"))
|
||||||
assert.Len(t, mb.Messages, 0)
|
assert.Len(t, mb.Messages, 0)
|
||||||
}
|
}
|
||||||
|
|
|
@ -210,11 +210,15 @@ func (s *Slack) SendMessageType(channel, message string, meMessage bool) (string
|
||||||
postUrl = "https://slack.com/api/chat.meMessage"
|
postUrl = "https://slack.com/api/chat.meMessage"
|
||||||
}
|
}
|
||||||
|
|
||||||
nick := s.config.Nick
|
nick := s.config.Get("Nick")
|
||||||
icon := s.config.IconURL
|
icon := s.config.Get("IconURL")
|
||||||
|
if icon == "" {
|
||||||
|
icon = "https://placekitten.com/400/400"
|
||||||
|
log.Println("Set config item IconURL to customize appearance!")
|
||||||
|
}
|
||||||
|
|
||||||
resp, err := http.PostForm(postUrl,
|
resp, err := http.PostForm(postUrl,
|
||||||
url.Values{"token": {s.config.Slack.Token},
|
url.Values{"token": {s.config.Get("Slack.Token")},
|
||||||
"username": {nick},
|
"username": {nick},
|
||||||
"icon_url": {icon},
|
"icon_url": {icon},
|
||||||
"channel": {channel},
|
"channel": {channel},
|
||||||
|
@ -269,11 +273,11 @@ func (s *Slack) SendAction(channel, message string) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Slack) ReplyToMessageIdentifier(channel, message, identifier string) (string, bool) {
|
func (s *Slack) ReplyToMessageIdentifier(channel, message, identifier string) (string, bool) {
|
||||||
nick := s.config.Nick
|
nick := s.config.Get("Nick")
|
||||||
icon := s.config.IconURL
|
icon := s.config.Get("IconURL")
|
||||||
|
|
||||||
resp, err := http.PostForm("https://slack.com/api/chat.postMessage",
|
resp, err := http.PostForm("https://slack.com/api/chat.postMessage",
|
||||||
url.Values{"token": {s.config.Slack.Token},
|
url.Values{"token": {s.config.Get("Slack.Token")},
|
||||||
"username": {nick},
|
"username": {nick},
|
||||||
"icon_url": {icon},
|
"icon_url": {icon},
|
||||||
"channel": {channel},
|
"channel": {channel},
|
||||||
|
@ -321,7 +325,7 @@ func (s *Slack) ReplyToMessage(channel, message string, replyTo msg.Message) (st
|
||||||
func (s *Slack) React(channel, reaction string, message msg.Message) bool {
|
func (s *Slack) React(channel, reaction string, message msg.Message) bool {
|
||||||
log.Printf("Reacting in %s: %s", channel, reaction)
|
log.Printf("Reacting in %s: %s", channel, reaction)
|
||||||
resp, err := http.PostForm("https://slack.com/api/reactions.add",
|
resp, err := http.PostForm("https://slack.com/api/reactions.add",
|
||||||
url.Values{"token": {s.config.Slack.Token},
|
url.Values{"token": {s.config.Get("Slack.Token")},
|
||||||
"name": {reaction},
|
"name": {reaction},
|
||||||
"channel": {channel},
|
"channel": {channel},
|
||||||
"timestamp": {message.AdditionalData["RAW_SLACK_TIMESTAMP"]}})
|
"timestamp": {message.AdditionalData["RAW_SLACK_TIMESTAMP"]}})
|
||||||
|
@ -335,7 +339,7 @@ func (s *Slack) React(channel, reaction string, message msg.Message) bool {
|
||||||
func (s *Slack) Edit(channel, newMessage, identifier string) bool {
|
func (s *Slack) Edit(channel, newMessage, identifier string) bool {
|
||||||
log.Printf("Editing in (%s) %s: %s", identifier, channel, newMessage)
|
log.Printf("Editing in (%s) %s: %s", identifier, channel, newMessage)
|
||||||
resp, err := http.PostForm("https://slack.com/api/chat.update",
|
resp, err := http.PostForm("https://slack.com/api/chat.update",
|
||||||
url.Values{"token": {s.config.Slack.Token},
|
url.Values{"token": {s.config.Get("Slack.Token")},
|
||||||
"channel": {channel},
|
"channel": {channel},
|
||||||
"text": {newMessage},
|
"text": {newMessage},
|
||||||
"ts": {identifier}})
|
"ts": {identifier}})
|
||||||
|
@ -352,7 +356,7 @@ func (s *Slack) GetEmojiList() map[string]string {
|
||||||
|
|
||||||
func (s *Slack) populateEmojiList() {
|
func (s *Slack) populateEmojiList() {
|
||||||
resp, err := http.PostForm("https://slack.com/api/emoji.list",
|
resp, err := http.PostForm("https://slack.com/api/emoji.list",
|
||||||
url.Values{"token": {s.config.Slack.Token}})
|
url.Values{"token": {s.config.Get("Slack.Token")}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error retrieving emoji list from Slack: %s", err)
|
log.Printf("Error retrieving emoji list from Slack: %s", err)
|
||||||
return
|
return
|
||||||
|
@ -545,7 +549,7 @@ func (s *Slack) markAllChannelsRead() {
|
||||||
func (s *Slack) getAllChannels() []slackChannelListItem {
|
func (s *Slack) getAllChannels() []slackChannelListItem {
|
||||||
u := s.url + "channels.list"
|
u := s.url + "channels.list"
|
||||||
resp, err := http.PostForm(u,
|
resp, err := http.PostForm(u,
|
||||||
url.Values{"token": {s.config.Slack.Token}})
|
url.Values{"token": {s.config.Get("Slack.Token")}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error posting user info request: %s",
|
log.Printf("Error posting user info request: %s",
|
||||||
err)
|
err)
|
||||||
|
@ -570,7 +574,7 @@ func (s *Slack) getAllChannels() []slackChannelListItem {
|
||||||
func (s *Slack) markChannelAsRead(slackChanId string) error {
|
func (s *Slack) markChannelAsRead(slackChanId string) error {
|
||||||
u := s.url + "channels.info"
|
u := s.url + "channels.info"
|
||||||
resp, err := http.PostForm(u,
|
resp, err := http.PostForm(u,
|
||||||
url.Values{"token": {s.config.Slack.Token}, "channel": {slackChanId}})
|
url.Values{"token": {s.config.Get("Slack.Token")}, "channel": {slackChanId}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error posting user info request: %s",
|
log.Printf("Error posting user info request: %s",
|
||||||
err)
|
err)
|
||||||
|
@ -592,7 +596,7 @@ func (s *Slack) markChannelAsRead(slackChanId string) error {
|
||||||
|
|
||||||
u = s.url + "channels.mark"
|
u = s.url + "channels.mark"
|
||||||
resp, err = http.PostForm(u,
|
resp, err = http.PostForm(u,
|
||||||
url.Values{"token": {s.config.Slack.Token}, "channel": {slackChanId}, "ts": {chanInfo.Channel.Latest.Ts}})
|
url.Values{"token": {s.config.Get("Slack.Token")}, "channel": {slackChanId}, "ts": {chanInfo.Channel.Latest.Ts}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error posting user info request: %s",
|
log.Printf("Error posting user info request: %s",
|
||||||
err)
|
err)
|
||||||
|
@ -617,7 +621,7 @@ func (s *Slack) markChannelAsRead(slackChanId string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Slack) connect() {
|
func (s *Slack) connect() {
|
||||||
token := s.config.Slack.Token
|
token := s.config.Get("Slack.Token")
|
||||||
u := fmt.Sprintf("https://slack.com/api/rtm.connect?token=%s", token)
|
u := fmt.Sprintf("https://slack.com/api/rtm.connect?token=%s", token)
|
||||||
resp, err := http.Get(u)
|
resp, err := http.Get(u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -663,7 +667,7 @@ func (s *Slack) getUser(id string) (string, bool) {
|
||||||
log.Printf("User %s not already found, requesting info", id)
|
log.Printf("User %s not already found, requesting info", id)
|
||||||
u := s.url + "users.info"
|
u := s.url + "users.info"
|
||||||
resp, err := http.PostForm(u,
|
resp, err := http.PostForm(u,
|
||||||
url.Values{"token": {s.config.Slack.Token}, "user": {id}})
|
url.Values{"token": {s.config.Get("Slack.Token")}, "user": {id}})
|
||||||
if err != nil || resp.StatusCode != 200 {
|
if err != nil || resp.StatusCode != 200 {
|
||||||
log.Printf("Error posting user info request: %d %s",
|
log.Printf("Error posting user info request: %d %s",
|
||||||
resp.StatusCode, err)
|
resp.StatusCode, err)
|
||||||
|
@ -685,7 +689,7 @@ func (s *Slack) Who(id string) []string {
|
||||||
log.Println("Who is queried for ", id)
|
log.Println("Who is queried for ", id)
|
||||||
u := s.url + "channels.info"
|
u := s.url + "channels.info"
|
||||||
resp, err := http.PostForm(u,
|
resp, err := http.PostForm(u,
|
||||||
url.Values{"token": {s.config.Slack.Token}, "channel": {id}})
|
url.Values{"token": {s.config.Get("Slack.Token")}, "channel": {id}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Printf("Error posting user info request: %s",
|
log.Printf("Error posting user info request: %s",
|
||||||
err)
|
err)
|
||||||
|
|
Loading…
Reference in New Issue