This repository has been archived on 2022-03-09. You can view files and clone it, but cannot push or open issues or pull requests.
snoo2nebby/vendor/github.com/turnage/graw/scan.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
}