309 lines
8 KiB
Go
309 lines
8 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
"fmt"
|
|
"regexp"
|
|
"database/sql"
|
|
_ "github.com/mattn/go-sqlite3"
|
|
)
|
|
|
|
var begin_char = []byte{'-', '<'}
|
|
var db *sql.DB
|
|
var err error
|
|
|
|
|
|
// function to split advise message correctly
|
|
func filter(msg string, foo bot) cmd {
|
|
var c cmd
|
|
|
|
if len(msg) <= 0 {
|
|
c.error = "Message is too short."
|
|
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 {
|
|
c.error = "You entered weird stuff, please try again."
|
|
return c
|
|
}
|
|
|
|
c.cmd = res[1]
|
|
if c.cmd == "" {
|
|
LOG_WARN.Printf("empty cmd\n")
|
|
c.error = "The command was empty. A non-empty command is needed."
|
|
return c
|
|
}
|
|
|
|
// substitute group names with ids
|
|
groups := strings.Fields(res[2])
|
|
stmt, err := db.Prepare("select id from groups where name = ?")
|
|
checkErr(err)
|
|
|
|
for _, group := range groups {
|
|
rows, err := stmt.Query(group)
|
|
if err != nil {
|
|
LOG_WARN.Printf("invalid query.")
|
|
return c
|
|
}
|
|
if rows.Next() {
|
|
group_id := 0
|
|
rows.Scan(&group_id)
|
|
c.groups = append(c.groups, fmt.Sprintf("%d", group_id))
|
|
} else {
|
|
if c.add {
|
|
c.groups = append(c.groups, addgroups([]string{group}, nil)...)
|
|
}
|
|
}
|
|
rows.Close()
|
|
defer stmt.Close()
|
|
}
|
|
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 {
|
|
c.error = "You entered weird stuff, please try again."
|
|
return c
|
|
}
|
|
c.cmd = res[1]
|
|
if c.cmd == "" {
|
|
c.error = "The command was empty. A non-empty command is needed."
|
|
return c
|
|
}
|
|
|
|
c.suffix = res[2]
|
|
c.valid = true
|
|
}
|
|
c.cmd = strings.TrimSpace(c.cmd)
|
|
c.suffix = strings.TrimSpace(c.suffix)
|
|
c.groups = unique_str(c.groups)
|
|
|
|
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"
|
|
task += " where l.id = b.line_id and t.id = b.tag_id and t.id = " + c.cmd
|
|
if len(c.groups) > 0 {
|
|
task += " and l.id in (select line_id from brain where group_id = " + strings.Join(c.groups," intersect select line_id from brain where group_id = ") + ")"
|
|
}
|
|
task += " ORDER BY RANDOM() LIMIT 1"
|
|
return task
|
|
}
|
|
|
|
func addgroups(new_groups []string, msg *irc_msg) []string {
|
|
stat_sel, err := db.Prepare("select id from groups where name = ?")
|
|
checkErr(err)
|
|
stat_ins, err := db.Prepare("insert into groups(name) values (?)")
|
|
checkErr(err)
|
|
var groups_added []string
|
|
var groupids_added []string
|
|
for _, group := range new_groups {
|
|
ret, err := stat_sel.Query(group)
|
|
if ret.Next() {
|
|
ret.Close()
|
|
continue
|
|
}
|
|
groupid_res, err := stat_ins.Exec(group)
|
|
checkErr(err)
|
|
defer stat_ins.Close()
|
|
groupid, err := groupid_res.LastInsertId()
|
|
checkErr(err)
|
|
groupids_added = append(groupids_added, fmt.Sprintf("%d", groupid))
|
|
groups_added = append(groups_added, group)
|
|
}
|
|
if msg != nil {
|
|
if len(groups_added) > 0 {
|
|
(*msg).retmsg = "Added " + strings.Join(groups_added, ", ") + " to groups-table!"
|
|
} else {
|
|
(*msg).retmsg = "Added nothing to groups-table! :("
|
|
}
|
|
}
|
|
return groupids_added
|
|
}
|
|
|
|
func checkSorter(msg *irc_msg, c *cmd) bool {
|
|
sorter_row_sel, err := db.Prepare("select id, tag_id, groups_allow, name_allow, has_groups from sorter where name = ?")
|
|
checkErr(err)
|
|
sorter_row, err := sorter_row_sel.Query((*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)
|
|
sorter_row.Close()
|
|
|
|
if groups_allow != 0 {
|
|
(*msg).retmsg = "This command does not allow groups. :("
|
|
return false
|
|
}
|
|
if name_allow != 0 && !(*c).add {
|
|
// warning: not allowed
|
|
(*c).suffix = ""
|
|
}
|
|
|
|
(*c).cmd = tag_id
|
|
|
|
if has_groups == 0 {
|
|
group_sel, err := db.Prepare("select group_id from sorter_groups where sorter_id = ?")
|
|
checkErr(err)
|
|
sorter_groups_row, err := group_sel.Query(sorter_id)
|
|
//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, fmt.Sprintf("%d", group_id))
|
|
}
|
|
sorter_groups_row.Close()
|
|
if (*c).add {
|
|
var tag_name string
|
|
tag_name_row, err := db.Query(fmt.Sprintf("select name from tag where id = %s", tag_id))
|
|
checkErr(err)
|
|
if tag_name_row.Next() {
|
|
tag_name_row.Scan(&tag_name)
|
|
}
|
|
tag_name_row.Close()
|
|
LOG_WARN.Printf("Alias used. Tell the user about that.\n")
|
|
(*msg).retmsg = "You're using an alias. Please try again with 'add " + tag_name + " [" + strings.Join((*c).groups, " ") + "]. Thanks!"
|
|
return false
|
|
}
|
|
}
|
|
} else {
|
|
LOG_WARN.Printf("no sorter entry, no translation possible\n")
|
|
(*msg).retmsg = "No entry found, sorry..."
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
func chooseEntry(msg *irc_msg, c *cmd) {
|
|
task := getRandomEntry(*c)
|
|
|
|
LOG_INFO.Printf(task)
|
|
row, err := db.Query(task)
|
|
checkErr(err)
|
|
if row.Next() {
|
|
row.Scan(&((*msg).retmsg))
|
|
}
|
|
row.Close()
|
|
|
|
if len((*msg).retmsg) <= 0 {
|
|
LOG_WARN.Printf("no entry found\n")
|
|
(*msg).retmsg = "No matching entry found :("
|
|
} else if len((*c).suffix) > 0 {
|
|
(*msg).retmsg = fmt.Sprintf("%s... %s", (*c).suffix, (*msg).retmsg)
|
|
}
|
|
}
|
|
|
|
func addLine(msg *irc_msg, line string, groups []string, cmd string) string {
|
|
LOG_WARN.Printf("adding new stuff: %s from %s.\n", line, (*msg).author)
|
|
|
|
res, err := db.Exec("insert into line (content, author) values (?,?)", line, (*msg).author)
|
|
checkErr(err)
|
|
LOG_WARN.Printf("added line to table.\n")
|
|
|
|
// get ID of content...
|
|
line_id, err := res.LastInsertId();
|
|
checkErr(err)
|
|
|
|
LOG_WARN.Printf("line_id: %d, tag_id: %s, groups: %s\n", line_id, cmd, strings.Join(groups, "-"))
|
|
// for tag and all groups
|
|
if len(groups) == 0 {
|
|
stat, err := db.Prepare("insert into brain(line_id, tag_id) values (?,?)")
|
|
checkErr(err)
|
|
_, err = stat.Exec(line_id, cmd)
|
|
checkErr(err)
|
|
defer stat.Close()
|
|
} else {
|
|
stat, err := db.Prepare("insert into brain(line_id, tag_id, group_id) values (?,?,?)")
|
|
checkErr(err)
|
|
for _, group := range groups {
|
|
_, err = stat.Exec(line_id, cmd, group)
|
|
checkErr(err)
|
|
}
|
|
defer stat.Close()
|
|
}
|
|
(*msg).retmsg = fmt.Sprintf("success adding new super funny enjoyable line with ID %d!", line_id)
|
|
return fmt.Sprintf("new line: > %s < (ID %d), into groups %s", line, line_id, strings.Join(groups,","))
|
|
}
|
|
// 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 (*msg).msg == "<3" {
|
|
(*msg).msg = string(begin_char[0]) + "flirt kreisi"
|
|
}
|
|
|
|
if !in((*msg).msg[0], begin_char) {
|
|
return false
|
|
}
|
|
(*msg).msg = (*msg).msg[1:]
|
|
|
|
c := filter((*msg).msg, foo)
|
|
if !c.valid {
|
|
LOG_WARN.Printf("non valid input found.\n")
|
|
if c.error != "" {
|
|
(*msg).retmsg = "Falscher input du SP-Ersti... " + c.error
|
|
}
|
|
return false
|
|
}
|
|
LOG_WARN.Printf("line was parsed, continue with evaluation.\n")
|
|
if c.cmd == "" {
|
|
LOG_WARN.Printf("no command provided.\n")
|
|
return false
|
|
}
|
|
if c.cmd == "help" {
|
|
return false
|
|
}
|
|
// hard code 'groups' to add new groups to the groups-table
|
|
if c.add && (c.cmd == "groups" || c.cmd == "group") {
|
|
if (c.groups != nil) {
|
|
(*msg).retmsg = "Ignoring groups for the groups-adding. Well, what were you expecting...?"
|
|
}
|
|
addgroups(strings.Fields((&c).suffix), msg)
|
|
return false
|
|
}
|
|
|
|
// have a look at sorter table if command is valid
|
|
if !checkSorter(msg, &c) {
|
|
return false
|
|
}
|
|
|
|
// new line for database
|
|
if c.add {
|
|
// if there is nothing to add, just return. :-)
|
|
if (len(c.suffix) <= 0) {
|
|
return false;
|
|
}
|
|
c.suffix = strings.Replace(c.suffix,"\"","'", -1)
|
|
sendmsg(foo.conn, "horscchtey", addLine(msg, c.suffix, c.groups, c.cmd))
|
|
} else {
|
|
chooseEntry(msg, &c)
|
|
}
|
|
return true
|
|
}
|