summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/irclogs/main.go10
-rw-r--r--internal/client.go54
2 files changed, 58 insertions, 6 deletions
diff --git a/cmd/irclogs/main.go b/cmd/irclogs/main.go
index 509447f..1090e66 100644
--- a/cmd/irclogs/main.go
+++ b/cmd/irclogs/main.go
@@ -22,7 +22,7 @@ func main() {
clients := []irclogs.IRCClient{}
for {
- rows, err := db.Query("SELECT host, port, nick, pass, capabilities FROM servers")
+ rows, err := db.Query("SELECT id, host, port, nick, pass, capabilities FROM servers")
if err != nil {
log.Fatalf("Failed to get servers: %v\n", err)
continue
@@ -30,8 +30,8 @@ func main() {
for rows.Next() {
var host, nick, pass, caps string
- var port int
- if err = rows.Scan(&host, &port, &nick, &pass, &caps); err != nil {
+ var dbid, port int
+ if err = rows.Scan(&dbid, &host, &port, &nick, &pass, &caps); err != nil {
log.Fatalf("Failed to scan rows: %v\n", err)
continue
}
@@ -40,7 +40,7 @@ func main() {
return c.Host == host
}) {
log.Printf("Connecting to %s:%d...\n", host, port)
- c := irclogs.NewIRCClient(host, port, nick, pass, strings.Split(caps, "\n"))
+ c := irclogs.NewIRCClient(dbid, host, port, nick, pass, strings.Split(caps, "\n"))
go func() {
if err = c.Connect(); err != nil {
@@ -48,6 +48,8 @@ func main() {
}
}()
+ go c.JoinChannels(db)
+
clients = append(clients, c)
}
}
diff --git a/internal/client.go b/internal/client.go
index 092504e..c0373a0 100644
--- a/internal/client.go
+++ b/internal/client.go
@@ -2,24 +2,31 @@ package irclogs
import (
"bufio"
+ "database/sql"
"fmt"
"log"
"net"
"net/textproto"
+ "slices"
)
type IRCClient struct {
+ dbid int
+
Host string
port int
nick string
pass string
caps []string
+ rooms []string
+
conn net.Conn
}
-func NewIRCClient(host string, port int, nick string, pass string, capabilities []string) IRCClient {
+func NewIRCClient(dbid int, host string, port int, nick string, pass string, capabilities []string) IRCClient {
return IRCClient{
+ dbid: dbid,
Host: host,
port: port,
nick: nick,
@@ -36,6 +43,9 @@ func (c *IRCClient) Connect() (err error) {
c.conn = conn
c.authorize()
+ for _, r := range c.rooms {
+ c.SendRaw(fmt.Sprintf("JOIN %s", r))
+ }
tp := textproto.NewReader(bufio.NewReader(c.conn))
@@ -57,5 +67,45 @@ func (c *IRCClient) authorize() {
}
func (c *IRCClient) SendRaw(message string) {
- fmt.Fprintf(c.conn, "%s\r\n", message)
+ if c.conn != nil {
+ fmt.Fprintf(c.conn, "%s\r\n", message)
+ }
+}
+
+func (c *IRCClient) JoinChannels(db *sql.DB) {
+ for {
+ rooms := []string{}
+ rows, err := 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
+ }
+
+ for rows.Next() {
+ var room string
+ if err = rows.Scan(&room); err != nil {
+ log.Fatalf("Failed to scan rows: %v\n", err)
+ continue
+ }
+ rooms = append(rooms, room)
+ }
+
+ rows.Close()
+
+ for _, r := range rooms {
+ if !slices.Contains(c.rooms, r) {
+ log.Printf("[%s] Joining %s...", c.Host, r)
+ c.SendRaw(fmt.Sprintf("JOIN %s", r))
+ c.rooms = append(c.rooms, r)
+ }
+ }
+
+ for _, r := range c.rooms {
+ if !slices.Contains(rooms, r) {
+ log.Printf("[%s] Departing %s...", c.Host, r)
+ c.SendRaw(fmt.Sprintf("PART %s", r))
+ c.rooms = slices.DeleteFunc(c.rooms, func(s string) bool { return s == r })
+ }
+ }
+ }
}