165 lines
3.0 KiB
Go
165 lines
3.0 KiB
Go
package graw
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"github.com/turnage/graw/botfaces"
|
|
"github.com/turnage/graw/reddit"
|
|
"github.com/turnage/graw/streams"
|
|
)
|
|
|
|
var (
|
|
postHandlerErr = fmt.Errorf(
|
|
"You must implement PostHandler to handle subreddit feeds.",
|
|
)
|
|
commentHandlerErr = fmt.Errorf(
|
|
"You must implement CommentHandler to handle subreddit " +
|
|
"comment feeds.",
|
|
)
|
|
userHandlerErr = fmt.Errorf(
|
|
"You must implement UserHandler to handle user feeds.",
|
|
)
|
|
loggedOutErr = fmt.Errorf(
|
|
"You must be running as a logged in bot to get inbox feeds.",
|
|
)
|
|
)
|
|
|
|
// Scan connects any requested logged-out event sources to the given handler,
|
|
// making requests with the given script handle. It launches a goroutine for the
|
|
// scan. It returns two functions: a stop() function to stop the scan at any
|
|
// time, and a wait() function to block until the scan fails.
|
|
func Scan(handler interface{}, script reddit.Script, cfg Config) (
|
|
func(),
|
|
func() error,
|
|
error,
|
|
) {
|
|
kill := make(chan bool)
|
|
errs := make(chan error)
|
|
|
|
if cfg.PostReplies || cfg.CommentReplies || cfg.Mentions || cfg.Messages {
|
|
return nil, nil, loggedOutErr
|
|
}
|
|
|
|
if err := connectScanStreams(
|
|
handler,
|
|
script,
|
|
cfg,
|
|
kill,
|
|
errs,
|
|
); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
|
|
return launch(handler, kill, errs, logger(cfg.Logger))
|
|
}
|
|
|
|
// connectScanStreams connects the streams a scanner can subscribe to to the
|
|
// handler.
|
|
func connectScanStreams(
|
|
handler interface{},
|
|
sc reddit.Scanner,
|
|
c Config,
|
|
kill <-chan bool,
|
|
errs chan<- error,
|
|
) error {
|
|
if len(c.Subreddits) > 0 {
|
|
ph, ok := handler.(botfaces.PostHandler)
|
|
if !ok {
|
|
return postHandlerErr
|
|
}
|
|
|
|
if posts, err := streams.Subreddits(
|
|
sc,
|
|
kill,
|
|
errs,
|
|
c.Subreddits...,
|
|
); err != nil {
|
|
return err
|
|
} else {
|
|
go func() {
|
|
for p := range posts {
|
|
errs <- ph.Post(p)
|
|
}
|
|
}()
|
|
}
|
|
}
|
|
|
|
if len(c.CustomFeeds) > 0 {
|
|
ph, ok := handler.(botfaces.PostHandler)
|
|
if !ok {
|
|
return postHandlerErr
|
|
}
|
|
|
|
for user, feeds := range c.CustomFeeds {
|
|
if posts, err := streams.CustomFeeds(
|
|
sc,
|
|
kill,
|
|
errs,
|
|
user,
|
|
feeds...,
|
|
); err != nil {
|
|
return err
|
|
} else {
|
|
go func() {
|
|
for p := range posts {
|
|
errs <- ph.Post(p)
|
|
}
|
|
}()
|
|
}
|
|
}
|
|
}
|
|
|
|
if len(c.SubredditComments) > 0 {
|
|
ch, ok := handler.(botfaces.CommentHandler)
|
|
if !ok {
|
|
return commentHandlerErr
|
|
}
|
|
|
|
if comments, err := streams.SubredditComments(
|
|
sc,
|
|
kill,
|
|
errs,
|
|
c.SubredditComments...,
|
|
); err != nil {
|
|
return err
|
|
} else {
|
|
go func() {
|
|
for c := range comments {
|
|
errs <- ch.Comment(c)
|
|
}
|
|
}()
|
|
}
|
|
}
|
|
|
|
if len(c.Users) > 0 {
|
|
uh, ok := handler.(botfaces.UserHandler)
|
|
if !ok {
|
|
return userHandlerErr
|
|
}
|
|
|
|
for _, user := range c.Users {
|
|
if posts, comments, err := streams.User(
|
|
sc,
|
|
kill,
|
|
errs,
|
|
user,
|
|
); err != nil {
|
|
return err
|
|
} else {
|
|
go func() {
|
|
for p := range posts {
|
|
errs <- uh.UserPost(p)
|
|
}
|
|
}()
|
|
go func() {
|
|
for c := range comments {
|
|
errs <- uh.UserComment(c)
|
|
}
|
|
}()
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|