diff --git a/boddle.db b/boddle.db index 3a7dc7a..23d8f99 100644 Binary files a/boddle.db and b/boddle.db differ diff --git a/boddle.go b/boddle.go index 3f2f6f9..38e3b62 100644 --- a/boddle.go +++ b/boddle.go @@ -16,11 +16,12 @@ type cmd struct { valid bool add bool cmd string - groups []int + groups []string suffix string + error string } -var begin_char = []byte{'<'} +var begin_char = []byte{'-', '<'} var db *sql.DB var err error @@ -39,7 +40,19 @@ func in (a byte, arr []byte) bool { return false } -func unique(intSlice []int) []int { +func unique_str(stringSlice []string) []string { + keys := make(map[string]bool) + list := []string{} + for _, entry := range stringSlice { + if _, value := keys[entry]; !value { + keys[entry] = true + list = append(list, entry) + } + } + return list +} + +func unique_int(intSlice []int) []int { keys := make(map[int]bool) list := []int{} for _, entry := range intSlice { @@ -51,11 +64,26 @@ func unique(intSlice []int) []int { return list } +/* +func unique[T any](tSlice []T) []T { + keys := make(map[T]bool) + list := []T{} + for _, entry := range tSlice { + 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 { +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 } @@ -71,33 +99,41 @@ func filter(msg string) cmd { } if (strings.Contains(msg, "[") && strings.Contains(msg, "]")) { - re, _ := regexp.Compile(`\s*(\w*)\s*\[(.*)\]\s*(.*)\s*`) + 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 } - // TODO: substitute group names with ids + // 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) + stmt, err := db.Prepare("select id from groups where name = ?") + checkErr(err) - row, err := db.Query(task) + for _, group := range groups { + rows, err := stmt.Query(group) if err != nil { - LOG_WARN.Printf("no such column: %s\n", i) + LOG_WARN.Printf("invalid query.") 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) + if rows.Next() { + rows.Scan(&group_id) + c.groups = append(c.groups, fmt.Sprintf("%d", group_id)) + rows.Close() + } else { + c.valid = false + c.error = "Group name " + group + " is invalid." + rows.Close() + return c } } c.suffix = res[3] @@ -107,10 +143,12 @@ func filter(msg string) cmd { 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 } @@ -127,23 +165,12 @@ 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 = fmt.Sprintf("%s, groups g", task) + 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 = 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) + task += " ORDER BY RANDOM() LIMIT 1" + return task } // line: @@ -158,9 +185,12 @@ func parsemsg(msg irc_msg, foo bot) bool { } msg.msg = msg.msg[1:] - c := filter(msg.msg) + c := filter(msg.msg, foo) if !c.valid { LOG_WARN.Printf("non valid input found.\n") + if c.error != "" { + sendmsg(foo.conn, msg.channel, "Falscher input du SP-Ersti... " + c.error) + } return false } if c.cmd == "" { @@ -183,28 +213,44 @@ func parsemsg(msg irc_msg, foo bot) bool { 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 + sendmsg(foo.conn, msg.channel, "This command does not allow groups. :(") + return false } if name_allow != 0 && !c.add { // warning: not allowed + sendmsg(foo.conn, msg.channel, "This command ignores provided names. :(") c.suffix = "" } c.cmd = tag_id + var sorter_groups []string 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) + if c.add { + sorter_groups = append(sorter_groups, fmt.Sprintf("%d", group_id)) + } else { + c.groups = append(c.groups, fmt.Sprintf("%d", group_id)) + } } sorter_groups_row.Close() } - c.groups = unique(c.groups) sorter_row.Close() + if c.add { + var tag_name string + tag_name_row, err := db.Query(fmt.Sprintf("select name from tag where id = %d", tag_id)) + checkErr(err) + if tag_name_row.Next() { + tag_name_row.Scan(&tag_name) + } + tag_name_row.Close() + sendmsg(foo.conn, msg.channel, "You're using an alias. Please try again with 'add" + tag_name + " [" + strings.Join(sorter_groups, " ") + "]. Thanks!") + return false + } } else { LOG_WARN.Printf("no sorter entry, no translation possible\n") sendmsg(foo.conn, msg.channel, "No entry found, sorry...") @@ -258,7 +304,7 @@ func parsemsg(msg irc_msg, foo bot) bool { defer stat.Close() } sendmsg(foo.conn, msg.channel, fmt.Sprintf("success adding new super funny enjoyable line with ID %d!", line_id)) - sendmsg(foo.conn, "horscchtey", fmt.Sprintf("new line: > %s < (ID %d)", c.suffix, line_id)) + sendmsg(foo.conn, "horscchtey", fmt.Sprintf("new line: > %s < (ID %d), into groups %s", c.suffix, line_id, strings.Join(c.groups,","))) return true } diff --git a/bot.go b/bot.go index 2559d02..330b58a 100644 --- a/bot.go +++ b/bot.go @@ -23,7 +23,7 @@ func main() { boddle := bot { name: "boddle", - channel: []string{"#faui2k16", "#fau", "#sigbike", "#sigfreibad", "#faui2k17"}, + channel: []string{"#faui2k16", "#fau", "#sigbike", "#sigfreibad"}, port: 6667, server: "irc.fau.de", } diff --git a/logging.go b/logging.go index 3a905d1..02769c6 100644 --- a/logging.go +++ b/logging.go @@ -12,11 +12,7 @@ var ( ) func LOG_init() { - file, err := os.OpenFile("logs.txt", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0666) - if err != nil { - log.Fatal(err) - } - defer file.Close() + file := os.Stdout LOG_INFO = log.New(file, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile) LOG_WARN = log.New(file, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile)