-
Notifications
You must be signed in to change notification settings - Fork 50
/
run.go
143 lines (130 loc) · 2.62 KB
/
run.go
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
135
136
137
138
139
140
141
142
143
package graw
import (
"fmt"
"github.com/turnage/graw/botfaces"
"github.com/turnage/graw/reddit"
"github.com/turnage/graw/streams"
)
var (
postReplyHandlerErr = fmt.Errorf(
"You must implement PostReplHandler to take post reply feeds.",
)
commentReplyHandlerErr = fmt.Errorf(
"You must implement CommentReplyHandler to take comment reply feeds.",
)
mentionHandlerErr = fmt.Errorf(
"You must implement MentionHandler to take mention feeds.",
)
messageHandlerErr = fmt.Errorf(
"You must implement MessageHandler to take message feeds.",
)
)
// Run connects a handler to any requested event sources and makes requests with
// the given bot api handle. It launches a goroutine for the run. It returns two
// functions, a stop() function to terminate the graw run at any time, and a
// wait() function to block until the graw run fails.
func Run(handler interface{}, bot reddit.Bot, cfg Config) (
func(),
func() error,
error,
) {
kill := make(chan bool)
errs := make(chan error)
if err := connectAllStreams(
handler,
bot,
cfg,
kill,
errs,
); err != nil {
return nil, nil, err
}
return launch(handler, kill, errs, logger(cfg.Logger))
}
func connectAllStreams(
handler interface{},
bot reddit.Bot,
c Config,
kill <-chan bool,
errs chan<- error,
) error {
if err := connectScanStreams(
handler,
bot,
c,
kill,
errs,
); err != nil {
return err
}
// lol no generics:
if c.PostReplies {
if prh, ok := handler.(botfaces.PostReplyHandler); !ok {
return postReplyHandlerErr
} else if prs, err := streams.PostReplies(
bot,
kill,
errs,
); err != nil {
return err
} else {
go func() {
for pr := range prs {
errs <- prh.PostReply(pr)
}
}()
}
}
if c.CommentReplies {
if crh, ok := handler.(botfaces.CommentReplyHandler); !ok {
return commentReplyHandlerErr
} else if crs, err := streams.CommentReplies(
bot,
kill,
errs,
); err != nil {
return err
} else {
go func() {
for cr := range crs {
errs <- crh.CommentReply(cr)
}
}()
}
}
if c.Mentions {
if mh, ok := handler.(botfaces.MentionHandler); !ok {
return mentionHandlerErr
} else if ms, err := streams.Mentions(
bot,
kill,
errs,
); err != nil {
return err
} else {
go func() {
for m := range ms {
errs <- mh.Mention(m)
}
}()
}
}
if c.Messages {
if mh, ok := handler.(botfaces.MessageHandler); !ok {
return messageHandlerErr
} else if ms, err := streams.Messages(
bot,
kill,
errs,
); err != nil {
return err
} else {
go func() {
for m := range ms {
errs <- mh.Message(m)
}
}()
}
}
return nil
}