mirror of https://github.com/velour/catbase.git
Make testing great again! Add examples in counter
* Made bot.Bot an interface and added a mock with an in-memory database for plugins to use. * Remove logger nonsense * Rename Counter New
This commit is contained in:
parent
a34afa97ad
commit
ef40d335eb
89
bot/bot.go
89
bot/bot.go
|
@ -16,33 +16,33 @@ import (
|
|||
"github.com/velour/catbase/config"
|
||||
)
|
||||
|
||||
// Bot type provides storage for bot-wide information, configs, and database connections
|
||||
type Bot struct {
|
||||
// bot type provides storage for bot-wide information, configs, and database connections
|
||||
type bot struct {
|
||||
// Each plugin must be registered in our plugins handler. To come: a map so that this
|
||||
// will allow plugins to respond to specific kinds of events
|
||||
Plugins map[string]Handler
|
||||
PluginOrdering []string
|
||||
plugins map[string]Handler
|
||||
pluginOrdering []string
|
||||
|
||||
// Users holds information about all of our friends
|
||||
Users []User
|
||||
users []User
|
||||
// Represents the bot
|
||||
Me User
|
||||
me User
|
||||
|
||||
Config *config.Config
|
||||
config *config.Config
|
||||
|
||||
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
|
||||
db *sqlx.DB
|
||||
dbVersion int64
|
||||
|
||||
logIn chan Message
|
||||
logOut chan Messages
|
||||
|
||||
Version string
|
||||
version string
|
||||
|
||||
// The entries to the bot's HTTP interface
|
||||
httpEndPoints map[string]string
|
||||
|
@ -109,8 +109,8 @@ func init() {
|
|||
})
|
||||
}
|
||||
|
||||
// NewBot creates a Bot for a given connection and set of handlers.
|
||||
func NewBot(config *config.Config, connector Connector) *Bot {
|
||||
// Newbot creates a bot for a given connection and set of handlers.
|
||||
func New(config *config.Config, connector Connector) Bot {
|
||||
sqlDB, err := sqlx.Open("sqlite3_custom", config.DB.File)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
|
@ -127,17 +127,17 @@ func NewBot(config *config.Config, connector Connector) *Bot {
|
|||
},
|
||||
}
|
||||
|
||||
bot := &Bot{
|
||||
Config: config,
|
||||
Plugins: make(map[string]Handler),
|
||||
PluginOrdering: make([]string, 0),
|
||||
Conn: connector,
|
||||
Users: users,
|
||||
Me: users[0],
|
||||
DB: sqlDB,
|
||||
bot := &bot{
|
||||
config: config,
|
||||
plugins: make(map[string]Handler),
|
||||
pluginOrdering: make([]string, 0),
|
||||
conn: connector,
|
||||
users: users,
|
||||
me: users[0],
|
||||
db: sqlDB,
|
||||
logIn: logIn,
|
||||
logOut: logOut,
|
||||
Version: config.Version,
|
||||
version: config.Version,
|
||||
httpEndPoints: make(map[string]string),
|
||||
}
|
||||
|
||||
|
@ -155,32 +155,45 @@ func NewBot(config *config.Config, connector Connector) *Bot {
|
|||
return bot
|
||||
}
|
||||
|
||||
// Config gets the configuration that the bot is using
|
||||
func (b *bot) Config() *config.Config {
|
||||
return b.config
|
||||
}
|
||||
|
||||
func (b *bot) DBVersion() int64 {
|
||||
return b.dbVersion
|
||||
}
|
||||
|
||||
func (b *bot) DB() *sqlx.DB {
|
||||
return b.db
|
||||
}
|
||||
|
||||
// Create any tables if necessary based on version of DB
|
||||
// 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.
|
||||
func (b *Bot) migrateDB() {
|
||||
_, err := b.DB.Exec(`create table if not exists version (version integer);`)
|
||||
func (b *bot) migrateDB() {
|
||||
_, err := b.db.Exec(`create table if not exists version (version integer);`)
|
||||
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)
|
||||
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)
|
||||
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)`)
|
||||
_, err := b.db.Exec(`insert into version (version) values (1)`)
|
||||
if err != nil {
|
||||
log.Fatal("Initial DB migration insert: ", err)
|
||||
}
|
||||
}
|
||||
|
||||
if b.DBVersion == 1 {
|
||||
if _, err := b.DB.Exec(`create table if not exists variables (
|
||||
if b.dbVersion == 1 {
|
||||
if _, err := b.db.Exec(`create table if not exists variables (
|
||||
id integer primary key,
|
||||
name string,
|
||||
perms string,
|
||||
|
@ -188,7 +201,7 @@ func (b *Bot) migrateDB() {
|
|||
);`); err != nil {
|
||||
log.Fatal("Initial DB migration create variables table: ", err)
|
||||
}
|
||||
if _, err := b.DB.Exec(`create table if not exists 'values' (
|
||||
if _, err := b.db.Exec(`create table if not exists 'values' (
|
||||
id integer primary key,
|
||||
varId integer,
|
||||
value string
|
||||
|
@ -199,18 +212,18 @@ func (b *Bot) migrateDB() {
|
|||
}
|
||||
|
||||
// Adds a constructed handler to the bots handlers list
|
||||
func (b *Bot) AddHandler(name string, h Handler) {
|
||||
b.Plugins[strings.ToLower(name)] = h
|
||||
b.PluginOrdering = append(b.PluginOrdering, name)
|
||||
func (b *bot) AddHandler(name string, h Handler) {
|
||||
b.plugins[strings.ToLower(name)] = h
|
||||
b.pluginOrdering = append(b.pluginOrdering, name)
|
||||
if entry := h.RegisterWeb(); entry != nil {
|
||||
b.httpEndPoints[name] = *entry
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bot) Who(channel string) []User {
|
||||
func (b *bot) Who(channel string) []User {
|
||||
out := []User{}
|
||||
for _, u := range b.Users {
|
||||
if u.Name != b.Config.Nick {
|
||||
for _, u := range b.users {
|
||||
if u.Name != b.Config().Nick {
|
||||
out = append(out, u)
|
||||
}
|
||||
}
|
||||
|
@ -247,7 +260,7 @@ var rootIndex string = `
|
|||
</html>
|
||||
`
|
||||
|
||||
func (b *Bot) serveRoot(w http.ResponseWriter, r *http.Request) {
|
||||
func (b *bot) serveRoot(w http.ResponseWriter, r *http.Request) {
|
||||
context := make(map[string]interface{})
|
||||
context["EndPoints"] = b.httpEndPoints
|
||||
t, err := template.New("rootIndex").Parse(rootIndex)
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
)
|
||||
|
||||
// Handles incomming PRIVMSG requests
|
||||
func (b *Bot) MsgReceived(msg Message) {
|
||||
func (b *bot) MsgReceived(msg Message) {
|
||||
log.Println("Received message: ", msg)
|
||||
|
||||
// msg := b.buildMessage(client, inMsg)
|
||||
|
@ -27,8 +27,8 @@ func (b *Bot) MsgReceived(msg Message) {
|
|||
goto RET
|
||||
}
|
||||
|
||||
for _, name := range b.PluginOrdering {
|
||||
p := b.Plugins[name]
|
||||
for _, name := range b.pluginOrdering {
|
||||
p := b.plugins[name]
|
||||
if p.Message(msg) {
|
||||
break
|
||||
}
|
||||
|
@ -40,31 +40,31 @@ RET:
|
|||
}
|
||||
|
||||
// Handle incoming events
|
||||
func (b *Bot) EventReceived(msg Message) {
|
||||
func (b *bot) EventReceived(msg Message) {
|
||||
log.Println("Received event: ", msg)
|
||||
//msg := b.buildMessage(conn, inMsg)
|
||||
for _, name := range b.PluginOrdering {
|
||||
p := b.Plugins[name]
|
||||
for _, name := range b.pluginOrdering {
|
||||
p := b.plugins[name]
|
||||
if p.Event(msg.Body, msg) { // TODO: could get rid of msg.Body
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bot) SendMessage(channel, message string) {
|
||||
b.Conn.SendMessage(channel, message)
|
||||
func (b *bot) SendMessage(channel, message string) {
|
||||
b.conn.SendMessage(channel, message)
|
||||
}
|
||||
|
||||
func (b *Bot) SendAction(channel, message string) {
|
||||
b.Conn.SendAction(channel, message)
|
||||
func (b *bot) SendAction(channel, message string) {
|
||||
b.conn.SendAction(channel, message)
|
||||
}
|
||||
|
||||
// Checks to see if the user is asking for help, returns true if so and handles the situation.
|
||||
func (b *Bot) checkHelp(channel string, parts []string) {
|
||||
func (b *bot) checkHelp(channel string, parts []string) {
|
||||
if len(parts) == 1 {
|
||||
// just print out a list of help topics
|
||||
topics := "Help topics: about variables"
|
||||
for name, _ := range b.Plugins {
|
||||
for name, _ := range b.plugins {
|
||||
topics = fmt.Sprintf("%s, %s", topics, name)
|
||||
}
|
||||
b.SendMessage(channel, topics)
|
||||
|
@ -78,7 +78,7 @@ func (b *Bot) checkHelp(channel string, parts []string) {
|
|||
b.listVars(channel, parts)
|
||||
return
|
||||
}
|
||||
plugin := b.Plugins[parts[1]]
|
||||
plugin := b.plugins[parts[1]]
|
||||
if plugin != nil {
|
||||
plugin.Help(channel, parts)
|
||||
} else {
|
||||
|
@ -88,7 +88,7 @@ func (b *Bot) checkHelp(channel string, parts []string) {
|
|||
}
|
||||
}
|
||||
|
||||
func (b *Bot) LastMessage(channel string) (Message, error) {
|
||||
func (b *bot) LastMessage(channel string) (Message, error) {
|
||||
log := <-b.logOut
|
||||
if len(log) == 0 {
|
||||
return Message{}, errors.New("No messages found.")
|
||||
|
@ -103,7 +103,7 @@ func (b *Bot) LastMessage(channel string) (Message, error) {
|
|||
}
|
||||
|
||||
// Take an input string and mutate it based on $vars in the string
|
||||
func (b *Bot) Filter(message Message, input string) string {
|
||||
func (b *bot) Filter(message Message, input string) string {
|
||||
rand.Seed(time.Now().Unix())
|
||||
|
||||
if strings.Contains(input, "$NICK") {
|
||||
|
@ -155,9 +155,9 @@ func (b *Bot) Filter(message Message, input string) string {
|
|||
return input
|
||||
}
|
||||
|
||||
func (b *Bot) getVar(varName string) (string, error) {
|
||||
func (b *bot) getVar(varName string) (string, error) {
|
||||
var text string
|
||||
err := b.DB.QueryRow(`select v.value from variables as va inner join "values" as v on va.id = va.id = v.varId order by random() limit 1`).Scan(&text)
|
||||
err := b.db.QueryRow(`select v.value from variables as va inner join "values" as v on va.id = va.id = v.varId order by random() limit 1`).Scan(&text)
|
||||
switch {
|
||||
case err == sql.ErrNoRows:
|
||||
return "", fmt.Errorf("No factoid found")
|
||||
|
@ -167,8 +167,8 @@ func (b *Bot) getVar(varName string) (string, error) {
|
|||
return text, nil
|
||||
}
|
||||
|
||||
func (b *Bot) listVars(channel string, parts []string) {
|
||||
rows, err := b.DB.Query(`select name from variables`)
|
||||
func (b *bot) listVars(channel string, parts []string) {
|
||||
rows, err := b.db.Query(`select name from variables`)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -185,17 +185,17 @@ func (b *Bot) listVars(channel string, parts []string) {
|
|||
b.SendMessage(channel, msg)
|
||||
}
|
||||
|
||||
func (b *Bot) Help(channel string, parts []string) {
|
||||
func (b *bot) Help(channel string, parts []string) {
|
||||
msg := fmt.Sprintf("Hi, I'm based on godeepintir version %s. I'm written in Go, and you "+
|
||||
"can find my source code on the internet here: "+
|
||||
"http://github.com/velour/catbase", b.Version)
|
||||
"http://github.com/velour/catbase", b.version)
|
||||
b.SendMessage(channel, msg)
|
||||
}
|
||||
|
||||
// Send our own musings to the plugins
|
||||
func (b *Bot) selfSaid(channel, message string, action bool) {
|
||||
func (b *bot) selfSaid(channel, message string, action bool) {
|
||||
msg := Message{
|
||||
User: &b.Me, // hack
|
||||
User: &b.me, // hack
|
||||
Channel: channel,
|
||||
Body: message,
|
||||
Raw: message, // hack
|
||||
|
@ -205,8 +205,8 @@ func (b *Bot) selfSaid(channel, message string, action bool) {
|
|||
Host: "0.0.0.0", // hack
|
||||
}
|
||||
|
||||
for _, name := range b.PluginOrdering {
|
||||
p := b.Plugins[name]
|
||||
for _, name := range b.pluginOrdering {
|
||||
p := b.plugins[name]
|
||||
if p.BotMessage(msg) {
|
||||
break
|
||||
}
|
||||
|
|
|
@ -2,6 +2,25 @@
|
|||
|
||||
package bot
|
||||
|
||||
import (
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/velour/catbase/config"
|
||||
)
|
||||
|
||||
type Bot interface {
|
||||
Config() *config.Config
|
||||
DBVersion() int64
|
||||
DB() *sqlx.DB
|
||||
Who(string) []User
|
||||
AddHandler(string, Handler)
|
||||
SendMessage(string, string)
|
||||
SendAction(string, string)
|
||||
MsgReceived(Message)
|
||||
EventReceived(Message)
|
||||
Filter(Message, string) string
|
||||
LastMessage(string) (Message, error)
|
||||
}
|
||||
|
||||
type Connector interface {
|
||||
RegisterEventReceived(func(message Message))
|
||||
RegisterMessageReceived(func(message Message))
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
// © 2016 the CatBase Authors under the WTFPL license. See AUTHORS for the list of authors.
|
||||
|
||||
package bot
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/jmoiron/sqlx"
|
||||
"github.com/stretchr/testify/mock"
|
||||
"github.com/velour/catbase/config"
|
||||
)
|
||||
|
||||
type MockBot struct {
|
||||
mock.Mock
|
||||
db *sqlx.DB
|
||||
|
||||
Messages []string
|
||||
Actions []string
|
||||
}
|
||||
|
||||
func (mb *MockBot) Config() *config.Config { return &config.Config{} }
|
||||
func (mb *MockBot) DBVersion() int64 { return 1 }
|
||||
func (mb *MockBot) DB() *sqlx.DB { return mb.db }
|
||||
func (mb *MockBot) Who(string) []User { return []User{} }
|
||||
func (mb *MockBot) AddHandler(name string, f Handler) {}
|
||||
func (mb *MockBot) SendMessage(ch string, msg string) {
|
||||
mb.Messages = append(mb.Messages, msg)
|
||||
}
|
||||
func (mb *MockBot) SendAction(ch string, msg string) {
|
||||
mb.Actions = append(mb.Actions, msg)
|
||||
}
|
||||
func (mb *MockBot) MsgReceived(msg Message) {}
|
||||
func (mb *MockBot) EventReceived(msg Message) {}
|
||||
func (mb *MockBot) Filter(msg Message, s string) string { return "" }
|
||||
func (mb *MockBot) LastMessage(ch string) (Message, error) { return Message{}, nil }
|
||||
|
||||
func NewMockBot() *MockBot {
|
||||
db, err := sqlx.Open("sqlite3_custom", ":memory:")
|
||||
if err != nil {
|
||||
log.Fatal("Failed to open database:", err)
|
||||
}
|
||||
b := MockBot{
|
||||
db: db,
|
||||
Messages: make([]string, 0),
|
||||
Actions: make([]string, 0),
|
||||
}
|
||||
return &b
|
||||
}
|
10
bot/users.go
10
bot/users.go
|
@ -16,12 +16,12 @@ type User struct {
|
|||
|
||||
Admin bool
|
||||
|
||||
//bot *Bot
|
||||
//bot *bot
|
||||
}
|
||||
|
||||
var users = map[string]*User{}
|
||||
|
||||
func (b *Bot) GetUser(nick string) *User {
|
||||
func (b *bot) GetUser(nick string) *User {
|
||||
if _, ok := users[nick]; !ok {
|
||||
users[nick] = &User{
|
||||
Name: nick,
|
||||
|
@ -31,15 +31,15 @@ func (b *Bot) GetUser(nick string) *User {
|
|||
return users[nick]
|
||||
}
|
||||
|
||||
func (b *Bot) NewUser(nick string) *User {
|
||||
func (b *bot) NewUser(nick string) *User {
|
||||
return &User{
|
||||
Name: nick,
|
||||
Admin: b.checkAdmin(nick),
|
||||
}
|
||||
}
|
||||
|
||||
func (b *Bot) checkAdmin(nick string) bool {
|
||||
for _, u := range b.Config.Admins {
|
||||
func (b *bot) checkAdmin(nick string) bool {
|
||||
for _, u := range b.Config().Admins {
|
||||
if nick == u {
|
||||
return true
|
||||
}
|
||||
|
|
20
main.go
20
main.go
|
@ -9,10 +9,8 @@ import (
|
|||
"github.com/velour/catbase/bot"
|
||||
"github.com/velour/catbase/config"
|
||||
"github.com/velour/catbase/irc"
|
||||
"github.com/velour/catbase/plugins"
|
||||
"github.com/velour/catbase/plugins/admin"
|
||||
"github.com/velour/catbase/plugins/beers"
|
||||
"github.com/velour/catbase/plugins/counter"
|
||||
"github.com/velour/catbase/plugins/dice"
|
||||
"github.com/velour/catbase/plugins/downtime"
|
||||
"github.com/velour/catbase/plugins/fact"
|
||||
|
@ -39,22 +37,20 @@ func main() {
|
|||
log.Fatalf("Unknown connection type: %s", c.Type)
|
||||
}
|
||||
|
||||
b := bot.NewBot(c, client)
|
||||
b := bot.New(c, client)
|
||||
|
||||
// b.AddHandler(plugins.NewTestPlugin(b))
|
||||
b.AddHandler("admin", admin.NewAdminPlugin(b))
|
||||
b.AddHandler("admin", admin.New(b))
|
||||
// b.AddHandler("first", plugins.NewFirstPlugin(b))
|
||||
b.AddHandler("leftpad", leftpad.New(b))
|
||||
b.AddHandler("downtime", downtime.NewDowntimePlugin(b))
|
||||
b.AddHandler("downtime", downtime.New(b))
|
||||
b.AddHandler("talker", talker.New(b))
|
||||
b.AddHandler("dice", dice.NewDicePlugin(b))
|
||||
b.AddHandler("beers", beers.NewBeersPlugin(b))
|
||||
b.AddHandler("counter", counter.NewCounterPlugin(b))
|
||||
b.AddHandler("remember", fact.NewRememberPlugin(b))
|
||||
b.AddHandler("skeleton", plugins.NewSkeletonPlugin(b))
|
||||
b.AddHandler("your", your.NewYourPlugin(b))
|
||||
b.AddHandler("dice", dice.New(b))
|
||||
b.AddHandler("beers", beers.New(b))
|
||||
b.AddHandler("remember", fact.NewRemember(b))
|
||||
b.AddHandler("your", your.New(b))
|
||||
// catches anything left, will always return true
|
||||
b.AddHandler("factoid", fact.NewFactoidPlugin(b))
|
||||
b.AddHandler("factoid", fact.New(b))
|
||||
|
||||
client.Serve()
|
||||
}
|
||||
|
|
|
@ -17,15 +17,15 @@ import (
|
|||
// This is a admin plugin to serve as an example and quick copy/paste for new plugins.
|
||||
|
||||
type AdminPlugin struct {
|
||||
Bot *bot.Bot
|
||||
Bot bot.Bot
|
||||
DB *sqlx.DB
|
||||
}
|
||||
|
||||
// NewAdminPlugin creates a new AdminPlugin with the Plugin interface
|
||||
func NewAdminPlugin(bot *bot.Bot) *AdminPlugin {
|
||||
func New(bot bot.Bot) *AdminPlugin {
|
||||
p := &AdminPlugin{
|
||||
Bot: bot,
|
||||
DB: bot.DB,
|
||||
DB: bot.DB(),
|
||||
}
|
||||
p.LoadData()
|
||||
return p
|
||||
|
|
|
@ -22,7 +22,7 @@ import (
|
|||
// This is a skeleton plugin to serve as an example and quick copy/paste for new plugins.
|
||||
|
||||
type BeersPlugin struct {
|
||||
Bot *bot.Bot
|
||||
Bot bot.Bot
|
||||
db *sqlx.DB
|
||||
}
|
||||
|
||||
|
@ -35,9 +35,9 @@ type untappdUser struct {
|
|||
}
|
||||
|
||||
// NewBeersPlugin creates a new BeersPlugin with the Plugin interface
|
||||
func NewBeersPlugin(bot *bot.Bot) *BeersPlugin {
|
||||
if bot.DBVersion == 1 {
|
||||
if _, err := bot.DB.Exec(`create table if not exists untappd (
|
||||
func New(bot bot.Bot) *BeersPlugin {
|
||||
if bot.DBVersion() == 1 {
|
||||
if _, err := bot.DB().Exec(`create table if not exists untappd (
|
||||
id integer primary key,
|
||||
untappdUser string,
|
||||
channel string,
|
||||
|
@ -49,10 +49,10 @@ func NewBeersPlugin(bot *bot.Bot) *BeersPlugin {
|
|||
}
|
||||
p := BeersPlugin{
|
||||
Bot: bot,
|
||||
db: bot.DB,
|
||||
db: bot.DB(),
|
||||
}
|
||||
p.LoadData()
|
||||
for _, channel := range bot.Config.Untappd.Channels {
|
||||
for _, channel := range bot.Config().Untappd.Channels {
|
||||
go p.untappdLoop(channel)
|
||||
}
|
||||
return &p
|
||||
|
@ -313,7 +313,7 @@ type Beers struct {
|
|||
}
|
||||
|
||||
func (p *BeersPlugin) pullUntappd() ([]checkin, error) {
|
||||
access_token := "?access_token=" + p.Bot.Config.Untappd.Token
|
||||
access_token := "?access_token=" + p.Bot.Config().Untappd.Token
|
||||
baseUrl := "https://api.untappd.com/v4/checkin/recent/"
|
||||
|
||||
url := baseUrl + access_token + "&limit=25"
|
||||
|
@ -343,7 +343,7 @@ func (p *BeersPlugin) pullUntappd() ([]checkin, error) {
|
|||
}
|
||||
|
||||
func (p *BeersPlugin) checkUntappd(channel string) {
|
||||
token := p.Bot.Config.Untappd.Token
|
||||
token := p.Bot.Config().Untappd.Token
|
||||
if token == "" || token == "<Your Token>" {
|
||||
log.Println("No Untappd token, cannot enable plugin.")
|
||||
return
|
||||
|
@ -418,7 +418,7 @@ func (p *BeersPlugin) checkUntappd(channel string) {
|
|||
}
|
||||
|
||||
func (p *BeersPlugin) untappdLoop(channel string) {
|
||||
frequency := p.Bot.Config.Untappd.Freq
|
||||
frequency := p.Bot.Config().Untappd.Freq
|
||||
|
||||
log.Println("Checking every ", frequency, " seconds")
|
||||
|
||||
|
|
|
@ -15,7 +15,7 @@ import (
|
|||
// This is a counter plugin to count arbitrary things.
|
||||
|
||||
type CounterPlugin struct {
|
||||
Bot *bot.Bot
|
||||
Bot bot.Bot
|
||||
DB *sqlx.DB
|
||||
}
|
||||
|
||||
|
@ -102,9 +102,9 @@ func (i *Item) Delete() error {
|
|||
}
|
||||
|
||||
// NewCounterPlugin creates a new CounterPlugin with the Plugin interface
|
||||
func NewCounterPlugin(bot *bot.Bot) *CounterPlugin {
|
||||
if bot.DBVersion == 1 {
|
||||
if _, err := bot.DB.Exec(`create table if not exists counter (
|
||||
func New(bot bot.Bot) *CounterPlugin {
|
||||
if bot.DBVersion() == 1 {
|
||||
if _, err := bot.DB().Exec(`create table if not exists counter (
|
||||
id integer primary key,
|
||||
nick string,
|
||||
item string,
|
||||
|
@ -115,7 +115,7 @@ func NewCounterPlugin(bot *bot.Bot) *CounterPlugin {
|
|||
}
|
||||
return &CounterPlugin{
|
||||
Bot: bot,
|
||||
DB: bot.DB,
|
||||
DB: bot.DB(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -271,13 +271,6 @@ func (p *CounterPlugin) Message(message bot.Message) bool {
|
|||
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 *CounterPlugin) LoadData() {
|
||||
// This bot has no data to load
|
||||
}
|
||||
|
||||
// Help responds to help requests. Every plugin must implement a help function.
|
||||
func (p *CounterPlugin) Help(channel string, parts []string) {
|
||||
p.Bot.SendMessage(channel, "You can set counters incrementally by using "+
|
||||
|
|
|
@ -0,0 +1,168 @@
|
|||
// © 2016 the CatBase Authors under the WTFPL license. See AUTHORS for the list of authors.
|
||||
|
||||
package counter
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/velour/catbase/bot"
|
||||
)
|
||||
|
||||
func makeMessage(payload string) bot.Message {
|
||||
isCmd := strings.HasPrefix(payload, "!")
|
||||
if isCmd {
|
||||
payload = payload[1:]
|
||||
}
|
||||
return bot.Message{
|
||||
User: &bot.User{Name: "tester"},
|
||||
Channel: "test",
|
||||
Body: payload,
|
||||
Command: isCmd,
|
||||
}
|
||||
}
|
||||
|
||||
func TestCounterOne(t *testing.T) {
|
||||
mb := bot.NewMockBot()
|
||||
c := New(mb)
|
||||
assert.NotNil(t, c)
|
||||
c.Message(makeMessage("test++"))
|
||||
assert.Len(t, mb.Messages, 1)
|
||||
assert.Equal(t, mb.Messages[0], "tester has 1 test.")
|
||||
}
|
||||
|
||||
func TestCounterFour(t *testing.T) {
|
||||
mb := bot.NewMockBot()
|
||||
c := New(mb)
|
||||
assert.NotNil(t, c)
|
||||
for i := 0; i < 4; i++ {
|
||||
c.Message(makeMessage("test++"))
|
||||
}
|
||||
assert.Len(t, mb.Messages, 4)
|
||||
assert.Equal(t, mb.Messages[3], "tester has 4 test.")
|
||||
}
|
||||
|
||||
func TestCounterDecrement(t *testing.T) {
|
||||
mb := bot.NewMockBot()
|
||||
c := New(mb)
|
||||
assert.NotNil(t, c)
|
||||
for i := 0; i < 4; i++ {
|
||||
c.Message(makeMessage("test++"))
|
||||
assert.Equal(t, mb.Messages[i], fmt.Sprintf("tester has %d test.", i+1))
|
||||
}
|
||||
c.Message(makeMessage("test--"))
|
||||
assert.Len(t, mb.Messages, 5)
|
||||
assert.Equal(t, mb.Messages[4], "tester has 3 test.")
|
||||
}
|
||||
|
||||
func TestFriendCounterDecrement(t *testing.T) {
|
||||
mb := bot.NewMockBot()
|
||||
c := New(mb)
|
||||
assert.NotNil(t, c)
|
||||
for i := 0; i < 4; i++ {
|
||||
c.Message(makeMessage("other.test++"))
|
||||
assert.Equal(t, mb.Messages[i], fmt.Sprintf("other has %d test.", i+1))
|
||||
}
|
||||
c.Message(makeMessage("other.test--"))
|
||||
assert.Len(t, mb.Messages, 5)
|
||||
assert.Equal(t, mb.Messages[4], "other has 3 test.")
|
||||
}
|
||||
|
||||
func TestDecrementZero(t *testing.T) {
|
||||
mb := bot.NewMockBot()
|
||||
c := New(mb)
|
||||
assert.NotNil(t, c)
|
||||
for i := 0; i < 4; i++ {
|
||||
c.Message(makeMessage("test++"))
|
||||
assert.Equal(t, mb.Messages[i], fmt.Sprintf("tester has %d test.", i+1))
|
||||
}
|
||||
j := 4
|
||||
for i := 4; i > 0; i-- {
|
||||
c.Message(makeMessage("test--"))
|
||||
assert.Equal(t, mb.Messages[j], fmt.Sprintf("tester has %d test.", i-1))
|
||||
j++
|
||||
}
|
||||
assert.Len(t, mb.Messages, 8)
|
||||
assert.Equal(t, mb.Messages[7], "tester has 0 test.")
|
||||
}
|
||||
|
||||
func TestClear(t *testing.T) {
|
||||
mb := bot.NewMockBot()
|
||||
c := New(mb)
|
||||
assert.NotNil(t, c)
|
||||
for i := 0; i < 4; i++ {
|
||||
c.Message(makeMessage("test++"))
|
||||
assert.Equal(t, mb.Messages[i], fmt.Sprintf("tester has %d test.", i+1))
|
||||
}
|
||||
res := c.Message(makeMessage("!clear test"))
|
||||
assert.True(t, res)
|
||||
assert.Len(t, mb.Actions, 1)
|
||||
assert.Equal(t, mb.Actions[0], "chops a few test out of his brain")
|
||||
}
|
||||
|
||||
func TestCount(t *testing.T) {
|
||||
mb := bot.NewMockBot()
|
||||
c := New(mb)
|
||||
assert.NotNil(t, c)
|
||||
for i := 0; i < 4; i++ {
|
||||
c.Message(makeMessage("test++"))
|
||||
assert.Equal(t, mb.Messages[i], fmt.Sprintf("tester has %d test.", i+1))
|
||||
}
|
||||
res := c.Message(makeMessage("!count test"))
|
||||
assert.True(t, res)
|
||||
assert.Len(t, mb.Messages, 5)
|
||||
assert.Equal(t, mb.Messages[4], "tester has 4 test.")
|
||||
}
|
||||
|
||||
func TestInspectMe(t *testing.T) {
|
||||
mb := bot.NewMockBot()
|
||||
c := New(mb)
|
||||
assert.NotNil(t, c)
|
||||
for i := 0; i < 4; i++ {
|
||||
c.Message(makeMessage("test++"))
|
||||
assert.Equal(t, mb.Messages[i], fmt.Sprintf("tester has %d test.", i+1))
|
||||
}
|
||||
for i := 0; i < 2; i++ {
|
||||
c.Message(makeMessage("fucks++"))
|
||||
assert.Equal(t, mb.Messages[i+4], fmt.Sprintf("tester has %d fucks.", i+1))
|
||||
}
|
||||
for i := 0; i < 20; i++ {
|
||||
c.Message(makeMessage("cheese++"))
|
||||
assert.Equal(t, mb.Messages[i+6], fmt.Sprintf("tester has %d cheese.", i+1))
|
||||
}
|
||||
res := c.Message(makeMessage("!inspect me"))
|
||||
assert.True(t, res)
|
||||
assert.Len(t, mb.Messages, 27)
|
||||
assert.Equal(t, mb.Messages[26], "tester has the following counters: test: 4, fucks: 2, cheese: 20.")
|
||||
}
|
||||
|
||||
func TestHelp(t *testing.T) {
|
||||
mb := bot.NewMockBot()
|
||||
c := New(mb)
|
||||
assert.NotNil(t, c)
|
||||
c.Help("channel", []string{})
|
||||
assert.Len(t, mb.Messages, 1)
|
||||
}
|
||||
|
||||
func TestBotMessage(t *testing.T) {
|
||||
mb := bot.NewMockBot()
|
||||
c := New(mb)
|
||||
assert.NotNil(t, c)
|
||||
assert.False(t, c.BotMessage(makeMessage("test")))
|
||||
}
|
||||
|
||||
func TestEvent(t *testing.T) {
|
||||
mb := bot.NewMockBot()
|
||||
c := New(mb)
|
||||
assert.NotNil(t, c)
|
||||
assert.False(t, c.Event("dummy", makeMessage("test")))
|
||||
}
|
||||
|
||||
func TestRegisterWeb(t *testing.T) {
|
||||
mb := bot.NewMockBot()
|
||||
c := New(mb)
|
||||
assert.NotNil(t, c)
|
||||
assert.Nil(t, c.RegisterWeb())
|
||||
}
|
|
@ -15,11 +15,11 @@ import (
|
|||
// This is a dice plugin to serve as an example and quick copy/paste for new plugins.
|
||||
|
||||
type DicePlugin struct {
|
||||
Bot *bot.Bot
|
||||
Bot bot.Bot
|
||||
}
|
||||
|
||||
// NewDicePlugin creates a new DicePlugin with the Plugin interface
|
||||
func NewDicePlugin(bot *bot.Bot) *DicePlugin {
|
||||
func New(bot bot.Bot) *DicePlugin {
|
||||
return &DicePlugin{
|
||||
Bot: bot,
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ import (
|
|||
// This is a downtime plugin to monitor how much our users suck
|
||||
|
||||
type DowntimePlugin struct {
|
||||
Bot *bot.Bot
|
||||
Bot bot.Bot
|
||||
db *sqlx.DB
|
||||
}
|
||||
|
||||
|
@ -100,13 +100,13 @@ func (ie idleEntries) Swap(i, j int) {
|
|||
}
|
||||
|
||||
// NewDowntimePlugin creates a new DowntimePlugin with the Plugin interface
|
||||
func NewDowntimePlugin(bot *bot.Bot) *DowntimePlugin {
|
||||
func New(bot bot.Bot) *DowntimePlugin {
|
||||
p := DowntimePlugin{
|
||||
Bot: bot,
|
||||
db: bot.DB,
|
||||
db: bot.DB(),
|
||||
}
|
||||
|
||||
if bot.DBVersion == 1 {
|
||||
if bot.DBVersion() == 1 {
|
||||
_, err := p.db.Exec(`create table if not exists downtime (
|
||||
id integer primary key,
|
||||
nick string,
|
||||
|
@ -160,7 +160,7 @@ func (p *DowntimePlugin) Message(message bot.Message) bool {
|
|||
for _, e := range entries {
|
||||
|
||||
// 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().Nick) == e.nick {
|
||||
p.remove(e.nick)
|
||||
} else {
|
||||
tops = fmt.Sprintf("%s%s: %s ", tops, e.nick, time.Now().Sub(e.lastSeen))
|
||||
|
@ -204,7 +204,7 @@ func (p *DowntimePlugin) Help(channel string, parts []string) {
|
|||
// Empty event handler because this plugin does not do anything on event recv
|
||||
func (p *DowntimePlugin) Event(kind string, message bot.Message) bool {
|
||||
log.Println(kind, "\t", message)
|
||||
if kind != "PART" && message.User.Name != p.Bot.Config.Nick {
|
||||
if kind != "PART" && message.User.Name != p.Bot.Config().Nick {
|
||||
// user joined, let's nail them for it
|
||||
if kind == "NICK" {
|
||||
p.record(strings.ToLower(message.Channel))
|
||||
|
|
|
@ -196,14 +196,14 @@ func getSingleFact(db *sqlx.DB, fact string) (*factoid, error) {
|
|||
|
||||
// FactoidPlugin provides the necessary plugin-wide needs
|
||||
type FactoidPlugin struct {
|
||||
Bot *bot.Bot
|
||||
Bot bot.Bot
|
||||
NotFound []string
|
||||
LastFact *factoid
|
||||
db *sqlx.DB
|
||||
}
|
||||
|
||||
// NewFactoidPlugin creates a new FactoidPlugin with the Plugin interface
|
||||
func NewFactoidPlugin(botInst *bot.Bot) *FactoidPlugin {
|
||||
func New(botInst bot.Bot) *FactoidPlugin {
|
||||
p := &FactoidPlugin{
|
||||
Bot: botInst,
|
||||
NotFound: []string{
|
||||
|
@ -214,7 +214,7 @@ func NewFactoidPlugin(botInst *bot.Bot) *FactoidPlugin {
|
|||
"NOPE! NOPE! NOPE!",
|
||||
"One time, I learned how to jump rope.",
|
||||
},
|
||||
db: botInst.DB,
|
||||
db: botInst.DB(),
|
||||
}
|
||||
|
||||
_, err := p.db.Exec(`create table if not exists factoid (
|
||||
|
@ -231,13 +231,13 @@ func NewFactoidPlugin(botInst *bot.Bot) *FactoidPlugin {
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
for _, channel := range botInst.Config.Channels {
|
||||
for _, channel := range botInst.Config().Channels {
|
||||
go p.factTimer(channel)
|
||||
|
||||
go func(ch string) {
|
||||
// Some random time to start up
|
||||
time.Sleep(time.Duration(15) * time.Second)
|
||||
if ok, fact := p.findTrigger(p.Bot.Config.StartupFact); ok {
|
||||
if ok, fact := p.findTrigger(p.Bot.Config().StartupFact); ok {
|
||||
p.sayFact(bot.Message{
|
||||
Channel: ch,
|
||||
Body: "speed test", // BUG: This is defined in the config too
|
||||
|
@ -596,7 +596,7 @@ func (p *FactoidPlugin) randomFact() *factoid {
|
|||
|
||||
// factTimer spits out a fact at a given interval and with given probability
|
||||
func (p *FactoidPlugin) factTimer(channel string) {
|
||||
duration := time.Duration(p.Bot.Config.QuoteTime) * time.Minute
|
||||
duration := time.Duration(p.Bot.Config().QuoteTime) * time.Minute
|
||||
myLastMsg := time.Now()
|
||||
for {
|
||||
time.Sleep(time.Duration(5) * time.Second)
|
||||
|
@ -609,7 +609,7 @@ func (p *FactoidPlugin) factTimer(channel string) {
|
|||
tdelta := time.Since(lastmsg.Time)
|
||||
earlier := time.Since(myLastMsg) > tdelta
|
||||
chance := rand.Float64()
|
||||
success := chance < p.Bot.Config.QuoteChance
|
||||
success := chance < p.Bot.Config().QuoteChance
|
||||
|
||||
if success && tdelta > duration && earlier {
|
||||
fact := p.randomFact()
|
||||
|
@ -617,9 +617,11 @@ func (p *FactoidPlugin) factTimer(channel string) {
|
|||
continue
|
||||
}
|
||||
|
||||
users := p.Bot.Who(channel)
|
||||
|
||||
// we need to fabricate a message so that bot.Filter can operate
|
||||
message := bot.Message{
|
||||
User: &p.Bot.Users[rand.Intn(len(p.Bot.Users))],
|
||||
User: &users[rand.Intn(len(users))],
|
||||
Channel: channel,
|
||||
}
|
||||
p.sayFact(message, *fact)
|
||||
|
|
|
@ -17,17 +17,17 @@ import (
|
|||
// plugins.
|
||||
|
||||
type RememberPlugin struct {
|
||||
Bot *bot.Bot
|
||||
Bot bot.Bot
|
||||
Log map[string][]bot.Message
|
||||
db *sqlx.DB
|
||||
}
|
||||
|
||||
// NewRememberPlugin creates a new RememberPlugin with the Plugin interface
|
||||
func NewRememberPlugin(b *bot.Bot) *RememberPlugin {
|
||||
func NewRemember(b bot.Bot) *RememberPlugin {
|
||||
p := RememberPlugin{
|
||||
Bot: b,
|
||||
Log: make(map[string][]bot.Message),
|
||||
db: b.DB,
|
||||
db: b.DB(),
|
||||
}
|
||||
return &p
|
||||
}
|
||||
|
@ -167,8 +167,8 @@ func (p *RememberPlugin) quoteTimer(channel string) {
|
|||
for {
|
||||
// this pisses me off: You can't multiply int * time.Duration so it
|
||||
// has to look ugly as shit.
|
||||
time.Sleep(time.Duration(p.Bot.Config.QuoteTime) * time.Minute)
|
||||
chance := 1.0 / p.Bot.Config.QuoteChance
|
||||
time.Sleep(time.Duration(p.Bot.Config().QuoteTime) * time.Minute)
|
||||
chance := 1.0 / p.Bot.Config().QuoteChance
|
||||
if rand.Intn(int(chance)) == 0 {
|
||||
msg := p.randQuote()
|
||||
p.Bot.SendMessage(channel, msg)
|
||||
|
|
|
@ -18,7 +18,7 @@ import (
|
|||
|
||||
type FirstPlugin struct {
|
||||
First *FirstEntry
|
||||
Bot *bot.Bot
|
||||
Bot bot.Bot
|
||||
db *sqlx.DB
|
||||
}
|
||||
|
||||
|
@ -46,9 +46,9 @@ func (fe *FirstEntry) save(db *sqlx.DB) error {
|
|||
}
|
||||
|
||||
// NewFirstPlugin creates a new FirstPlugin with the Plugin interface
|
||||
func NewFirstPlugin(b *bot.Bot) *FirstPlugin {
|
||||
if b.DBVersion == 1 {
|
||||
_, err := b.DB.Exec(`create table if not exists first (
|
||||
func New(b bot.Bot) *FirstPlugin {
|
||||
if b.DBVersion() == 1 {
|
||||
_, err := b.DB().Exec(`create table if not exists first (
|
||||
id integer primary key,
|
||||
day integer,
|
||||
time integer,
|
||||
|
@ -62,14 +62,14 @@ func NewFirstPlugin(b *bot.Bot) *FirstPlugin {
|
|||
|
||||
log.Println("First plugin initialized with day:", midnight(time.Now()))
|
||||
|
||||
first, err := getLastFirst(b.DB)
|
||||
first, err := getLastFirst(b.DB())
|
||||
if err != nil {
|
||||
log.Fatal("Could not initialize first plugin: ", err)
|
||||
}
|
||||
|
||||
return &FirstPlugin{
|
||||
Bot: b,
|
||||
db: b.DB,
|
||||
db: b.DB(),
|
||||
First: first,
|
||||
}
|
||||
}
|
||||
|
@ -151,7 +151,7 @@ func (p *FirstPlugin) Message(message bot.Message) bool {
|
|||
}
|
||||
|
||||
func (p *FirstPlugin) allowed(message bot.Message) bool {
|
||||
for _, msg := range p.Bot.Config.Bad.Msgs {
|
||||
for _, msg := range p.Bot.Config().Bad.Msgs {
|
||||
match, err := regexp.MatchString(msg, strings.ToLower(message.Body))
|
||||
if err != nil {
|
||||
log.Println("Bad regexp: ", err)
|
||||
|
@ -161,13 +161,13 @@ func (p *FirstPlugin) allowed(message bot.Message) bool {
|
|||
return false
|
||||
}
|
||||
}
|
||||
for _, host := range p.Bot.Config.Bad.Hosts {
|
||||
for _, host := range p.Bot.Config().Bad.Hosts {
|
||||
if host == message.Host {
|
||||
log.Println("Disallowing first: ", message.User.Name, ":", message.Body)
|
||||
return false
|
||||
}
|
||||
}
|
||||
for _, nick := range p.Bot.Config.Bad.Nicks {
|
||||
for _, nick := range p.Bot.Config().Bad.Nicks {
|
||||
if nick == message.User.Name {
|
||||
log.Println("Disallowing first: ", message.User.Name, ":", message.Body)
|
||||
return false
|
||||
|
|
|
@ -15,11 +15,11 @@ import (
|
|||
)
|
||||
|
||||
type LeftpadPlugin struct {
|
||||
bot *bot.Bot
|
||||
bot bot.Bot
|
||||
}
|
||||
|
||||
// New creates a new LeftpadPlugin with the Plugin interface
|
||||
func New(bot *bot.Bot) *LeftpadPlugin {
|
||||
func New(bot bot.Bot) *LeftpadPlugin {
|
||||
p := LeftpadPlugin{
|
||||
bot: bot,
|
||||
}
|
||||
|
|
|
@ -2,7 +2,6 @@
|
|||
|
||||
package plugins
|
||||
|
||||
import "fmt"
|
||||
import "github.com/velour/catbase/bot"
|
||||
|
||||
// Plugin interface defines the methods needed to accept a plugin
|
||||
|
@ -14,96 +13,3 @@ type Plugin interface {
|
|||
Help()
|
||||
RegisterWeb()
|
||||
}
|
||||
|
||||
// ---- Below are some example plugins
|
||||
|
||||
// Creates a new TestPlugin with the Plugin interface
|
||||
func NewTestPlugin(bot *bot.Bot) *TestPlugin {
|
||||
tp := TestPlugin{}
|
||||
tp.LoadData()
|
||||
tp.Bot = bot
|
||||
return &tp
|
||||
}
|
||||
|
||||
// TestPlugin type allows our plugin to store persistent state information
|
||||
type TestPlugin struct {
|
||||
Bot *bot.Bot
|
||||
Responds []string
|
||||
Name string
|
||||
Feces string
|
||||
helpmsg []string
|
||||
}
|
||||
|
||||
func (p *TestPlugin) LoadData() {
|
||||
config := GetPluginConfig("TestPlugin")
|
||||
p.Name = config.Name
|
||||
p.Feces = config.Values["Feces"].(string)
|
||||
p.helpmsg = []string{
|
||||
"TestPlugin just shows off how shit works.",
|
||||
}
|
||||
}
|
||||
|
||||
func (p *TestPlugin) Message(message bot.Message) bool {
|
||||
user := message.User
|
||||
channel := message.Channel
|
||||
body := message.Body
|
||||
|
||||
fmt.Println(user, body)
|
||||
fmt.Println("My plugin name is:", p.Name, " My feces are:", p.Feces)
|
||||
p.Bot.SendMessage(channel, body)
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *TestPlugin) Help(message bot.Message) {
|
||||
for _, msg := range p.helpmsg {
|
||||
p.Bot.SendMessage(message.Channel, msg)
|
||||
}
|
||||
}
|
||||
|
||||
// Empty event handler because this plugin does not do anything on event recv
|
||||
func (p *TestPlugin) Event(kind string, message bot.Message) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Handler for bot's own messages
|
||||
func (p *TestPlugin) BotMessage(message bot.Message) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
type PluginConfig struct {
|
||||
Name string
|
||||
Values map[string]interface{}
|
||||
}
|
||||
|
||||
// Loads plugin config (could be out of a DB or something)
|
||||
func GetPluginConfig(name string) PluginConfig {
|
||||
return PluginConfig{
|
||||
Name: "TestPlugin",
|
||||
Values: map[string]interface{}{
|
||||
"Feces": "test",
|
||||
"Responds": "fucker",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
// FalsePlugin shows how plugin fallthrough works for handling messages
|
||||
type FalsePlugin struct{}
|
||||
|
||||
func (fp FalsePlugin) Message(user, message string) bool {
|
||||
fmt.Println("FalsePlugin returning false.")
|
||||
return false
|
||||
}
|
||||
|
||||
func (fp FalsePlugin) LoadData() {
|
||||
|
||||
}
|
||||
|
||||
// Empty event handler because this plugin does not do anything on event recv
|
||||
func (p *FalsePlugin) Event(kind string, message bot.Message) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Handler for bot's own messages
|
||||
func (p *FalsePlugin) BotMessage(message bot.Message) bool {
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -1,53 +0,0 @@
|
|||
// © 2013 the CatBase Authors under the WTFPL. See AUTHORS for the list of authors.
|
||||
|
||||
package plugins
|
||||
|
||||
import "github.com/velour/catbase/bot"
|
||||
|
||||
// This is a skeleton plugin to serve as an example and quick copy/paste for new plugins.
|
||||
|
||||
type SkeletonPlugin struct {
|
||||
Bot *bot.Bot
|
||||
}
|
||||
|
||||
// NewSkeletonPlugin creates a new SkeletonPlugin with the Plugin interface
|
||||
func NewSkeletonPlugin(bot *bot.Bot) *SkeletonPlugin {
|
||||
return &SkeletonPlugin{
|
||||
Bot: bot,
|
||||
}
|
||||
}
|
||||
|
||||
// Message responds to the bot hook on recieving messages.
|
||||
// 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.
|
||||
func (p *SkeletonPlugin) Message(message bot.Message) bool {
|
||||
// This bot does not reply to anything
|
||||
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 *SkeletonPlugin) LoadData() {
|
||||
// This bot has no data to load
|
||||
}
|
||||
|
||||
// Help responds to help requests. Every plugin must implement a help function.
|
||||
func (p *SkeletonPlugin) Help(channel string, parts []string) {
|
||||
p.Bot.SendMessage(channel, "Sorry, Skeleton does not do a goddamn thing.")
|
||||
}
|
||||
|
||||
// Empty event handler because this plugin does not do anything on event recv
|
||||
func (p *SkeletonPlugin) Event(kind string, message bot.Message) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Handler for bot's own messages
|
||||
func (p *SkeletonPlugin) BotMessage(message bot.Message) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
// Register any web URLs desired
|
||||
func (p *SkeletonPlugin) RegisterWeb() *string {
|
||||
return nil
|
||||
}
|
|
@ -40,14 +40,14 @@ var goatse []string = []string{
|
|||
}
|
||||
|
||||
type TalkerPlugin struct {
|
||||
Bot *bot.Bot
|
||||
Bot bot.Bot
|
||||
enforceNicks bool
|
||||
}
|
||||
|
||||
func New(bot *bot.Bot) *TalkerPlugin {
|
||||
func New(bot bot.Bot) *TalkerPlugin {
|
||||
return &TalkerPlugin{
|
||||
Bot: bot,
|
||||
enforceNicks: bot.Config.EnforceNicks,
|
||||
enforceNicks: bot.Config().EnforceNicks,
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -105,11 +105,11 @@ func (p *TalkerPlugin) Help(channel string, parts []string) {
|
|||
|
||||
// Empty event handler because this plugin does not do anything on event recv
|
||||
func (p *TalkerPlugin) Event(kind string, message bot.Message) bool {
|
||||
sayings := p.Bot.Config.WelcomeMsgs
|
||||
sayings := p.Bot.Config().WelcomeMsgs
|
||||
if len(sayings) == 0 {
|
||||
return false
|
||||
}
|
||||
if kind == "JOIN" && strings.ToLower(message.User.Name) != strings.ToLower(p.Bot.Config.Nick) {
|
||||
if kind == "JOIN" && strings.ToLower(message.User.Name) != strings.ToLower(p.Bot.Config().Nick) {
|
||||
msg := fmt.Sprintf(sayings[rand.Intn(len(sayings))], message.User.Name)
|
||||
p.Bot.SendMessage(message.Channel, msg)
|
||||
return true
|
||||
|
|
|
@ -12,11 +12,11 @@ import (
|
|||
)
|
||||
|
||||
type YourPlugin struct {
|
||||
bot *bot.Bot
|
||||
bot bot.Bot
|
||||
}
|
||||
|
||||
// NewYourPlugin creates a new YourPlugin with the Plugin interface
|
||||
func NewYourPlugin(bot *bot.Bot) *YourPlugin {
|
||||
func New(bot bot.Bot) *YourPlugin {
|
||||
rand.Seed(time.Now().Unix())
|
||||
return &YourPlugin{
|
||||
bot: bot,
|
||||
|
@ -28,7 +28,7 @@ func NewYourPlugin(bot *bot.Bot) *YourPlugin {
|
|||
// Otherwise, the function returns false and the bot continues execution of other plugins.
|
||||
func (p *YourPlugin) Message(message bot.Message) bool {
|
||||
lower := strings.ToLower(message.Body)
|
||||
config := p.bot.Config.Your
|
||||
config := p.bot.Config().Your
|
||||
if len(message.Body) > config.MaxLength {
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue