add new version of bot to raspi \o/
This commit is contained in:
commit
d51641ee36
7 changed files with 584 additions and 0 deletions
315
boddle.go
Normal file
315
boddle.go
Normal file
|
|
@ -0,0 +1,315 @@
|
|||
package main
|
||||
|
||||
import "strings"
|
||||
import "fmt"
|
||||
import "regexp"
|
||||
import "database/sql"
|
||||
import _ "github.com/mattn/go-sqlite3"
|
||||
|
||||
type irc_msg struct {
|
||||
channel string
|
||||
msg string
|
||||
author string
|
||||
}
|
||||
|
||||
type cmd struct {
|
||||
valid bool
|
||||
add bool
|
||||
cmd string
|
||||
groups []int
|
||||
suffix string
|
||||
}
|
||||
|
||||
var begin_char = []byte{'<'}
|
||||
var db *sql.DB
|
||||
var err error
|
||||
|
||||
func checkErr(err error) {
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func in (a byte, arr []byte) bool {
|
||||
for _, x := range arr {
|
||||
if x == a {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func unique(intSlice []int) []int {
|
||||
keys := make(map[int]bool)
|
||||
list := []int{}
|
||||
for _, entry := range intSlice {
|
||||
if _, value := keys[entry]; !value {
|
||||
keys[entry] = true
|
||||
list = append(list, entry)
|
||||
}
|
||||
}
|
||||
return list
|
||||
}
|
||||
|
||||
// function to split advise message correctly
|
||||
func filter(msg string) cmd {
|
||||
var c cmd
|
||||
|
||||
if len(msg) <= 0 {
|
||||
c.valid = false
|
||||
return c
|
||||
}
|
||||
|
||||
c.cmd = ""
|
||||
c.valid = false
|
||||
|
||||
if strings.HasPrefix(msg, "add ") {
|
||||
c.add = true
|
||||
msg = msg[4:]
|
||||
} else {
|
||||
c.add = false
|
||||
}
|
||||
|
||||
if (strings.Contains(msg, "[") && strings.Contains(msg, "]")) {
|
||||
re, _ := regexp.Compile(`\s*(\w*)\s*\[(.*)\]\s*(.*)\s*`)
|
||||
res := re.FindStringSubmatch(msg)
|
||||
if len(res) < 4 {
|
||||
return c
|
||||
}
|
||||
|
||||
c.cmd = res[1]
|
||||
if c.cmd == "" {
|
||||
LOG_WARN.Printf("empty cmd\n")
|
||||
return c
|
||||
}
|
||||
|
||||
// TODO: substitute group names with ids
|
||||
groups := strings.Fields(res[2])
|
||||
for _, i := range groups {
|
||||
task := fmt.Sprintf("select id from groups where name = '%s'", i)
|
||||
|
||||
row, err := db.Query(task)
|
||||
if err != nil {
|
||||
LOG_WARN.Printf("no such column: %s\n", i)
|
||||
return c
|
||||
}
|
||||
group_id := 0
|
||||
if row.Next() { row.Scan(&group_id) }
|
||||
row.Close()
|
||||
if (group_id != 0) {
|
||||
c.groups = append(c.groups, group_id)
|
||||
}
|
||||
}
|
||||
c.suffix = res[3]
|
||||
c.valid = true
|
||||
} else {
|
||||
c.groups = nil
|
||||
re, _ := regexp.Compile(`\s*(\w*)\s*(.*)\s*`)
|
||||
res := re.FindStringSubmatch(msg)
|
||||
if len(res) < 3 {
|
||||
return c
|
||||
}
|
||||
c.cmd = res[1]
|
||||
if c.cmd == "" {
|
||||
return c
|
||||
}
|
||||
|
||||
c.suffix = res[2]
|
||||
c.valid = true
|
||||
}
|
||||
c.cmd = strings.TrimSpace(c.cmd)
|
||||
c.suffix = strings.TrimSpace(c.suffix)
|
||||
|
||||
return c
|
||||
}
|
||||
|
||||
func getRandomEntry(c cmd) string {
|
||||
// TODO: increment counter
|
||||
// if database entry exists: set tag / group and run query
|
||||
task := "select distinct l.content from line l, brain b, tag t"
|
||||
if len(c.groups) > 0 {
|
||||
task = fmt.Sprintf("%s, groups g", task)
|
||||
}
|
||||
task = fmt.Sprintf("%s where l.id = b.line_id and t.id = b.tag_id", task)
|
||||
task = fmt.Sprintf("%s and t.id = %s", task, c.cmd)
|
||||
if len(c.groups) > 0 {
|
||||
task = fmt.Sprintf("%s and g.id = b.group_id and (", task)
|
||||
for i, group := range c.groups {
|
||||
task = fmt.Sprintf("%sg.id = %d", task, group)
|
||||
if i < (len(c.groups) - 1) {
|
||||
task = fmt.Sprintf("%s or ", task)
|
||||
} else {
|
||||
task = fmt.Sprintf("%s)", task)
|
||||
}
|
||||
}
|
||||
}
|
||||
return fmt.Sprintf("%s ORDER BY RANDOM() LIMIT 1", task)
|
||||
}
|
||||
|
||||
// line:
|
||||
// >befehl <[groups]> <name>
|
||||
// befehl ist genau ein wort
|
||||
func parsemsg(msg irc_msg, foo bot) bool {
|
||||
if len(msg.msg) <= 0 {
|
||||
return false
|
||||
}
|
||||
if !in(msg.msg[0], begin_char) {
|
||||
return false
|
||||
}
|
||||
msg.msg = msg.msg[1:]
|
||||
|
||||
c := filter(msg.msg)
|
||||
if !c.valid {
|
||||
LOG_WARN.Printf("non valid input found.\n")
|
||||
return false
|
||||
}
|
||||
if c.cmd == "" {
|
||||
LOG_WARN.Printf("no command provided.\n")
|
||||
return false
|
||||
}
|
||||
|
||||
sorter_row, err := db.Query(fmt.Sprintf("select id, tag_id, groups_allow, name_allow, has_groups from sorter where name = '%s'", c.cmd))
|
||||
checkErr(err)
|
||||
if sorter_row.Next() {
|
||||
var sorter_id string
|
||||
var tag_id string
|
||||
var groups_allow int
|
||||
var name_allow int
|
||||
var has_groups int
|
||||
sorter_row.Scan(&sorter_id, &tag_id, &groups_allow, &name_allow, &has_groups)
|
||||
|
||||
if groups_allow != 0 {
|
||||
// warning: not allowed
|
||||
c.groups = nil // use c.groups[:0] to keep allocated space
|
||||
}
|
||||
if name_allow != 0 && !c.add {
|
||||
// warning: not allowed
|
||||
c.suffix = ""
|
||||
}
|
||||
|
||||
c.cmd = tag_id
|
||||
|
||||
if has_groups == 0 {
|
||||
sorter_groups_row, err := db.Query(fmt.Sprintf("select group_id from sorter_groups where sorter_id = '%s'", sorter_id))
|
||||
checkErr(err)
|
||||
if sorter_groups_row.Next() {
|
||||
var group_id int
|
||||
sorter_groups_row.Scan(&group_id)
|
||||
c.groups = append(c.groups, group_id)
|
||||
}
|
||||
sorter_groups_row.Close()
|
||||
}
|
||||
c.groups = unique(c.groups)
|
||||
sorter_row.Close()
|
||||
} else {
|
||||
LOG_WARN.Printf("no sorter entry, no translation possible\n")
|
||||
return false
|
||||
}
|
||||
|
||||
if c.add {
|
||||
if (len(c.suffix) <= 0) {
|
||||
return false;
|
||||
}
|
||||
// insert into database
|
||||
statement, err := db.Prepare("insert into line (content, author) values (?,?)")
|
||||
checkErr(err)
|
||||
_, err = statement.Exec(c.suffix, msg.author)
|
||||
checkErr(err)
|
||||
defer statement.Close()
|
||||
|
||||
// get ID of content...
|
||||
task := fmt.Sprintf("select l.id from line l where l.content = '%s'", c.suffix)
|
||||
row, err := db.Query(task)
|
||||
checkErr(err)
|
||||
line_id := 0
|
||||
if row.Next() { row.Scan(&line_id) }
|
||||
row.Close()
|
||||
LOG_INFO.Printf(c.cmd)
|
||||
if line_id == 0 {
|
||||
LOG_WARN.Printf("no entry for adding")
|
||||
return false
|
||||
}
|
||||
|
||||
// for tag and all groups
|
||||
if len(c.groups) == 0 {
|
||||
stat, err := db.Prepare("insert into brain(line_id, tag_id) values (?,?)")
|
||||
checkErr(err)
|
||||
_, err = stat.Exec(line_id, c.cmd)
|
||||
checkErr(err)
|
||||
LOG_INFO.Printf("inserted foo! \n")
|
||||
defer stat.Close()
|
||||
} else {
|
||||
stat, err := db.Prepare("insert into brain(line_id, tag_id, group_id) values (?,?,?)")
|
||||
checkErr(err)
|
||||
for _, group := range c.groups {
|
||||
_, err = stat.Exec(line_id, c.cmd, group)
|
||||
checkErr(err)
|
||||
}
|
||||
LOG_INFO.Printf("inserted foo! \n")
|
||||
defer stat.Close()
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
task := getRandomEntry(c)
|
||||
|
||||
LOG_INFO.Printf(task)
|
||||
row, err := db.Query(task)
|
||||
checkErr(err)
|
||||
res := ""
|
||||
if row.Next() {
|
||||
row.Scan(&res)
|
||||
}
|
||||
row.Close()
|
||||
|
||||
if len(res) <= 0 {
|
||||
LOG_WARN.Printf("no entry found\n")
|
||||
res = "No matching entry found :("
|
||||
} else if len(c.suffix) > 0 {
|
||||
res = fmt.Sprintf("%s... %s", c.suffix, res)
|
||||
}
|
||||
sendmsg(foo.conn, msg.channel, res)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
/*
|
||||
func test() {
|
||||
db, err = sql.Open("sqlite3", "./boddle.db")
|
||||
checkErr(err)
|
||||
var msg irc_msg
|
||||
msg.channel = "testchannel"
|
||||
msg.author = "max mustermann"
|
||||
|
||||
// == invalid commands ==
|
||||
// empty cmd
|
||||
msg.msg = ">add [test me bro hahahaha] blob"
|
||||
parsemsg(msg)
|
||||
msg.msg = "> [test me bro hahahaha]"
|
||||
parsemsg(msg)
|
||||
msg.msg = ">[test me bro hahahaha] meow "
|
||||
parsemsg(msg)
|
||||
msg.msg = ">add [test me bro hahahaha] meow "
|
||||
parsemsg(msg)
|
||||
|
||||
// non-existent groups
|
||||
msg.msg = ">ohai [test me bro hahahaha]"
|
||||
parsemsg(msg)
|
||||
|
||||
// add command...? not implemented yet!
|
||||
msg.msg = ">add jokes blob"
|
||||
parsemsg(msg)
|
||||
msg.msg = ">add test [test me bro hahahaha] meow "
|
||||
parsemsg(msg)
|
||||
|
||||
// ok command \o/
|
||||
msg.msg = ">flirt [sweet] meow "
|
||||
parsemsg(msg)
|
||||
msg.msg = ">jokes [flach] meow "
|
||||
parsemsg(msg)
|
||||
msg.msg = ">hate [sweet] blobfisch "
|
||||
parsemsg(msg)
|
||||
msg.msg = ">radschlag [science]"
|
||||
parsemsg(msg)
|
||||
}
|
||||
*/
|
||||
Loading…
Add table
Add a link
Reference in a new issue