summaryrefslogtreecommitdiff
path: root/main.go
blob: bfef9754f614ff577f4db11c585b92155935173e (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
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
package main

import (
	"container/ring"
	"flag"
	"fmt"
	"log"
	"strconv"
	"strings"
	"time"

	"dim13.org/theo"
	"github.com/thoj/go-ircevent"
)

var (
	server = flag.String("server", "irc.rusnet.org.ru:6660", "IRC Server")
	room   = flag.String("room", "#lor", "IRC Channel")
	name   = flag.String("name", "theo", "Bot Name")
)

var (
	buffer   = ring.New(10)
	cmds     = make(map[string]CmdFn)
	dscr     []string
	lastNews time.Time
)

type CmdFn func(*irc.Event, []string)

func last(e *irc.Event, _ []string) {
	conn := e.Connection
	nick := e.Nick
	buffer.Do(func(v interface{}) {
		if v != nil {
			ev := v.(*irc.Event)
			conn.Privmsgf(nick, "%v: %v", ev.Nick, ev.Message())
		}
	})
}

func metar(e *irc.Event, arg []string) {
	conn := e.Connection
	metar, err := FetchMetar(arg[0])
	if err != nil {
		conn.Privmsg(*room, err.Error())
	} else {
		conn.Privmsg(*room, metar[1])
	}
}

func help(e *irc.Event, _ []string) {
	for _, m := range dscr {
		e.Connection.Privmsg(*room, m)
	}
}

func news(e *irc.Event, arg []string) {
	conn := e.Connection
	n := 5
	if len(arg) > 0 {
		i, err := strconv.Atoi(arg[0])
		if err == nil {
			n = i
		}
	}
	if time.Since(lastNews) > time.Minute {
		for _, n := range FetchNews(n) {
			conn.Privmsg(*room, n)
			lastNews = time.Now()
		}
	} else {
		conn.Privmsg(*room, e.Nick+", me just said it")
	}
}

func register(cmd string, f func(*irc.Event, []string), help string) {
	cmds[cmd] = f
	h := fmt.Sprintf("!%v %v", cmd, help)
	dscr = append(dscr, h)
}

func privmsg(e *irc.Event) {
	conn := e.Connection
	msg := e.Message()
	nick := e.Nick

	log.Println(nick, msg)

	switch msg[0] {
	case '!':
		arg := strings.Fields(msg[1:])
		if cmd, ok := cmds[arg[0]]; ok {
			go cmd(e, arg[1:])
		}
	default:
		if strings.Contains(msg, *name) {
			conn.Privmsg(*room, theo.Theo())
		}
		buffer.Value = e
		buffer = buffer.Next()
	}
}

func init() {
	flag.Parse()
	register("last", last, "shows last 10 messages")
	register("metar", metar, "<arg> shows weather report")
	register("help", help, "shows this message")
	register("top", news, "shows top 10 news")
}

// 001 Welcome
// 332 Topic
// 333 Unix Time
// 353 Names list
// 366 End of NAMES List
// JOIN
// CTCP_ACTION /me
// PRIVMSG

func main() {
	con := irc.IRC(*name, *name)
	err := con.Connect(*server)
	if err != nil {
		log.Fatal(err)
	}
	con.AddCallback("001", func(e *irc.Event) {
		e.Connection.Join(*room)
		log.Println("joined", *room)
	})
	con.AddCallback("PRIVMSG", privmsg)
	con.Loop()
}