diff options
| author | ilotterytea <iltsu@alright.party> | 2025-08-03 17:56:12 +0500 |
|---|---|---|
| committer | ilotterytea <iltsu@alright.party> | 2025-08-03 17:56:12 +0500 |
| commit | 9a20de85770f2f5ba09ad492aa2fb06782966096 (patch) | |
| tree | 9c5ef003093c6db54b44eb0c56b98f7b7c8cd9f5 | |
| parent | c2432518c6ae67afa40c68c2a466ba34728e5de6 (diff) | |
feat: save messages into the database
| -rw-r--r-- | cmd/irclogs/main.go | 4 | ||||
| -rw-r--r-- | internal/client.go | 16 | ||||
| -rw-r--r-- | internal/message.go | 65 |
3 files changed, 78 insertions, 7 deletions
diff --git a/cmd/irclogs/main.go b/cmd/irclogs/main.go index 1090e66..bc567e5 100644 --- a/cmd/irclogs/main.go +++ b/cmd/irclogs/main.go @@ -40,7 +40,7 @@ func main() { return c.Host == host }) { log.Printf("Connecting to %s:%d...\n", host, port) - c := irclogs.NewIRCClient(dbid, host, port, nick, pass, strings.Split(caps, "\n")) + c := irclogs.NewIRCClient(db, dbid, host, port, nick, pass, strings.Split(caps, "\n")) go func() { if err = c.Connect(); err != nil { @@ -48,7 +48,7 @@ func main() { } }() - go c.JoinChannels(db) + go c.JoinChannels() clients = append(clients, c) } diff --git a/internal/client.go b/internal/client.go index 8adc12c..5099074 100644 --- a/internal/client.go +++ b/internal/client.go @@ -12,6 +12,7 @@ import ( ) type IRCClient struct { + db *sql.DB dbid int Host string @@ -25,8 +26,9 @@ type IRCClient struct { conn net.Conn } -func NewIRCClient(dbid int, host string, port int, nick string, pass string, capabilities []string) IRCClient { +func NewIRCClient(db *sql.DB, dbid int, host string, port int, nick string, pass string, capabilities []string) IRCClient { return IRCClient{ + db: db, dbid: dbid, Host: host, port: port, @@ -58,7 +60,13 @@ func (c *IRCClient) Connect() (err error) { for _, line := range strings.Split(raw, "\r\n") { message := ParseIRCMessage(line) - log.Printf("IRC message: %s\n", message) + + switch message.Command { + case "PRIVMSG", "JOIN", "PART": + message.Save(c.db, c.dbid) + case "PING": + c.SendRaw(fmt.Sprintf("PONG :%s", strings.Join(message.Params, " "))) + } } } } @@ -77,10 +85,10 @@ func (c *IRCClient) SendRaw(message string) { } } -func (c *IRCClient) JoinChannels(db *sql.DB) { +func (c *IRCClient) JoinChannels() { for { rooms := []string{} - rows, err := db.Query("SELECT name FROM rooms WHERE server_id = ? AND departed_at IS NULL", c.dbid) + rows, err := c.db.Query("SELECT name FROM rooms WHERE server_id = ? AND departed_at IS NULL", c.dbid) if err != nil { log.Fatalf("Failed to get rooms: %v\n", err) continue diff --git a/internal/message.go b/internal/message.go index e8df9a4..46dae07 100644 --- a/internal/message.go +++ b/internal/message.go @@ -1,6 +1,12 @@ package irclogs -import "strings" +import ( + "database/sql" + "fmt" + "log" + "slices" + "strings" +) type IRCMessage struct { Tags map[string]string @@ -62,3 +68,60 @@ func ParseIRCMessage(message string) IRCMessage { return msg } + +func (m *IRCMessage) Save(db *sql.DB, serverId int) { + var roomId int + var roomDepart sql.NullTime + err := db.QueryRow( + "SELECT id, departed_at FROM rooms WHERE name = ? AND server_id = ?", + m.Params[0], serverId, + ).Scan(&roomId, &roomDepart) + if err != nil || roomDepart.Valid { + return + } + + var userId int64 + var userDepart sql.NullTime + err = db.QueryRow( + "SELECT id, departed_at FROM users WHERE server_id = ? AND nick = ?", + serverId, m.Nick, + ).Scan(&userId, &userDepart) + if err == sql.ErrNoRows { + res, err := db.Exec("INSERT INTO users(server_id, nick) VALUES (?, ?)", serverId, m.Nick) + if err != nil { + log.Panicf("Failed to create a new user: %v\n", err) + } + userId, _ = res.LastInsertId() + } else if err != nil { + log.Panicf("Failed to get a user: %v\n", err) + } else if userDepart.Valid { + return + } + + tags := sql.NullString{ + String: "", + Valid: len(m.Tags) > 0, + } + for k, v := range m.Tags { + tags.String += fmt.Sprintf("%s=%s;", k, v) + } + if len(tags.String) > 0 { + tags.String = tags.String[:len(tags.String)-1] + } + + if len(m.Params) > 0 && m.Params[0][0] == '#' { + m.Params = slices.Delete(m.Params, 0, 1) + } + + params := sql.NullString{ + String: strings.Join(m.Params, " "), + Valid: len(m.Params) > 0, + } + + _, err = db.Exec("INSERT INTO messages(room_id, user_id, command, params, tags) VALUES (?, ?, ?, ?, ?)", + roomId, userId, m.Command, params, tags) + + if err != nil { + log.Panicf("Failed to add a message: %v\n", err) + } +} |
