Blob


1 package main
3 import (
4 "crypto/tls"
5 "flag"
6 "fmt"
7 "io"
8 "io/ioutil"
9 "log"
10 "net/http"
11 "regexp"
13 irc "github.com/fluffle/goirc/client"
14 )
16 var (
17 baseurl = flag.String("baseurl", "gemini://m2i.omarpolo.com", "base url")
18 matrixOutDir = flag.String("matrix-out", "", "matrix out directory")
20 matrixRe = regexp.MustCompile(`https://matrix.org/[^\s]+\.txt`)
21 channel = "#kikuchiyo"
22 )
24 func matrix2gemini(conn *irc.Conn, line *irc.Line) {
25 matches := matrixRe.FindAllString(line.Text(), -1)
27 // it's not a good idea to defer inside a loop, but we know
28 // len(matches) is small (usually just 1). Morover, I like
29 // living in danger!
31 for _, link := range matches {
32 resp, err := http.Get(link)
33 if err != nil {
34 conn.Privmsg(
35 channel,
36 fmt.Sprintf("failed to download %q: %s", link, err),
37 )
38 continue
39 }
40 defer resp.Body.Close()
42 tmpfile, err := ioutil.TempFile(*matrixOutDir, "message-")
43 if err != nil {
44 conn.Privmsg(channel, fmt.Sprintf("failed to tmpfile: %s", err))
45 return
46 }
47 defer tmpfile.Close()
49 io.Copy(tmpfile, resp.Body)
51 conn.Privmsg(
52 channel,
53 fmt.Sprintf("better: %s/%s", *baseurl, tmpfile.Name()),
54 )
55 }
56 }
58 func dostuff(conn *irc.Conn, line *irc.Line) {
59 matrix2gemini(conn, line)
60 // ...
61 }
63 func main() {
64 flag.Parse()
66 cfg := irc.NewConfig("gemitbot")
67 cfg.SSL = true
68 cfg.SSLConfig = &tls.Config{ServerName: "irc.freenode.net"}
69 cfg.Server = "irc.freenode.net:7000"
70 cfg.NewNick = func(n string) string { return n + "^" }
72 c := irc.Client(cfg)
74 c.HandleFunc(irc.CONNECTED, func(conn *irc.Conn, line *irc.Line) {
75 log.Println("connected, joining", channel)
76 conn.Join(channel)
77 })
79 c.HandleFunc(irc.PRIVMSG, dostuff)
80 c.HandleFunc(irc.ACTION, dostuff)
82 quit := make(chan bool)
84 c.HandleFunc(irc.DISCONNECTED, func(conn *irc.Conn, line *irc.Line) {
85 quit <- true
86 })
88 if err := c.Connect(); err != nil {
89 log.Fatalln("connection error:", err)
90 }
92 <-quit
93 }