added simple reddit implementation

It does nothing but log now.
This commit is contained in:
Stephen McQuay 2016-05-07 15:46:45 -07:00
parent 787c65f0df
commit 473f9212b9
No known key found for this signature in database
GPG Key ID: 1ABF428F71BAFC3D
2 changed files with 152 additions and 1 deletions

146
bots/reddit/reddit.go Normal file
View File

@ -0,0 +1,146 @@
package reddit
import (
"encoding/json"
"fmt"
"log"
"net/http"
"regexp"
"sort"
"time"
irc "github.com/fluffle/goirc/client"
)
const name = "reddit"
func Register(host, channel string, done chan<- bool) {
var p *regexp.Regexp
c := irc.SimpleClient(name, name)
c.EnableStateTracking()
c.HandleFunc(
irc.CONNECTED,
func(conn *irc.Conn, line *irc.Line) {
conn.Join(channel)
var err error
p, err = regexp.Compile(`\b` + conn.Me().Nick + `\b`)
if err != nil {
log.Printf("%+v", err)
}
},
)
c.HandleFunc(
irc.DISCONNECTED,
func(conn *irc.Conn, line *irc.Line) {
done <- true
},
)
c.HandleFunc(
irc.PRIVMSG,
func(conn *irc.Conn, line *irc.Line) {
if p.MatchString(line.Text()) {
log.Printf("addressed me: %v", line.Text())
}
},
)
go func() {
seen := map[string]int{}
prime, err := items()
if err != nil {
log.Printf("%+v", err)
}
for _, item := range prime {
seen[item.ID] = item.Score
}
for {
log.Printf("reddit ...")
latest, err := items()
log.Printf("got %+v items", len(latest))
if err != nil {
log.Printf("%+v", err)
}
for _, item := range latest {
if _, ok := seen[item.ID]; ok {
continue
}
log.Printf("%+v", item)
seen[item.ID] = item.Score
c.Privmsgf(channel, "%v", item)
}
time.Sleep(5 * time.Minute)
}
}()
if err := c.ConnectTo(host); err != nil {
fmt.Printf("Connection error: %s\n", err)
}
}
type Item struct {
ID string `json:"id"`
Author string `json:"author"`
Score int `json:"score"`
URL string `json:"url"`
Title string `json:"title"`
Comments int `json:"num_comments"`
}
func (i Item) String() string {
com := ""
switch i.Comments {
case 0:
// nothing
case 1:
com = " (1 comment)"
default:
com = fmt.Sprintf(" (%d comments)", i.Comments)
}
return fmt.Sprintf("(%d: %s) %s%s\n%s", i.Score, i.ID, i.Title, com, i.URL)
}
type response struct {
Data struct {
Children []struct {
Data Item
}
}
}
func items() ([]Item, error) {
url := fmt.Sprintf("https://www.reddit.com/r/exmormon.json")
client := http.Client{}
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
req.Header.Set("User-Agent", "sm bot")
resp, err := client.Do(req)
if err != nil {
return nil, err
}
rresp := response{}
if err := json.NewDecoder(resp.Body).Decode(&rresp); err != nil {
return nil, err
}
defer resp.Body.Close()
items := []Item{}
for _, child := range rresp.Data.Children {
items = append(items, child.Data)
}
sort.Sort(ByScore(items))
return items, nil
}
type ByScore []Item
func (a ByScore) Len() int { return len(a) }
func (a ByScore) Swap(i, j int) { a[i], a[j] = a[j], a[i] }
func (a ByScore) Less(i, j int) bool { return a[i].Score > a[j].Score }

View File

@ -7,6 +7,7 @@ import (
"time"
"mcquay.me/exmo/bots/bybot"
"mcquay.me/exmo/bots/reddit"
)
var host *string = flag.String("host", "localhost:6668", "irc server hostname")
@ -20,5 +21,9 @@ func main() {
done := make(chan bool)
bybot.Register(*host, *channel, done)
<-done
reddit.Register(*host, *channel, done)
for i := 0; i < 2; i++ {
<-done
}
}