From c0fb632cfbda51bb3b54b13e7267496577b989e5 Mon Sep 17 00:00:00 2001 From: Janne Koschinski <janne@kuschku.de> Date: Thu, 24 May 2018 01:08:18 +0200 Subject: [PATCH] Implement first working version --- glide.lock | 14 +++++ glide.yaml | 4 ++ main.go | 181 ++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 198 insertions(+), 1 deletion(-) create mode 100644 glide.lock diff --git a/glide.lock b/glide.lock new file mode 100644 index 0000000..9a55495 --- /dev/null +++ b/glide.lock @@ -0,0 +1,14 @@ +hash: 71071f00798b1f4ce22ab71a61bbaccc0a10c7cb9e0a9acd0ac8c868c843d46d +updated: 2018-05-24T01:08:01.558664212+02:00 +imports: +- name: github.com/lib/pq + version: 90697d60dd844d5ef6ff15135d0203f65d2f53b8 + subpackages: + - oid +- name: github.com/lrstanley/girc + version: 102f17f86306c2152a8c6188f9bb8b0e7288de31 +- name: golang.org/x/crypto + version: 75e913eb8a8e3d31a97b216de09de106a7b07681 + subpackages: + - sha3 +testImports: [] diff --git a/glide.yaml b/glide.yaml index 531c988..10bbc8a 100644 --- a/glide.yaml +++ b/glide.yaml @@ -1,3 +1,7 @@ package: git.kuschku.de/justjanne/statsbot import: - package: github.com/lrstanley/girc +- package: github.com/lib/pq +- package: golang.org/x/crypto + subpackages: + - sha3 \ No newline at end of file diff --git a/main.go b/main.go index 17b6c08..42f47d3 100644 --- a/main.go +++ b/main.go @@ -1,5 +1,184 @@ -package statsbot +package main + +import ( + "github.com/lrstanley/girc" + "os" + "fmt" + "strings" + "log" + "time" + "golang.org/x/crypto/sha3" + _ "github.com/lib/pq" + "encoding/hex" + "database/sql" + "strconv" +) + +type Config struct { + Database DatabaseConfig + Irc IrcConfig +} + +type IrcConfig struct { + Server string + Port int + Secure bool + Nick string + Ident string + Realname string + SaslAccount string + SaslPassword string + SaslEnabled bool +} + +type DatabaseConfig struct { + Format string + Url string +} + +func NewConfigFromEnv() Config { + var err error + config := Config{} + + config.Irc.Server = os.Getenv("KSTATS_IRC_SERVER") + config.Irc.Port, err = strconv.Atoi(os.Getenv("KSTATS_IRC_PORT")) + if err != nil { + panic(err) + } + config.Irc.Secure = os.Getenv("KSTATS_IRC_SECURE") == "true" + config.Irc.Nick = os.Getenv("KSTATS_IRC_NICK") + config.Irc.Ident = os.Getenv("KSTATS_IRC_IDENT") + config.Irc.Realname = os.Getenv("KSTATS_IRC_REALNAME") + config.Irc.SaslEnabled = os.Getenv("KSTATS_IRC_SASL_ENABLED") == "true" + config.Irc.SaslAccount = os.Getenv("KSTATS_IRC_SASL_ACCOUNT") + config.Irc.SaslPassword = os.Getenv("KSTATS_IRC_SASL_PASSWORD") + + config.Database.Format = os.Getenv("KSTATS_DATABASE_TYPE") + config.Database.Url = os.Getenv("KSTATS_DATABASE_URL") + + return config +} + +type IrcMessage struct { + Time time.Time + Channel int + Sender string + Words int + Characters int + Question bool + Exclamation bool + Caps bool + Aggression bool + EmojiHappy bool + EmojiSad bool +} + +func (m *IrcMessage) ToString() string { + var flags []string + if m.Question { + flags = append(flags, "Question") + } + if m.Exclamation { + flags = append(flags, "Exclamation") + } + if m.Caps { + flags = append(flags, "Caps") + } + if m.Aggression { + flags = append(flags, "Aggression") + } + if m.EmojiHappy { + flags = append(flags, "EmojiHappy") + } + if m.EmojiSad { + flags = append(flags, "EmojiSad") + } + + return fmt.Sprintf("IrcMessage{time=%s,channel=%d,sender=%s,words=%d,characters=%d,flags=[%s]}", m.Time.Format(time.RFC3339), m.Channel, m.Sender, m.Words, m.Characters, strings.Join(flags, ",")) +} func main() { + config := NewConfigFromEnv() + + db, err := sql.Open(config.Database.Format, config.Database.Url) + if err != nil { + panic(err) + } + + ircConfig := girc.Config{ + Server: config.Irc.Server, + Port: config.Irc.Port, + SSL: config.Irc.Secure, + Nick: config.Irc.Nick, + User: config.Irc.Ident, + Name: config.Irc.Realname, + Debug: os.Stdout, + } + if config.Irc.SaslEnabled { + ircConfig.SASL = &girc.SASLPlain{ + User: config.Irc.SaslAccount, + Pass: config.Irc.SaslPassword, + } + } + client := girc.New(ircConfig) + + channels := map[string]int{} + client.Handlers.Add(girc.CONNECTED, func(c *girc.Client, e girc.Event) { + result, err := db.Query("SELECT id, channel FROM channels") + if err != nil { + panic(err) + } + for result.Next() { + var id int + var name string + err := result.Scan(&id, &name) + if err != nil { + panic(err) + } + channels[name] = id + } + for name := range channels { + c.Cmd.Join(name) + } + }) + + client.Handlers.Add(girc.PRIVMSG, func(c *girc.Client, e girc.Event) { + if len(e.Params) == 1 { + channel := e.Params[0] + if id, ok := channels[channel]; ok { + name := hex.EncodeToString(sha3.New256().Sum([]byte(e.Source.Name))) + content := strings.TrimSpace(e.Trailing) + // Add referenced nick part here + // c.LookupChannel(channel).UserList + message := IrcMessage{ + Time: time.Now().UTC(), + Channel: id, + Sender: name, + Words: len(strings.Split(content, " ")), + Characters: len(content), + Question: strings.HasSuffix(content, "?"), + Exclamation: strings.HasSuffix(content, "!"), + Caps: content == strings.ToUpper(content), + Aggression: false, + EmojiHappy: strings.Contains(content, ":)"), + EmojiSad: strings.Contains(content, ":("), + } + _, err := db.Exec("INSERT INTO messages (time, channel, sender, words, characters, question, exclamation, caps, aggression, emoji_happy, emoji_sad) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)", message.Time, message.Channel, message.Sender, message.Words, message.Characters, message.Question, message.Exclamation, message.Caps, message.Aggression, message.EmojiHappy, message.EmojiSad) + if err != nil { + println(err.Error()) + } + } + } + }) + + for { + if err := client.Connect(); err != nil { + log.Printf("error: %s", err) + log.Println("reconnecting in 30 seconds...") + time.Sleep(30 * time.Second) + } else { + return + } + } } -- GitLab