Automatic group adding

This commit is contained in:
Horscchtey 2022-02-03 21:08:20 +00:00
commit fe7055298a
4 changed files with 178 additions and 162 deletions

311
boddle.go
View file

@ -8,8 +8,9 @@ import _ "github.com/mattn/go-sqlite3"
type irc_msg struct { type irc_msg struct {
channel string channel string
msg string msg string
author string author string
retmsg string
} }
type cmd struct { type cmd struct {
@ -65,20 +66,6 @@ func unique_int(intSlice []int) []int {
return list 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 // function to split advise message correctly
func filter(msg string, foo bot) cmd { func filter(msg string, foo bot) cmd {
var c cmd var c cmd
@ -125,17 +112,17 @@ func filter(msg string, foo bot) cmd {
LOG_WARN.Printf("invalid query.") LOG_WARN.Printf("invalid query.")
return c return c
} }
group_id := 0
if rows.Next() { if rows.Next() {
group_id := 0
rows.Scan(&group_id) rows.Scan(&group_id)
c.groups = append(c.groups, fmt.Sprintf("%d", group_id)) c.groups = append(c.groups, fmt.Sprintf("%d", group_id))
rows.Close()
} else { } else {
c.valid = false if c.add {
c.error = "Group name " + group + " is invalid." c.groups = append(c.groups, addgroups([]string{group}, nil)...)
rows.Close() }
return c
} }
rows.Close()
defer stmt.Close()
} }
c.suffix = res[3] c.suffix = res[3]
c.valid = true c.valid = true
@ -158,6 +145,7 @@ func filter(msg string, foo bot) cmd {
} }
c.cmd = strings.TrimSpace(c.cmd) c.cmd = strings.TrimSpace(c.cmd)
c.suffix = strings.TrimSpace(c.suffix) c.suffix = strings.TrimSpace(c.suffix)
c.groups = unique_str(c.groups)
return c return c
} }
@ -174,23 +162,162 @@ func getRandomEntry(c cmd) string {
return task 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: // line:
// >befehl <[groups]> <name> // >befehl <[groups]> <name>
// befehl ist genau ein wort // befehl ist genau ein wort
func parsemsg(msg irc_msg, foo bot) bool { func parsemsg(msg *irc_msg, foo bot) bool {
if len(msg.msg) <= 0 { if len((*msg).msg) <= 0 {
return false return false
} }
if !in(msg.msg[0], begin_char) { if !in((*msg).msg[0], begin_char) {
return false 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 { if !c.valid {
LOG_WARN.Printf("non valid input found.\n") LOG_WARN.Printf("non valid input found.\n")
if c.error != "" { 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 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 // hard code 'groups' to add new groups to the groups-table
if c.add && (c.cmd == "groups" || c.cmd == "group") { if c.add && (c.cmd == "groups" || c.cmd == "group") {
if (c.groups != nil) { if (c.groups != nil) {
sendmsg(foo.conn, msg.channel, "Ignoring groups for the groups-adding. Well, what were you expecting...?") (*msg).retmsg = "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! :(")
} }
addgroups(strings.Fields((&c).suffix), msg)
return false 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)) // have a look at sorter table if command is valid
checkErr(err) if !checkSorter(msg, &c) {
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...")
return false return false
} }
// new line for database
if c.add { if c.add {
// if there is nothing to add, just return. :-) // if there is nothing to add, just return. :-)
if (len(c.suffix) <= 0) { if (len(c.suffix) <= 0) {
return false; return false;
} }
c.suffix = strings.Replace(c.suffix,"\"","'", -1) c.suffix = strings.Replace(c.suffix,"\"","'", -1)
LOG_WARN.Printf("adding new stuff: %s from %s.\n", c.suffix, msg.author) sendmsg(foo.conn, "horscchtey", addLine(msg, c.suffix, c.groups, c.cmd))
} else {
res, err := db.Exec("insert into line (content, author) values (?,?)", c.suffix, msg.author) chooseEntry(msg, &c)
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
} }
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 return true
} }

6
bot.go
View file

@ -31,12 +31,6 @@ func main() {
if err := configo.Load("./boddle.toml", &boddle.Conf); err != nil { if err := configo.Load("./boddle.toml", &boddle.Conf); err != nil {
log.Fatal(err) log.Fatal(err)
} }
// boddle := bot {
// name: "boddle",
// channel: []string{"#faui2k16", "#fau", "#sigbike", "#sigfreibad"},
// port: 6667,
// server: "irc.fau.de",
// }
LOG_INFO.Println("bot started!") LOG_INFO.Println("bot started!")

8
conf.go Normal file
View file

@ -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"`
}

View file

@ -32,6 +32,7 @@ func scanline_privmsg (msg string) irc_msg {
if ! strings.HasPrefix(irc.channel, "#") { if ! strings.HasPrefix(irc.channel, "#") {
irc.channel = irc.author irc.channel = irc.author
} }
irc.retmsg = ""
return irc return irc
} }
@ -44,12 +45,9 @@ func listenToIRC (foo bot) <-chan []byte {
return nil return nil
} }
var line []byte
var err error
go func() { go func() {
for { for {
line, err = reader.ReadBytes('\n') line, err := reader.ReadString('\n')
if err != nil { if err != nil {
LOG_ERR.Printf("Error while reading bytes from connection.\n") LOG_ERR.Printf("Error while reading bytes from connection.\n")
dead = true dead = true
@ -57,7 +55,7 @@ func listenToIRC (foo bot) <-chan []byte {
return return
} }
c <- line c <- []byte(line)
if bytes.Contains([]byte(line), []byte("PING :")) { if bytes.Contains([]byte(line), []byte("PING :")) {
v := []byte(bytes.Replace([]byte(line), []byte("PING"), []byte("PONG"), 1)) 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")) { if !bytes.Contains([]byte(line), []byte("PRIVMSG")) {
continue continue
} }
msg := scanline_privmsg(string(line))
parsemsg(scanline_privmsg(string(line)), foo) parsemsg(&msg, foo)
if msg.retmsg != "" {
sendmsg(foo.conn, msg.channel, msg.retmsg)
}
} }
} () } ()
return c return c