diff --git a/boddle.go b/boddle.go index c1bc72c..50a6807 100644 --- a/boddle.go +++ b/boddle.go @@ -1,70 +1,17 @@ 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 - retmsg string -} - -type cmd struct { - valid bool - add bool - cmd string - groups []string - suffix string - error string -} +import ( + "strings" + "fmt" + "regexp" + "database/sql" + _ "github.com/mattn/go-sqlite3" +) var begin_char = []byte{'-', '<'} var db *sql.DB var err error -func checkErr(err error) { - if err != nil { - fmt.Printf("::::ERROR:::: %s\n", err) - panic(err) - } -} - -func in (a byte, arr []byte) bool { - for _, x := range arr { - if x == a { - return true - } - } - return false -} - -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 { - 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 { @@ -232,7 +179,7 @@ func checkSorter(msg *irc_msg, c *cmd) bool { 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)) + 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) @@ -281,7 +228,7 @@ func addLine(msg *irc_msg, line string, groups []string, cmd string) string { 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, "-")) + 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 (?,?)") diff --git a/bot.go b/bot.go index afc9c04..9fd056e 100644 --- a/bot.go +++ b/bot.go @@ -6,22 +6,94 @@ import ( "fmt" "net" "time" + "bufio" + "bytes" + "strings" + "database/sql" configo "github.com/distributedio/configo" _ "github.com/mattn/go-sqlite3" ) -var dead = true - -type Config 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"` +func sendmsg (conn net.Conn, channel string, msg string) { + mesg := fmt.Sprintf("PRIVMSG %s :%s\r\n", channel, msg) + fmt.Printf(mesg) + conn.Write([]byte(mesg)) } -type bot struct { - Conf Config - conn net.Conn +func scanline_privmsg (msg string) irc_msg { + var irc irc_msg + + msg = msg[1:] + t := strings.Split(msg, "!") + irc.author, irc.channel = t[0], t[1] + t = strings.Split(irc.channel, "PRIVMSG ") + irc.channel = t[1] + t = strings.Split(irc.channel, " :") + irc.channel, irc.msg = t[0], t[1] + t = strings.Split(irc.msg, "\r\n") + irc.msg = strings.TrimSpace(t[0]) + if ! strings.HasPrefix(irc.channel, "#") { + irc.channel = irc.author + } + irc.retmsg = "" + return irc +} + +func listenToIRC (foo bot) <-chan []byte { + c := make(chan []byte) + reader := bufio.NewReader(foo.conn) + db, err = sql.Open("sqlite3", foo.Conf.Database) + if err != nil { + LOG_ERR.Printf("opening database failed") + return nil + } + + go func() { + for { + line, err := reader.ReadString('\n') + if err != nil { + LOG_ERR.Printf("Error while reading bytes from connection.\n") + close(c) + return + } + + c <- []byte(line) + + if bytes.Contains([]byte(line), []byte("PING :")) { + v := []byte(bytes.Replace([]byte(line), []byte("PING"), []byte("PONG"), 1)) + fmt.Printf(string(v[:])) + foo.conn.Write(v) + } else if bytes.Contains([]byte(line), []byte("PRIVMSG")) { + msg := scanline_privmsg(string(line)) + parsemsg(&msg, foo) + if msg.retmsg != "" { + sendmsg(foo.conn, msg.channel, msg.retmsg) + } + } + } + } () + return c +} + +func connect(boddle *bot) <-chan []byte { + conn, err := net.Dial("tcp", (*boddle).Conf.Server) + + if err != nil { + fmt.Fprintf(os.Stderr, "Error while dialing server.") + LOG_ERR.Printf("Error while connecting to server.") + return nil + } + + (*boddle).conn = conn + + /* connect to irc */ + fmt.Fprintf((*boddle).conn, "NICK %s\r\n", (*boddle).Conf.Name) + fmt.Fprintf((*boddle).conn, "USER %s 1 1 1:%s\r\n", (*boddle).Conf.Name, (*boddle).Conf.Name) + for _, channel := range((*boddle).Conf.Channels) { + fmt.Fprintf((*boddle).conn, "JOIN %s\r\n", channel) + } + + return listenToIRC((*boddle)) } func main() { @@ -35,23 +107,21 @@ func main() { LOG_INFO.Println("bot started!") var botchan <-chan []byte - var line []byte - dead = true for { - if dead { - LOG_WARN.Println("died.") - for { - botchan = connect(boddle) - if botchan != nil { - break - } - time.Sleep(10 * time.Second) + botchan = connect(&boddle) + for { + select { + case res := <-botchan: + fmt.Println(string(res)) + case <-time.After(10 * time.Minute): + fmt.Println("timeout - 10 Minutes no ping received.") + // close channel, close connection + boddle.conn.Close() + goto Reconnect } - LOG_INFO.Println("reconnected.") - dead = false } - line = <-botchan - fmt.Fprintf(os.Stderr, string(line)) +Reconnect: + fmt.Println("trying to reconnect...") } } diff --git a/forraspidothis b/forraspidothis index 1bc0a64..d295ea6 100755 --- a/forraspidothis +++ b/forraspidothis @@ -9,7 +9,7 @@ export GOARCH=arm export GOARM=7 declare -a src -src+=(bot.go boddle.go logging.go ircfoo.go) +src+=(bot.go boddle.go logging.go helpers.go types.go) declare -i nproc="$(nproc)" go build -p ${nproc} "${src[@]}" diff --git a/helpers.go b/helpers.go new file mode 100644 index 0000000..f59c740 --- /dev/null +++ b/helpers.go @@ -0,0 +1,45 @@ +package main + +import ( + "fmt" +) + +func checkErr(err error) { + if err != nil { + fmt.Printf("::::ERROR:::: %s\n", err) + panic(err) + } +} + +func in (a byte, arr []byte) bool { + for _, x := range arr { + if x == a { + return true + } + } + return false +} + +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 { + if _, value := keys[entry]; !value { + keys[entry] = true + list = append(list, entry) + } + } + return list +} diff --git a/ircfoo.go b/ircfoo.go deleted file mode 100644 index cb04aac..0000000 --- a/ircfoo.go +++ /dev/null @@ -1,99 +0,0 @@ -package main - -import ( - "fmt" - "net" - "os" - "bufio" - "bytes" - "strings" - "database/sql" - _ "github.com/mattn/go-sqlite3" -) - -func sendmsg (conn net.Conn, channel string, msg string) { - mesg := fmt.Sprintf("PRIVMSG %s :%s\r\n", channel, msg) - fmt.Printf(mesg) - conn.Write([]byte(mesg)) -} - -func scanline_privmsg (msg string) irc_msg { - var irc irc_msg - - msg = msg[1:] - t := strings.Split(msg, "!") - irc.author, irc.channel = t[0], t[1] - t = strings.Split(irc.channel, "PRIVMSG ") - irc.channel = t[1] - t = strings.Split(irc.channel, " :") - irc.channel, irc.msg = t[0], t[1] - t = strings.Split(irc.msg, "\r\n") - irc.msg = strings.TrimSpace(t[0]) - if ! strings.HasPrefix(irc.channel, "#") { - irc.channel = irc.author - } - irc.retmsg = "" - return irc -} - -func listenToIRC (foo bot) <-chan []byte { - c := make(chan []byte) - reader := bufio.NewReader(foo.conn) - db, err = sql.Open("sqlite3", foo.Conf.Database) - if err != nil { - LOG_ERR.Printf("opening database failed") - return nil - } - - go func() { - for { - line, err := reader.ReadString('\n') - if err != nil { - LOG_ERR.Printf("Error while reading bytes from connection.\n") - dead = true - c <- []byte("killed it") - return - } - - c <- []byte(line) - - if bytes.Contains([]byte(line), []byte("PING :")) { - v := []byte(bytes.Replace([]byte(line), []byte("PING"), []byte("PONG"), 1)) - fmt.Printf(string(v[:])) - foo.conn.Write(v) - continue - } - - if !bytes.Contains([]byte(line), []byte("PRIVMSG")) { - continue - } - msg := scanline_privmsg(string(line)) - parsemsg(&msg, foo) - if msg.retmsg != "" { - sendmsg(foo.conn, msg.channel, msg.retmsg) - } - } - } () - return c -} - -func connect(boddle bot) <-chan []byte { - conn, err := net.Dial("tcp", boddle.Conf.Server) - - if err != nil { - fmt.Fprintf(os.Stderr, "Error while dialing server.") - LOG_ERR.Printf("Error while connecting to server.") - return nil - } - - boddle.conn = conn - - /* connect to irc */ - fmt.Fprintf(boddle.conn, "NICK %s\r\n", boddle.Conf.Name) - fmt.Fprintf(boddle.conn, "USER %s 1 1 1:%s\r\n", boddle.Conf.Name, boddle.Conf.Name) - for _, channel := range(boddle.Conf.Channels) { - fmt.Fprintf(boddle.conn, "JOIN %s\r\n", channel) - } - - return listenToIRC(boddle) -} diff --git a/logging.go b/logging.go index 02769c6..6c03744 100644 --- a/logging.go +++ b/logging.go @@ -12,9 +12,9 @@ var ( ) func LOG_init() { - file := os.Stdout + 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) - LOG_ERR = log.New(file, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile) + LOG_INFO = log.New(file, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile) + LOG_WARN = log.New(file, "WARNING: ", log.Ldate|log.Ltime|log.Lshortfile) + LOG_ERR = log.New(file, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile) } diff --git a/pepe.go b/pepe.go deleted file mode 100644 index 9ba9fd5..0000000 --- a/pepe.go +++ /dev/null @@ -1,40 +0,0 @@ -package main - -var pepe = []string{ -"░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░", -"░░░░░░░░░░░░░░░░░░░░░░░▓▓▒▒▒▒▒▒▓▓▒░░░░░░░░░▓▓░▓▓▒░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░", -"░░░░░░░░░░░░░░░░░░░ ▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓░▓▒▒▒▒▒▒▒▒▒▒▒▒▓░░ ░░░░░░░░░░░░░░░░░░░░░░░░░", -"░░░░░░░░░░░░░░░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▓░░░░░░░░░░░░░░░░░░░░░░░░░░░", -"░░░░░░░░░░░░░░░░░▓▒▒▒▒▒▒▓▓▓▒▒▒▒▒▒▒▓▓▓▒▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▓ ░░░░░░░░░░░░░░░░░░░░░░░░░", -"░░░░░░░░░░░░░░░▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓░░░░░░░░░░░░░░░░░░░░░░░░", -"░░░░░░░░░░░░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓░▓▓▒▒▓▓▓░░▒▒▒▒▒▒▓▓░░░░░▓▓▒▓░░░░░░░░░░░░░░░░░░░░░", -"░░░░░░░░░░░░░▓▓▒▒▒▒▒▒▒▒▒▒▒▓▓▒▓▓▓▒▒▒▒▒▒▒▒▓▓▓░▓▓▓▓▓▓▒▒▒▒▒▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░░", -"░░░░░░░░░░▒▒▒▓▒▒▒▒▒▒▒▒▒▓▒▓▓▓▒▒▒▒▒▒▒▒▓▓▓▒▒▒▒▓▒▒▒▒▓▓▓▒▒▓▓▓▒▒▒▒▓▓░░░░░░░░░░░░░░░░░░", -"░░░░░░░░░▓▒▒▒▓▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒▓▓▒░▒█░███░ ▒ ░█▓░████ ░░░░░░░░░░░░░░░░░░", -"░░░░░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓ ░████░ ██░ ▒ ██░██ ░██ ▒░░░░░░░░░░░░░░░░░░", -"░░░░░░ ▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▒▓▓▒███░███░▓▒▒░▒▒▓▓▓▓░░░▓▓▓▒▒▒▓▒░░░░░░░░░░░░░░░░░░░", -"░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒░░░░░░░░░░░░░░░░░░░░░", -"░░░░░▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▒▒▒▒▒▒▓▓▓▒▒▒▒▓▓░▒ ░░░░░░░░░░░░░░░░░░░░░░░", -"░░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓░░░░░░░░░░░░░░░░░░░░░░░", -"░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓░░░░░░░░░█░░▒▓█▓░█░░░░", -"░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓ ░░░░░░░█▒░█▒▒░▓▒█▒░░", -"░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓░▓▒▒▒▓▓░▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓░▓░▒░░▓░░▓▓▒░░▒▓█▓▒█░░", -"░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒░▒▒▒▒▒▓░░░░▓▓▓▓▓░░░▓▒▒▒░▒▒░░▒░▓█ ░█▒▒░░▒░▒▓▓░░", -"░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▒▒▒▒░▒▒▒▒▒▒▒▒▒▒▓▓▓▓░░░░░▓▓▓█▒█▒▒▒▒▒▒▒█░░░", -"░░░░░▒▓▒▒▒▒▒▒▒▒▒▒▒▓▒▒▒▓▓▓▓▓▓▓▓▓▓▓▒▒▒▒▒▓█░█░▓▒█▓░▒▒▒▒▒▒▒▒▒▓ ░░░░░░▒▒▒▒▒▒▒▒▒▒█░░░░", -"░░░░░░░▓▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒█▓▓░▒█░█▓▒█░░░▓▓▓▓▒░░░░░▒▒▒▒▒▒▒▒▒▒▒▓█▒░░░░░", -" ░ ░▒▒ ▒▓▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓██▒█▒▒░▒▓▓▒█▒▓░▓░░▒ ░░░░▒░▒▒▒▒▒▒▒▒▒▒▓█░░░░░░░░░", -" ▒ ░▓▓▒▓▓░▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒█▒█░▒▒▓▒▒█░▓▒▓░█▒▒░░░░░ ░▒▒▒▒▒▒▒▒▓█▒░░░░░░░░░░░", -"▒ ░▓▓▓▒▒▒▒▒▒▓▓▓▓▓▓▓▓░▓▒░▒▒▒▒▒▒▒▒▒░▒▒▒▓░░░░░░░▒▒▒▒▒▒▒▒░ ░░░░░░░░░░░░", -" ░░░▒▒▒▒▒▓█▓▒▒▒▒▒▒▒▒▒▒▒░░░░░░░░░▒▓▒▒▒▒▒▒▒░ ░░░░░░░░░░░░", -" ░▒▒▒▒░▓▒▒█▒ ▒░░░░░░░░░█▒▒▒▒▒▒▒▓▒░░░░░░░░░░░░", -" ▓▒▒▒▒▒▒▒▓░ █▒░░░░░▒▒▒▒▒▒▒▒▒█░░░░░░░░░░░░", -" ░▓▒▒▒▒▒▒▒░ ░░░░░░░▓▒▒▒▒▒▒▒▓▓░░░░░░░░░░░"}; - - -func printPepe(channel string, foo bot) { - for _, x := range pepe { - sendmsg(foo.conn, channel, x) - } - LOG_INFO.Printf("Sent pepe to ppl") -} diff --git a/types.go b/types.go new file mode 100644 index 0000000..b2968c4 --- /dev/null +++ b/types.go @@ -0,0 +1,34 @@ +package main + +import ( + "net" +) + +type Config 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"` +} + +type irc_msg struct { + channel string + msg string + author string + retmsg string +} + +type cmd struct { + valid bool + add bool + cmd string + groups []string + suffix string + error string +} + +type bot struct { + Conf Config + conn net.Conn +} +