about summary refs log tree commit diff
path: root/fun/tvl-ebooks/ebook-client/main.go
diff options
context:
space:
mode:
authorBen Cartwright-Cox <tvl@Benjojo.co.uk>2020-09-27T23·22+0100
committerben <tvl@benjojo.co.uk>2020-09-27T23·26+0000
commita8508373ee4bb00d866315a63dccfaa924a8a6ae (patch)
treea2666ffa11767a5a510a5e8e6021db916c0620e6 /fun/tvl-ebooks/ebook-client/main.go
parentcf878224ab60ef58fcb3cb0a52c7142bbe2ae10b (diff)
feat(ebooks): Add tvl-ebooks code r/1822
Change-Id: If519e789a91fbf427373daa383c6ae00ba5e0b6c
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2007
Tested-by: BuildkiteCI
Reviewed-by: tazjin <mail@tazj.in>
Diffstat (limited to 'fun/tvl-ebooks/ebook-client/main.go')
-rw-r--r--fun/tvl-ebooks/ebook-client/main.go170
1 files changed, 170 insertions, 0 deletions
diff --git a/fun/tvl-ebooks/ebook-client/main.go b/fun/tvl-ebooks/ebook-client/main.go
new file mode 100644
index 000000000000..7954184dd7be
--- /dev/null
+++ b/fun/tvl-ebooks/ebook-client/main.go
@@ -0,0 +1,170 @@
+package main
+
+import (
+	"crypto/tls"
+	"encoding/json"
+	"flag"
+	"fmt"
+	"log"
+	"net"
+	"sync"
+	"time"
+
+	"github.com/go-redis/redis"
+	"gopkg.in/irc.v3"
+)
+
+var messageBeat chan bool
+var firstMessage chan bool
+var client *irc.Client
+var safeLock sync.Mutex
+
+func main() {
+	nick := flag.String("nick", "NONE", "the ircnick you want")
+	from := flag.String("ip", "[::1]", "src address")
+	flag.Parse()
+
+	localAddrDialier := &net.Dialer{
+		LocalAddr: &net.TCPAddr{
+			IP:   net.ParseIP(*from),
+			Port: 0,
+		},
+	}
+
+	conn, err := tls.DialWithDialer(localAddrDialier, "tcp", "chat.freenode.net:6697", &tls.Config{})
+	if err != nil {
+		log.Fatalln(err)
+	}
+
+	messageBeat = make(chan bool)
+	firstMessage = make(chan bool, 10)
+	go ircKeepalive()
+
+	redisc := redis.NewClient(&redis.Options{
+		Addr:     fmt.Sprintf("127.0.0.1:%d", 6379),
+		Password: "", // no password set
+		DB:       0,  // use default DB
+	})
+
+	go func() {
+		for {
+			time.Sleep(time.Second)
+			r := redisc.Ping()
+			if r.Err() != nil {
+				redisc = redis.NewClient(&redis.Options{
+					Addr:     fmt.Sprintf("127.0.0.1:%d", 6379),
+					Password: "", // no password set
+					DB:       0,  // use default DB
+				})
+			}
+			redisc.Set(fmt.Sprintf("alive-%s", *nick), "yes", time.Second*5)
+		}
+	}()
+
+	if *nick == "NONE" {
+		log.Fatalf("You must set a nick")
+	}
+
+	go func() {
+		<-firstMessage
+		for {
+			psub := redisc.Subscribe(fmt.Sprintf("irc-%s", *nick))
+
+			for {
+				msg, err := psub.ReceiveMessage()
+				if err != nil {
+					break
+				}
+				client.WriteMessage(&irc.Message{
+					Command: "PRIVMSG",
+					Params: []string{
+						"##tvl-ebooks",
+						msg.Payload,
+					},
+				})
+			}
+			time.Sleep(time.Second * 10)
+		}
+
+	}()
+
+	go func() {
+		<-firstMessage
+		for {
+			psub := redisc.Subscribe(fmt.Sprintf("raw-irc-%s", *nick))
+
+			for {
+				msg, err := psub.ReceiveMessage()
+				if err != nil {
+					break
+				}
+				im := irc.Message{}
+				err = json.Unmarshal([]byte(msg.Payload), &im)
+				if err == nil {
+					client.WriteMessage(&im)
+				}
+			}
+			time.Sleep(time.Second * 10)
+		}
+
+	}()
+
+	seenMsgBefore := false
+	config := irc.ClientConfig{
+		Nick: *nick,
+		User: *nick,
+		Name: fmt.Sprintf("%s Ebooks", *nick),
+		Handler: irc.HandlerFunc(func(c *irc.Client, m *irc.Message) {
+			b, _ := json.Marshal(m)
+			log.Printf("%#v", string(b))
+
+			messageBeat <- true
+
+			if !seenMsgBefore {
+				firstMessage <- true
+				seenMsgBefore = true
+			}
+			res := redisc.Publish("ebook", string(b))
+			if res.Err() != nil {
+				log.Printf("Publish error! %#v", err)
+			}
+			if m.Command == "001" {
+				// 001 is a welcome event, so we join channels there
+				c.Write("JOIN ##tvl-ebooks")
+			}
+			// else if m.Command == "PRIVMSG" && c.FromChannel(m) {
+			// 	// // Create a handler on all messages.
+			// 	// c.WriteMessage(&irc.Message{
+			// 	// 	Command: "PRIVMSG",
+			// 	// 	Params: []string{
+			// 	// 		m.Params[0],
+			// 	// 		m.Trailing(),
+			// 	// 	},
+			// 	// })
+			// }
+		}),
+	}
+
+	// Create the client
+	client = irc.NewClient(conn, config)
+	err = client.Run()
+	if err != nil {
+		log.Fatalln(err)
+	}
+}
+
+func ircKeepalive() {
+	tt := time.NewTimer(time.Second)
+	lastPing := time.Now()
+	for {
+		select {
+		case <-tt.C:
+			if time.Since(lastPing) > time.Minute*5 {
+				log.Fatalf("It's been too long since the last IRC message, blowing up")
+			}
+			break
+		case <-messageBeat:
+			lastPing = time.Now()
+		}
+	}
+}