From fe7055298a956d2a2c56f487c7638ce7da040118 Mon Sep 17 00:00:00 2001 From: Horscchtey Date: Thu, 3 Feb 2022 21:08:20 +0000 Subject: [PATCH] Automatic group adding --- boddle.go | 311 ++++++++++++++++++++++++++++-------------------------- bot.go | 6 -- conf.go | 8 ++ ircfoo.go | 15 +-- 4 files changed, 178 insertions(+), 162 deletions(-) create mode 100644 conf.go diff --git a/boddle.go b/boddle.go index 86604cf..1e78497 100644 --- a/boddle.go +++ b/boddle.go @@ -8,8 +8,9 @@ import _ "github.com/mattn/go-sqlite3" type irc_msg struct { channel string - msg string + msg string author string + retmsg string } type cmd struct { @@ -65,20 +66,6 @@ func unique_int(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, foo bot) cmd { var c cmd @@ -125,17 +112,17 @@ func filter(msg string, foo bot) cmd { LOG_WARN.Printf("invalid query.") return c } - group_id := 0 if rows.Next() { + group_id := 0 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 + if c.add { + c.groups = append(c.groups, addgroups([]string{group}, nil)...) + } } + rows.Close() + defer stmt.Close() } c.suffix = res[3] c.valid = true @@ -158,6 +145,7 @@ func filter(msg string, foo bot) cmd { } c.cmd = strings.TrimSpace(c.cmd) c.suffix = strings.TrimSpace(c.suffix) + c.groups = unique_str(c.groups) return c } @@ -174,23 +162,162 @@ func getRandomEntry(c cmd) string { 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 = %d", 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: %d, 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]> // befehl ist genau ein wort -func parsemsg(msg irc_msg, foo bot) bool { - if len(msg.msg) <= 0 { +func parsemsg(msg *irc_msg, foo bot) bool { + if len((*msg).msg) <= 0 { return false } - if !in(msg.msg[0], begin_char) { + if !in((*msg).msg[0], begin_char) { return false } - msg.msg = msg.msg[1:] + (*msg).msg = (*msg).msg[1:] - c := filter(msg.msg, foo) + 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) + (*msg).retmsg = "Falscher input du SP-Ersti... " + c.error } return false } @@ -205,141 +332,27 @@ func parsemsg(msg irc_msg, foo bot) bool { // hard code 'groups' to add new groups to the groups-table if c.add && (c.cmd == "groups" || c.cmd == "group") { if (c.groups != nil) { - sendmsg(foo.conn, msg.channel, "Ignoring groups for the groups-adding. Well, what were you expecting...?") - } - new_groups := strings.Fields(c.suffix) - 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 - for _, group := range new_groups { - fmt.Println(group) - ret, err := stat_sel.Query(group) - if ret.Next() { - ret.Close() - continue - } - _, err = stat_ins.Exec(group) - checkErr(err) - groups_added = append(groups_added, group) - } - if len(groups_added) > 0 { - sendmsg(foo.conn, msg.channel, "Added " + strings.Join(groups_added, ", ") + " to groups-table!") - } else { - sendmsg(foo.conn, msg.channel, "Added nothing to groups-table! :(") + (*msg).retmsg = "Ignoring groups for the groups-adding. Well, what were you expecting...?" } + addgroups(strings.Fields((&c).suffix), msg) 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) - sorter_row.Close() - - if groups_allow != 0 { - sendmsg(foo.conn, msg.channel, "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 { - 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 = %d", 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") - sendmsg(foo.conn, msg.channel, "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") - sendmsg(foo.conn, msg.channel, "No entry found, sorry...") + // 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) - LOG_WARN.Printf("adding new stuff: %s from %s.\n", c.suffix, msg.author) - - res, err := db.Exec("insert into line (content, author) values (?,?)", c.suffix, 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: %d, groups: %s\n", line_id, c.cmd, strings.Join(c.groups, "-")) - // 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() - } - 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), into groups %s", c.suffix, line_id, strings.Join(c.groups,","))) - return true + sendmsg(foo.conn, "horscchtey", addLine(msg, c.suffix, c.groups, c.cmd)) + } else { + chooseEntry(msg, &c) } - - 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 } diff --git a/bot.go b/bot.go index 19bcce1..afc9c04 100644 --- a/bot.go +++ b/bot.go @@ -31,12 +31,6 @@ func main() { if err := configo.Load("./boddle.toml", &boddle.Conf); err != nil { log.Fatal(err) } -// boddle := bot { -// name: "boddle", -// channel: []string{"#faui2k16", "#fau", "#sigbike", "#sigfreibad"}, -// port: 6667, -// server: "irc.fau.de", -// } LOG_INFO.Println("bot started!") diff --git a/conf.go b/conf.go new file mode 100644 index 0000000..ccccef9 --- /dev/null +++ b/conf.go @@ -0,0 +1,8 @@ +package main + +type Boddle struct { + name string `cfg:"name; boddle; printableascii; IRC nick of bot"` + channels []string `cfg:"channels; required; printableascii; Channel list to join to"` + server string `cfg:"server; required; netaddr; Server name to connect to"` + database string `cfg:"database; ./boddle.db; path; Path to database"` +} diff --git a/ircfoo.go b/ircfoo.go index 2a3e2bd..cb04aac 100644 --- a/ircfoo.go +++ b/ircfoo.go @@ -32,6 +32,7 @@ func scanline_privmsg (msg string) irc_msg { if ! strings.HasPrefix(irc.channel, "#") { irc.channel = irc.author } + irc.retmsg = "" return irc } @@ -44,12 +45,9 @@ func listenToIRC (foo bot) <-chan []byte { return nil } - var line []byte - var err error - go func() { for { - line, err = reader.ReadBytes('\n') + line, err := reader.ReadString('\n') if err != nil { LOG_ERR.Printf("Error while reading bytes from connection.\n") dead = true @@ -57,7 +55,7 @@ func listenToIRC (foo bot) <-chan []byte { return } - c <- line + c <- []byte(line) if bytes.Contains([]byte(line), []byte("PING :")) { v := []byte(bytes.Replace([]byte(line), []byte("PING"), []byte("PONG"), 1)) @@ -69,8 +67,11 @@ func listenToIRC (foo bot) <-chan []byte { if !bytes.Contains([]byte(line), []byte("PRIVMSG")) { continue } - - parsemsg(scanline_privmsg(string(line)), foo) + msg := scanline_privmsg(string(line)) + parsemsg(&msg, foo) + if msg.retmsg != "" { + sendmsg(foo.conn, msg.channel, msg.retmsg) + } } } () return c