add reddit things! and eyebleach!
This commit is contained in:
10
args.go
10
args.go
@ -12,6 +12,8 @@ type botOptions struct {
|
|||||||
LogConvIDStr string `env:"BOT_LOG_CONVID" envDefault:""`
|
LogConvIDStr string `env:"BOT_LOG_CONVID" envDefault:""`
|
||||||
HomePath string `envDefault:""`
|
HomePath string `envDefault:""`
|
||||||
JSON bool `env:"BOT_LOG_JSON" envDefault:"false"`
|
JSON bool `env:"BOT_LOG_JSON" envDefault:"false"`
|
||||||
|
RedditUser string `env:"BOT_REDDIT_USER" envDefault:""`
|
||||||
|
RedditPass string `env:"BOT_REDDIT_PASS" envDefault:""`
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseArgs(args []string) botOptions {
|
func parseArgs(args []string) botOptions {
|
||||||
@ -27,6 +29,8 @@ func parseArgs(args []string) botOptions {
|
|||||||
flags.BoolVar(&cliOpts.JSON, "json", false, "enables JSON logging")
|
flags.BoolVar(&cliOpts.JSON, "json", false, "enables JSON logging")
|
||||||
flags.StringVar(&cliOpts.LogConvIDStr, "log-convid", "", "set the keybase conversation log id")
|
flags.StringVar(&cliOpts.LogConvIDStr, "log-convid", "", "set the keybase conversation log id")
|
||||||
flags.StringVar(&cliOpts.HomePath, "kbhome", "", "sets alternate keybase home folder for debugging")
|
flags.StringVar(&cliOpts.HomePath, "kbhome", "", "sets alternate keybase home folder for debugging")
|
||||||
|
flags.StringVar(&cliOpts.RedditUser, "reddit-user", "", "sets the reddit auth user")
|
||||||
|
flags.StringVar(&cliOpts.RedditPass, "reddit-pass", "", "sets the reddit auth password")
|
||||||
if err := flags.Parse(args[1:]); err != nil {
|
if err := flags.Parse(args[1:]); err != nil {
|
||||||
log.Fatalf("Unable to parse cli args: %+v", err)
|
log.Fatalf("Unable to parse cli args: %+v", err)
|
||||||
}
|
}
|
||||||
@ -44,6 +48,12 @@ func parseArgs(args []string) botOptions {
|
|||||||
if cliOpts.LogConvIDStr != "" {
|
if cliOpts.LogConvIDStr != "" {
|
||||||
opts.LogConvIDStr = cliOpts.LogConvIDStr
|
opts.LogConvIDStr = cliOpts.LogConvIDStr
|
||||||
}
|
}
|
||||||
|
if cliOpts.RedditUser != "" {
|
||||||
|
opts.RedditUser = cliOpts.RedditUser
|
||||||
|
}
|
||||||
|
if cliOpts.RedditPass != "" {
|
||||||
|
opts.RedditPass = cliOpts.RedditPass
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return opts
|
return opts
|
||||||
}
|
}
|
||||||
|
|||||||
33
cmd/eyebleach.go
Normal file
33
cmd/eyebleach.go
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
|
||||||
|
"github.com/kf5grd/keybasebot"
|
||||||
|
"github.com/teris-io/shortid"
|
||||||
|
"samhofi.us/x/keybase/v2/types/chat1"
|
||||||
|
)
|
||||||
|
|
||||||
|
var EyebleachAd = chat1.UserBotCommandInput{
|
||||||
|
Name: "eyebleach",
|
||||||
|
Usage: "",
|
||||||
|
Description: "Sends some cute critters",
|
||||||
|
}
|
||||||
|
|
||||||
|
func Eyebleach(m chat1.MsgSummary, b *keybasebot.Bot) (bool, error) {
|
||||||
|
path, desc, err := getRandomRedditMedia(b, "eyebleach", "top", 20)
|
||||||
|
if err != nil {
|
||||||
|
eid := shortid.MustGenerate()
|
||||||
|
b.Logger.Error("%s: %+v", eid, err)
|
||||||
|
b.KB.ReactByConvID(m.ConvID, m.Id, "Error: %s", eid)
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
// upload the image
|
||||||
|
b.KB.UploadToConversation(m.ConvID, desc, path)
|
||||||
|
// delete the file
|
||||||
|
err = os.Remove(path)
|
||||||
|
if err != nil {
|
||||||
|
b.Logger.Error("Unable to remove file %s", path)
|
||||||
|
}
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
162
cmd/reddit.go
Normal file
162
cmd/reddit.go
Normal file
@ -0,0 +1,162 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"math/rand"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/PuerkitoBio/goquery"
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/jzelinskie/geddit"
|
||||||
|
"github.com/kf5grd/keybasebot"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getMetaLoginCreds(b *keybasebot.Bot) (username, password string, err error) {
|
||||||
|
user, ok := b.Meta["reddit-user"]
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("No reddit username has been set.")
|
||||||
|
}
|
||||||
|
pass, ok := b.Meta["reddit-pass"]
|
||||||
|
if !ok {
|
||||||
|
err = fmt.Errorf("No reddit password has been set.")
|
||||||
|
}
|
||||||
|
username = user.(string)
|
||||||
|
password = pass.(string)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRedditSubmissions(b *keybasebot.Bot, sub string, sort string, count int) ([]*geddit.Submission, error) {
|
||||||
|
// check the sort type
|
||||||
|
allowedSort := map[string]bool{
|
||||||
|
"hot": true,
|
||||||
|
"new": true,
|
||||||
|
"rising": true,
|
||||||
|
"top": true,
|
||||||
|
"controversial": true,
|
||||||
|
"": true,
|
||||||
|
}
|
||||||
|
if !allowedSort[sort] {
|
||||||
|
return nil, fmt.Errorf("%s is not an allowed sort method", sort)
|
||||||
|
}
|
||||||
|
user, pass, err := getMetaLoginCreds(b)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
session, err := geddit.NewLoginSession(
|
||||||
|
user,
|
||||||
|
pass,
|
||||||
|
"golang:pub.keybase.haukened.ssh0le:v2.0 (by /u/no-names-here)",
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
subOpts := geddit.ListingOptions{
|
||||||
|
Limit: count,
|
||||||
|
}
|
||||||
|
submissions, err := session.SubredditSubmissions(sub, geddit.PopularitySort(sort), subOpts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return submissions, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterSubmissions(gs []*geddit.Submission, test func(*geddit.Submission) bool) (ret []*geddit.Submission) {
|
||||||
|
for _, s := range gs {
|
||||||
|
if test(s) {
|
||||||
|
ret = append(ret, s)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func filterMedia(gs []*geddit.Submission) (ret []*geddit.Submission) {
|
||||||
|
test := func(s *geddit.Submission) bool {
|
||||||
|
return strings.HasSuffix(s.URL, ".jpg") ||
|
||||||
|
strings.HasSuffix(s.URL, ".png") ||
|
||||||
|
strings.HasSuffix(s.URL, ".gif") ||
|
||||||
|
strings.HasSuffix(s.URL, ".mp4")
|
||||||
|
}
|
||||||
|
ret = filterSubmissions(gs, test)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func fixGfycatURL(sub *geddit.Submission) error {
|
||||||
|
resp, err := http.Get(sub.URL)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
doc, err := goquery.NewDocumentFromReader(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
vids := doc.Find("source")
|
||||||
|
found := false
|
||||||
|
for _, vid := range vids.Nodes {
|
||||||
|
for _, element := range vid.Attr {
|
||||||
|
if strings.HasSuffix(element.Val, ".mp4") && strings.Contains(element.Val, "-mobile") {
|
||||||
|
sub.URL = element.Val
|
||||||
|
found = true
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if !found {
|
||||||
|
return fmt.Errorf("Unable to find Gfycat Video, because they suck.")
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func downloadRedditMedia(s *geddit.Submission) (path string, err error) {
|
||||||
|
// break down the url to get the path, less the host and any arguments or fragments
|
||||||
|
URLParts, err := url.Parse(s.URL)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// get the file extension
|
||||||
|
ext := filepath.Ext(URLParts.Path)
|
||||||
|
if ext == "" {
|
||||||
|
err = fmt.Errorf("URL had no media file extension")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// get the file
|
||||||
|
response, err := http.Get(s.URL)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer response.Body.Close()
|
||||||
|
// open a tmp file for writing
|
||||||
|
uid := uuid.New()
|
||||||
|
path = fmt.Sprintf("/tmp/%s.%s", uid, ext)
|
||||||
|
file, err := os.Create(path)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
defer file.Close()
|
||||||
|
_, err = io.Copy(file, response.Body)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
func getRandomRedditMedia(b *keybasebot.Bot, sub string, sortby string, count int) (path, description string, err error) {
|
||||||
|
submissions, err := getRedditSubmissions(b, sub, sortby, count)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
mediaSubs := filterMedia(submissions)
|
||||||
|
// select a random post
|
||||||
|
rand.Seed(time.Now().Unix())
|
||||||
|
randSub := mediaSubs[rand.Intn(len(mediaSubs))]
|
||||||
|
path, err = downloadRedditMedia(randSub)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
// generate the description
|
||||||
|
description = fmt.Sprintf("image by /u/%s", randSub.Author)
|
||||||
|
return
|
||||||
|
}
|
||||||
17
main.go
17
main.go
@ -1,6 +1,7 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/signal"
|
"os/signal"
|
||||||
"syscall"
|
"syscall"
|
||||||
@ -20,6 +21,10 @@ func main() {
|
|||||||
b.JSON = opts.JSON
|
b.JSON = opts.JSON
|
||||||
b.LogWriter = os.Stdout
|
b.LogWriter = os.Stdout
|
||||||
b.LogConv = chat1.ConvIDStr(opts.LogConvIDStr)
|
b.LogConv = chat1.ConvIDStr(opts.LogConvIDStr)
|
||||||
|
if opts.RedditUser != "" && opts.RedditPass != "" {
|
||||||
|
b.Meta["reddit-user"] = opts.RedditUser
|
||||||
|
b.Meta["reddit-pass"] = opts.RedditPass
|
||||||
|
}
|
||||||
|
|
||||||
// register the bot commands
|
// register the bot commands
|
||||||
b.Commands = append(b.Commands,
|
b.Commands = append(b.Commands,
|
||||||
@ -44,6 +49,18 @@ func main() {
|
|||||||
Run: keybasebot.Adapt(cmd.SendPrice, keybasebot.MessageType("text"), keybasebot.CommandPrefix("!price")),
|
Run: keybasebot.Adapt(cmd.SendPrice, keybasebot.MessageType("text"), keybasebot.CommandPrefix("!price")),
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
// if there are reddit credentials add the reddit commands
|
||||||
|
if opts.RedditPass != "" && opts.RedditUser != "" {
|
||||||
|
b.Commands = append(b.Commands,
|
||||||
|
keybasebot.BotCommand{
|
||||||
|
Name: "eyebleach",
|
||||||
|
Ad: &cmd.EyebleachAd,
|
||||||
|
Run: keybasebot.Adapt(cmd.Eyebleach, keybasebot.MessageType("text"), keybasebot.CommandPrefix("!eyebleach")),
|
||||||
|
},
|
||||||
|
)
|
||||||
|
fmt.Printf("%+v\n", opts)
|
||||||
|
}
|
||||||
|
|
||||||
// catch ctrl-c so we can clean up
|
// catch ctrl-c so we can clean up
|
||||||
c := make(chan os.Signal)
|
c := make(chan os.Signal)
|
||||||
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
signal.Notify(c, os.Interrupt, syscall.SIGTERM)
|
||||||
|
|||||||
Reference in New Issue
Block a user