mirror of https://github.com/velour/catbase.git
Compare commits
4 Commits
c6559530e7
...
d5a2bec582
Author | SHA1 | Date |
---|---|---|
Chris Sexton | d5a2bec582 | |
Chris Sexton | 10a1745502 | |
Chris Sexton | c184566f07 | |
Chris Sexton | 0057f91ce6 |
|
@ -81,6 +81,7 @@ type Connector interface {
|
||||||
Serve() error
|
Serve() error
|
||||||
|
|
||||||
Who(string) []string
|
Who(string) []string
|
||||||
|
Profile(string) (user.User, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Plugin interface used for compatibility with the Plugin interface
|
// Plugin interface used for compatibility with the Plugin interface
|
||||||
|
|
|
@ -9,6 +9,7 @@ type User struct {
|
||||||
ID string
|
ID string
|
||||||
Name string
|
Name string
|
||||||
Admin bool
|
Admin bool
|
||||||
|
Icon string
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(name string) User {
|
func New(name string) User {
|
||||||
|
|
|
@ -310,3 +310,7 @@ func (i *Irc) buildMessage(inMsg irc.Msg) msg.Message {
|
||||||
func (i Irc) Who(channel string) []string {
|
func (i Irc) Who(channel string) []string {
|
||||||
return []string{}
|
return []string{}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (i Irc) Profile(string) (user.User, error) {
|
||||||
|
return user.User{}, fmt.Errorf("unimplemented")
|
||||||
|
}
|
||||||
|
|
|
@ -730,3 +730,7 @@ func (s *Slack) Who(id string) []string {
|
||||||
log.Debug().Msgf("Returning %d handles", len(handles))
|
log.Debug().Msgf("Returning %d handles", len(handles))
|
||||||
return handles
|
return handles
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *Slack) Profile(string) (user.User, error) {
|
||||||
|
return user.User{}, fmt.Errorf("unimplemented")
|
||||||
|
}
|
||||||
|
|
|
@ -2,6 +2,8 @@ package slackapp
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"unicode/utf8"
|
"unicode/utf8"
|
||||||
|
|
||||||
|
"github.com/slack-go/slack"
|
||||||
)
|
)
|
||||||
|
|
||||||
// fixText strips all of the Slack-specific annotations from message text,
|
// fixText strips all of the Slack-specific annotations from message text,
|
||||||
|
@ -13,7 +15,7 @@ import (
|
||||||
// • Strips < and > surrounding links.
|
// • Strips < and > surrounding links.
|
||||||
//
|
//
|
||||||
// This was directly bogarted from velour/chat with emoji conversion removed.
|
// This was directly bogarted from velour/chat with emoji conversion removed.
|
||||||
func fixText(findUser func(id, defaultName string) string, text string) string {
|
func fixText(findUser func(id, defaultName string) (string, *slack.User), text string) string {
|
||||||
var output []rune
|
var output []rune
|
||||||
for len(text) > 0 {
|
for len(text) > 0 {
|
||||||
r, i := utf8.DecodeRuneInString(text)
|
r, i := utf8.DecodeRuneInString(text)
|
||||||
|
@ -48,14 +50,14 @@ func fixText(findUser func(id, defaultName string) string, text string) string {
|
||||||
return string(output)
|
return string(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
func fixTag(findUser func(string, string) string, tag []rune) ([]rune, bool) {
|
func fixTag(findUser func(string, string) (string, *slack.User), tag []rune) ([]rune, bool) {
|
||||||
switch {
|
switch {
|
||||||
case hasPrefix(tag, "@U"):
|
case hasPrefix(tag, "@U"):
|
||||||
if i := indexRune(tag, '|'); i >= 0 {
|
if i := indexRune(tag, '|'); i >= 0 {
|
||||||
return tag[i+1:], true
|
return tag[i+1:], true
|
||||||
}
|
}
|
||||||
if findUser != nil {
|
if findUser != nil {
|
||||||
u := findUser(string(tag[1:]), "unknown")
|
u, _ := findUser(string(tag[1:]), "unknown")
|
||||||
return []rune(u), true
|
return []rune(u), true
|
||||||
}
|
}
|
||||||
return tag, true
|
return tag, true
|
||||||
|
|
|
@ -19,8 +19,8 @@ import (
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
"github.com/nlopes/slack"
|
"github.com/slack-go/slack"
|
||||||
"github.com/nlopes/slack/slackevents"
|
"github.com/slack-go/slack/slackevents"
|
||||||
|
|
||||||
"github.com/velour/catbase/bot"
|
"github.com/velour/catbase/bot"
|
||||||
"github.com/velour/catbase/bot/msg"
|
"github.com/velour/catbase/bot/msg"
|
||||||
|
@ -422,7 +422,12 @@ func (s *SlackApp) buildMessage(m *slackevents.MessageEvent) msg.Message {
|
||||||
if m.BotID != "" {
|
if m.BotID != "" {
|
||||||
defaultName = m.Username
|
defaultName = m.Username
|
||||||
}
|
}
|
||||||
name := s.getUser(m.User, defaultName)
|
icon := ""
|
||||||
|
log.Debug().Msgf("Getting user %s", m.User)
|
||||||
|
name, u := s.getUser(m.User, defaultName)
|
||||||
|
if u != nil {
|
||||||
|
icon = u.Profile.Image192
|
||||||
|
}
|
||||||
if m.Username != "" && name == "unknown" {
|
if m.Username != "" && name == "unknown" {
|
||||||
name = m.Username
|
name = m.Username
|
||||||
}
|
}
|
||||||
|
@ -438,6 +443,7 @@ func (s *SlackApp) buildMessage(m *slackevents.MessageEvent) msg.Message {
|
||||||
User: &user.User{
|
User: &user.User{
|
||||||
ID: m.User,
|
ID: m.User,
|
||||||
Name: name,
|
Name: name,
|
||||||
|
Icon: icon,
|
||||||
},
|
},
|
||||||
Body: text,
|
Body: text,
|
||||||
Raw: m,
|
Raw: m,
|
||||||
|
@ -478,9 +484,9 @@ func stringForUser(user *slack.User) string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get username for Slack user ID
|
// Get username for Slack user ID
|
||||||
func (s *SlackApp) getUser(id, defaultName string) string {
|
func (s *SlackApp) getUser(id, defaultName string) (string, *slack.User) {
|
||||||
if u, ok := s.users[id]; ok {
|
if u, ok := s.users[id]; ok {
|
||||||
return stringForUser(u)
|
return stringForUser(u), u
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Debug().
|
log.Debug().
|
||||||
|
@ -489,10 +495,10 @@ func (s *SlackApp) getUser(id, defaultName string) string {
|
||||||
|
|
||||||
u, err := s.api.GetUserInfo(id)
|
u, err := s.api.GetUserInfo(id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return defaultName
|
return defaultName, nil
|
||||||
}
|
}
|
||||||
s.users[id] = u
|
s.users[id] = u
|
||||||
return stringForUser(u)
|
return stringForUser(u), u
|
||||||
}
|
}
|
||||||
|
|
||||||
// Who gets usernames out of a channel
|
// Who gets usernames out of a channel
|
||||||
|
@ -522,7 +528,7 @@ func (s *SlackApp) Who(id string) []string {
|
||||||
if m == "" {
|
if m == "" {
|
||||||
log.Error().Msg("empty member")
|
log.Error().Msg("empty member")
|
||||||
}
|
}
|
||||||
u := s.getUser(m, "unknown")
|
u, _ := s.getUser(m, "unknown")
|
||||||
if u == "unknown" {
|
if u == "unknown" {
|
||||||
log.Error().
|
log.Error().
|
||||||
Err(err).
|
Err(err).
|
||||||
|
@ -599,7 +605,7 @@ func (s *SlackApp) log(msg, channel string) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SlackApp) reactionReceived(event *slack.ReactionAddedEvent) error {
|
func (s *SlackApp) reactionReceived(event *slack.ReactionAddedEvent) error {
|
||||||
name := s.getUser(event.User, "unknown")
|
name, _ := s.getUser(event.User, "unknown")
|
||||||
|
|
||||||
ch, err := s.getChannel(event.Item.Channel)
|
ch, err := s.getChannel(event.Item.Channel)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -619,7 +625,7 @@ func (s *SlackApp) reactionReceived(event *slack.ReactionAddedEvent) error {
|
||||||
if m.BotID != "" {
|
if m.BotID != "" {
|
||||||
defaultName = m.Username
|
defaultName = m.Username
|
||||||
}
|
}
|
||||||
u := s.getUser(m.User, defaultName)
|
u, _ := s.getUser(m.User, defaultName)
|
||||||
body = fmt.Sprintf("%s: %s", u, m.Text)
|
body = fmt.Sprintf("%s: %s", u, m.Text)
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -634,3 +640,25 @@ func (s *SlackApp) reactionReceived(event *slack.ReactionAddedEvent) error {
|
||||||
|
|
||||||
return s.log(msg, channel)
|
return s.log(msg, channel)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *SlackApp) Profile(name string) (user.User, error) {
|
||||||
|
log.Debug().Msgf("Getting profile for %s", name)
|
||||||
|
|
||||||
|
users, err := s.api.GetUsers()
|
||||||
|
if err != nil {
|
||||||
|
return user.User{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, u := range users {
|
||||||
|
if u.Name == name {
|
||||||
|
return user.User{
|
||||||
|
ID: u.ID,
|
||||||
|
Name: stringForUser(&u),
|
||||||
|
Admin: false,
|
||||||
|
Icon: u.Profile.Image192,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return user.User{}, fmt.Errorf("user %s not found", err)
|
||||||
|
}
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -36,11 +36,11 @@ require (
|
||||||
github.com/mmcdole/gofeed v1.0.0-beta2
|
github.com/mmcdole/gofeed v1.0.0-beta2
|
||||||
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf // indirect
|
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf // indirect
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
|
||||||
github.com/nlopes/slack v0.6.0
|
|
||||||
github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254
|
github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254
|
||||||
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d // indirect
|
github.com/robertkrimen/otto v0.0.0-20180617131154-15f95af6e78d // indirect
|
||||||
github.com/rs/zerolog v1.15.0
|
github.com/rs/zerolog v1.15.0
|
||||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
|
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca // indirect
|
||||||
|
github.com/slack-go/slack v0.6.4
|
||||||
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
github.com/spaolacci/murmur3 v1.1.0 // indirect
|
||||||
github.com/stretchr/objx v0.2.0 // indirect
|
github.com/stretchr/objx v0.2.0 // indirect
|
||||||
github.com/stretchr/testify v1.4.0
|
github.com/stretchr/testify v1.4.0
|
||||||
|
|
6
go.sum
6
go.sum
|
@ -50,6 +50,8 @@ github.com/garyburd/go-oauth v0.0.0-20180319155456-bca2e7f09a17/go.mod h1:HfkOCN
|
||||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||||
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
|
github.com/go-sql-driver/mysql v1.4.0 h1:7LxgVwFb2hIQtMm87NdgAVfXjnt4OePseqT1tKx+opk=
|
||||||
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
|
||||||
|
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
|
||||||
|
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
|
||||||
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y=
|
||||||
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8=
|
||||||
github.com/gocolly/colly v1.2.0 h1:qRz9YAn8FIH0qzgNUw+HT9UN7wm1oF9OBAilwEWpyrI=
|
github.com/gocolly/colly v1.2.0 h1:qRz9YAn8FIH0qzgNUw+HT9UN7wm1oF9OBAilwEWpyrI=
|
||||||
|
@ -90,8 +92,6 @@ github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf h1:sWGE2v+hO0Nd4yFU/
|
||||||
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf/go.mod h1:pasqhqstspkosTneA62Nc+2p9SOBBYAPbnmRRWPQ0V8=
|
github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf/go.mod h1:pasqhqstspkosTneA62Nc+2p9SOBBYAPbnmRRWPQ0V8=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 h1:zYyBkD/k9seD2A7fsi6Oo2LfFZAehjjQMERAvZLEDnQ=
|
||||||
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
|
||||||
github.com/nlopes/slack v0.6.0 h1:jt0jxVQGhssx1Ib7naAOZEZcGdtIhTzkP0nopK0AsRA=
|
|
||||||
github.com/nlopes/slack v0.6.0/go.mod h1:JzQ9m3PMAqcpeCam7UaHSuBuupz7CmpjehYMayT6YOk=
|
|
||||||
github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254 h1:JYoQR67E1vv1WGoeW8DkdFs7vrIEe/5wP+qJItd5tUE=
|
github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254 h1:JYoQR67E1vv1WGoeW8DkdFs7vrIEe/5wP+qJItd5tUE=
|
||||||
github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254/go.mod h1:DPucAeQGDPUzYUt+NaWw6qsF5SFapWWToxEiVDh2aV0=
|
github.com/olebedev/when v0.0.0-20190311101825-c3b538a97254/go.mod h1:DPucAeQGDPUzYUt+NaWw6qsF5SFapWWToxEiVDh2aV0=
|
||||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
@ -106,6 +106,8 @@ github.com/rs/zerolog v1.15.0 h1:uPRuwkWF4J6fGsJ2R0Gn2jB1EQiav9k3S6CSdygQJXY=
|
||||||
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
github.com/rs/zerolog v1.15.0/go.mod h1:xYTKnLHcpfU2225ny5qZjxnj9NvkumZYjJHlAThCjNc=
|
||||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
|
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca h1:NugYot0LIVPxTvN8n+Kvkn6TrbMyxQiuvKdEwFdR9vI=
|
||||||
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
github.com/saintfish/chardet v0.0.0-20120816061221-3af4cd4741ca/go.mod h1:uugorj2VCxiV1x+LzaIdVa9b4S4qGAcH6cbhh4qVxOU=
|
||||||
|
github.com/slack-go/slack v0.6.4 h1:cxOqFgM5RW6mdEyDqAJutFk3qiORK9oHRKi5bPqkY9o=
|
||||||
|
github.com/slack-go/slack v0.6.4/go.mod h1:sGRjv3w+ERAUMMMbldHObQPBcNSyVB7KLKYfnwUFBfw=
|
||||||
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI=
|
||||||
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
|
||||||
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
|
||||||
|
|
|
@ -5,14 +5,16 @@ package cli
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/jmoiron/sqlx"
|
|
||||||
"github.com/rs/zerolog/log"
|
|
||||||
"github.com/velour/catbase/bot"
|
|
||||||
"github.com/velour/catbase/bot/msg"
|
|
||||||
"github.com/velour/catbase/bot/user"
|
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/jmoiron/sqlx"
|
||||||
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
|
"github.com/velour/catbase/bot"
|
||||||
|
"github.com/velour/catbase/bot/msg"
|
||||||
|
"github.com/velour/catbase/bot/user"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CliPlugin struct {
|
type CliPlugin struct {
|
||||||
|
@ -115,3 +117,6 @@ func (p *CliPlugin) Send(kind bot.Kind, args ...interface{}) (string, error) {
|
||||||
func (p *CliPlugin) GetEmojiList() map[string]string { return nil }
|
func (p *CliPlugin) GetEmojiList() map[string]string { return nil }
|
||||||
func (p *CliPlugin) Serve() error { return nil }
|
func (p *CliPlugin) Serve() error { return nil }
|
||||||
func (p *CliPlugin) Who(s string) []string { return nil }
|
func (p *CliPlugin) Who(s string) []string { return nil }
|
||||||
|
func (s *CliPlugin) Profile(name string) (user.User, error) {
|
||||||
|
return user.User{}, fmt.Errorf("unimplemented")
|
||||||
|
}
|
||||||
|
|
|
@ -6,6 +6,8 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"image"
|
"image"
|
||||||
|
"image/color"
|
||||||
|
"image/draw"
|
||||||
"image/png"
|
"image/png"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
|
@ -214,14 +216,25 @@ func (p *MemePlugin) slashMeme(c bot.Connector) http.HandlerFunc {
|
||||||
isCmd, message := bot.IsCmd(p.c, parts[1])
|
isCmd, message := bot.IsCmd(p.c, parts[1])
|
||||||
format := parts[0]
|
format := parts[0]
|
||||||
|
|
||||||
|
bullyIcon := ""
|
||||||
|
|
||||||
for _, bully := range p.c.GetArray("meme.bully", []string{}) {
|
for _, bully := range p.c.GetArray("meme.bully", []string{}) {
|
||||||
if format == bully {
|
if format == bully {
|
||||||
|
if u, err := c.Profile(bully); err == nil {
|
||||||
|
bullyIcon = u.Icon
|
||||||
|
} else {
|
||||||
|
log.Debug().Err(err).Msgf("could not get profile for %s", format)
|
||||||
|
}
|
||||||
formats := p.c.GetMap("meme.memes", defaultFormats)
|
formats := p.c.GetMap("meme.memes", defaultFormats)
|
||||||
format = randEntry(formats)
|
format = randEntry(formats)
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if u, err := c.Profile(from); bullyIcon == "" && err == nil {
|
||||||
|
bullyIcon = u.Icon
|
||||||
|
}
|
||||||
|
|
||||||
log.Debug().Strs("parts", parts).Msgf("Meme:\n%+v", text)
|
log.Debug().Strs("parts", parts).Msgf("Meme:\n%+v", text)
|
||||||
w.WriteHeader(200)
|
w.WriteHeader(200)
|
||||||
w.Write(nil)
|
w.Write(nil)
|
||||||
|
@ -239,7 +252,7 @@ func (p *MemePlugin) slashMeme(c bot.Connector) http.HandlerFunc {
|
||||||
message = top
|
message = top
|
||||||
}
|
}
|
||||||
|
|
||||||
id, err := p.genMeme(format, top, bottom)
|
id, err := p.genMeme(format, top, bottom, bullyIcon)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
msg := fmt.Sprintf("Hey %s, I couldn't download that image you asked for.", from)
|
msg := fmt.Sprintf("Hey %s, I couldn't download that image you asked for.", from)
|
||||||
p.bot.Send(c, bot.Message, channel, msg)
|
p.bot.Send(c, bot.Message, channel, msg)
|
||||||
|
@ -304,7 +317,7 @@ var defaultFormats = map[string]string{
|
||||||
"raptor": "Philosoraptor.jpg",
|
"raptor": "Philosoraptor.jpg",
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *MemePlugin) genMeme(meme, top, bottom string) (string, error) {
|
func (p *MemePlugin) genMeme(meme, top, bottom, bully string) (string, error) {
|
||||||
fontSizes := []float64{48, 36, 24, 16, 12}
|
fontSizes := []float64{48, 36, 24, 16, 12}
|
||||||
fontSize := fontSizes[0]
|
fontSize := fontSizes[0]
|
||||||
|
|
||||||
|
@ -354,6 +367,10 @@ func (p *MemePlugin) genMeme(meme, top, bottom string) (string, error) {
|
||||||
h = r.Dy()
|
h = r.Dy()
|
||||||
log.Debug().Msgf("resized to %v, %v", w, h)
|
log.Debug().Msgf("resized to %v, %v", w, h)
|
||||||
|
|
||||||
|
if bully != "" {
|
||||||
|
img = p.applyBully(img, bully)
|
||||||
|
}
|
||||||
|
|
||||||
m := gg.NewContext(w, h)
|
m := gg.NewContext(w, h)
|
||||||
m.DrawImage(img, 0, 0)
|
m.DrawImage(img, 0, 0)
|
||||||
fontLocation := p.c.Get("meme.font", "impact.ttf")
|
fontLocation := p.c.Get("meme.font", "impact.ttf")
|
||||||
|
@ -407,3 +424,58 @@ func (p *MemePlugin) genMeme(meme, top, bottom string) (string, error) {
|
||||||
|
|
||||||
return path, nil
|
return path, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *MemePlugin) applyBully(img image.Image, bully string) image.Image {
|
||||||
|
log.Debug().Msgf("applying bully: %s", bully)
|
||||||
|
dst := image.NewRGBA(img.Bounds())
|
||||||
|
u, err := url.Parse(bully)
|
||||||
|
if err != nil {
|
||||||
|
return img
|
||||||
|
}
|
||||||
|
bullyImg, err := DownloadTemplate(u)
|
||||||
|
if err != nil {
|
||||||
|
return img
|
||||||
|
}
|
||||||
|
|
||||||
|
scaleFactor := p.c.GetFloat64("meme.bullyScale", 0.1)
|
||||||
|
|
||||||
|
scaleFactor = float64(img.Bounds().Max.X) * scaleFactor / float64(bullyImg.Bounds().Max.X)
|
||||||
|
|
||||||
|
newSzX := uint(float64(bullyImg.Bounds().Max.X) * scaleFactor)
|
||||||
|
newSzY := uint(float64(bullyImg.Bounds().Max.Y) * scaleFactor)
|
||||||
|
|
||||||
|
bullyImg = resize.Resize(newSzX, newSzY, bullyImg, resize.Lanczos3)
|
||||||
|
|
||||||
|
draw.Draw(dst, img.Bounds(), img, image.Point{}, draw.Src)
|
||||||
|
srcSz := img.Bounds().Size()
|
||||||
|
|
||||||
|
w, h := bullyImg.Bounds().Max.X, bullyImg.Bounds().Max.Y
|
||||||
|
|
||||||
|
pt := image.Point{srcSz.X - w, srcSz.Y - h}
|
||||||
|
rect := image.Rect(pt.X, pt.Y, srcSz.X, srcSz.Y)
|
||||||
|
|
||||||
|
draw.DrawMask(dst, rect, bullyImg, image.Point{}, &circle{image.Point{w / 2, h / 2}, w / 2}, image.Point{}, draw.Over)
|
||||||
|
return dst
|
||||||
|
}
|
||||||
|
|
||||||
|
// the following is ripped off of https://blog.golang.org/image-draw
|
||||||
|
type circle struct {
|
||||||
|
p image.Point
|
||||||
|
r int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *circle) ColorModel() color.Model {
|
||||||
|
return color.AlphaModel
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *circle) Bounds() image.Rectangle {
|
||||||
|
return image.Rect(c.p.X-c.r, c.p.Y-c.r, c.p.X+c.r, c.p.Y+c.r)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *circle) At(x, y int) color.Color {
|
||||||
|
xx, yy, rr := float64(x-c.p.X)+0.5, float64(y-c.p.Y)+0.5, float64(c.r)
|
||||||
|
if xx*xx+yy*yy < rr*rr {
|
||||||
|
return color.Alpha{255}
|
||||||
|
}
|
||||||
|
return color.Alpha{0}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue