aboutsummaryrefslogtreecommitdiff
path: root/main.go
blob: f4278c87b36aa1812fbbe3004a8def0b4bbc7c43 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package main

import (
	"crypto/tls"
	"flag"
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"net/http"
	"path"
	"path/filepath"
	"regexp"

	irc "github.com/fluffle/goirc/client"
)

var (
	baseurl = flag.String("baseurl", "gemini://m2i.omarpolo.com", "base url")
	matrixOutDir = flag.String("matrix-out", "", "matrix out directory")

	matrixRe = regexp.MustCompile(`https://.*/[^\s]+\.(txt|png|jpg|jpeg|gif)`)
	channel = "#gemini-it"
)

func matrix2gemini(conn *irc.Conn, line *irc.Line) {
	matches := msgRe.FindAllString(line.Text(), -1)

	// it's not a good idea to defer inside a loop, but we know
	// len(matches) is small (usually just 1).  Morover, I like
	// living in danger!

	for _, link := range matches {
		resp, err := http.Get(link)
		if err != nil {
			conn.Privmsg(
				channel,
				fmt.Sprintf("failed to download %q: %s", link, err),
			)
			continue
		}
		defer resp.Body.Close()

		ext := path.Ext(link)
		tmpfile, err := ioutil.TempFile(*matrixOutDir, "message-*" + ext)
		if err != nil {
			conn.Privmsg(channel, fmt.Sprintf("failed to tmpfile: %s", err))
			return
		}
		defer tmpfile.Close()

		io.Copy(tmpfile, resp.Body)

		conn.Privmsg(
			channel,
			fmt.Sprintf(
				"better: %s/%s",
				*baseurl,
				filepath.Base(tmpfile.Name()),
			),
		)
	}
}

func dostuff(conn *irc.Conn, line *irc.Line) {
	matrix2gemini(conn, line)
	// ...
}

func main() {
	flag.Parse()

	cfg := irc.NewConfig("gemitbot")
	cfg.SSL = true
	cfg.SSLConfig = &tls.Config{ServerName: "irc.libera.chat"}
	cfg.Server = "irc.libera.chat:7000"
	cfg.NewNick = func(n string) string { return n + "^" }

	c := irc.Client(cfg)

	c.HandleFunc(irc.CONNECTED, func(conn *irc.Conn, line *irc.Line) {
		log.Println("connected, joining", channel)
		conn.Join(channel)
	})

	c.HandleFunc(irc.PRIVMSG, dostuff)
	c.HandleFunc(irc.ACTION, dostuff)

	quit := make(chan bool)

	c.HandleFunc(irc.DISCONNECTED, func(conn *irc.Conn, line *irc.Line) {
		quit <- true
	})

	if err := c.Connect(); err != nil {
		log.Fatalln("connection error:", err)
	}

	<-quit
}