mirror of https://github.com/velour/catbase.git
Compare commits
3 Commits
250ce836bf
...
789409e159
Author | SHA1 | Date |
---|---|---|
Chris Sexton | 789409e159 | |
Chris Sexton | b978702706 | |
Chris Sexton | ced2108f31 |
|
@ -73,3 +73,4 @@ util/files
|
||||||
gus.sh
|
gus.sh
|
||||||
rathaus.sh
|
rathaus.sh
|
||||||
run.sh
|
run.sh
|
||||||
|
impact.ttf
|
||||||
|
|
|
@ -103,6 +103,7 @@ func (c *Config) GetMap(key string, fallback map[string]string) map[string]strin
|
||||||
vals := map[string]string{}
|
vals := map[string]string{}
|
||||||
err := json.Unmarshal([]byte(content), &vals)
|
err := json.Unmarshal([]byte(content), &vals)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msgf("Could not decode config for %s", key)
|
||||||
return fallback
|
return fallback
|
||||||
}
|
}
|
||||||
return vals
|
return vals
|
||||||
|
|
|
@ -17,6 +17,8 @@ import (
|
||||||
"text/template"
|
"text/template"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
zerowidth "github.com/trubitsyn/go-zero-width"
|
||||||
|
|
||||||
"github.com/rs/zerolog/log"
|
"github.com/rs/zerolog/log"
|
||||||
|
|
||||||
"github.com/slack-go/slack"
|
"github.com/slack-go/slack"
|
||||||
|
@ -419,6 +421,8 @@ func (s *SlackApp) buildMessage(m *slackevents.MessageEvent) msg.Message {
|
||||||
|
|
||||||
// Slack likes to put these NBSP in and it screws with matching later
|
// Slack likes to put these NBSP in and it screws with matching later
|
||||||
text = strings.ReplaceAll(text, "\u00a0", " ")
|
text = strings.ReplaceAll(text, "\u00a0", " ")
|
||||||
|
text = strings.ReplaceAll(text, "\ufe0f", "")
|
||||||
|
text = zerowidth.RemoveZeroWidthCharacters(text)
|
||||||
|
|
||||||
isCmd, text := bot.IsCmd(s.config, text)
|
isCmd, text := bot.IsCmd(s.config, text)
|
||||||
|
|
||||||
|
|
1
go.mod
1
go.mod
|
@ -54,6 +54,7 @@ require (
|
||||||
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
|
||||||
github.com/temoto/robotstxt v1.1.1 // indirect
|
github.com/temoto/robotstxt v1.1.1 // indirect
|
||||||
|
github.com/trubitsyn/go-zero-width v1.0.1
|
||||||
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 // indirect
|
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 // indirect
|
||||||
github.com/ttacon/libphonenumber v1.1.0 // indirect
|
github.com/ttacon/libphonenumber v1.1.0 // indirect
|
||||||
github.com/velour/chat v0.0.0-20180713122344-fd1d1606cb89
|
github.com/velour/chat v0.0.0-20180713122344-fd1d1606cb89
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -139,6 +139,8 @@ github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJy
|
||||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||||
github.com/temoto/robotstxt v1.1.1 h1:Gh8RCs8ouX3hRSxxK7B1mO5RFByQ4CmJZDwgom++JaA=
|
github.com/temoto/robotstxt v1.1.1 h1:Gh8RCs8ouX3hRSxxK7B1mO5RFByQ4CmJZDwgom++JaA=
|
||||||
github.com/temoto/robotstxt v1.1.1/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo=
|
github.com/temoto/robotstxt v1.1.1/go.mod h1:+1AmkuG3IYkh1kv0d2qEB9Le88ehNO0zwOr3ujewlOo=
|
||||||
|
github.com/trubitsyn/go-zero-width v1.0.1 h1:AAZhtyGXW79T5BouAF0R9FtDhGcp7IGbLZo2Id3N+m8=
|
||||||
|
github.com/trubitsyn/go-zero-width v1.0.1/go.mod h1:gGhBV4CZHjqXBYSgaxTCKZj+dXJndhdm1zAtAChtIUI=
|
||||||
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 h1:5u+EJUQiosu3JFX0XS0qTf5FznsMOzTjGqavBGuCbo0=
|
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2 h1:5u+EJUQiosu3JFX0XS0qTf5FznsMOzTjGqavBGuCbo0=
|
||||||
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2/go.mod h1:4kyMkleCiLkgY6z8gK5BkI01ChBtxR0ro3I1ZDcGM3w=
|
github.com/ttacon/builder v0.0.0-20170518171403-c099f663e1c2/go.mod h1:4kyMkleCiLkgY6z8gK5BkI01ChBtxR0ro3I1ZDcGM3w=
|
||||||
github.com/ttacon/libphonenumber v1.1.0 h1:tC6kE4t8UI4OqQVQjW5q8gSWhG2wnY5moEpSEORdYm4=
|
github.com/ttacon/libphonenumber v1.1.0 h1:tC6kE4t8UI4OqQVQjW5q8gSWhG2wnY5moEpSEORdYm4=
|
||||||
|
|
|
@ -102,30 +102,6 @@ func (p *MemePlugin) help(c bot.Connector, kind bot.Kind, message msg.Message, a
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *MemePlugin) registerWeb(c bot.Connector) {
|
|
||||||
http.HandleFunc("/slash/meme", p.slashMeme(c))
|
|
||||||
http.HandleFunc("/meme/img/", p.img)
|
|
||||||
http.HandleFunc("/meme/all", p.all)
|
|
||||||
http.HandleFunc("/meme/add", p.addMeme)
|
|
||||||
http.HandleFunc("/meme/rm", p.rmMeme)
|
|
||||||
http.HandleFunc("/meme", p.webRoot)
|
|
||||||
p.bot.RegisterWeb("/meme", "Memes")
|
|
||||||
}
|
|
||||||
|
|
||||||
type webResp struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
URL string `json:"url"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type webResps []webResp
|
|
||||||
|
|
||||||
func (w webResps) Len() int { return len(w) }
|
|
||||||
func (w webResps) Swap(i, j int) { w[i], w[j] = w[j], w[i] }
|
|
||||||
|
|
||||||
type ByName struct{ webResps }
|
|
||||||
|
|
||||||
func (s ByName) Less(i, j int) bool { return s.webResps[i].Name < s.webResps[j].Name }
|
|
||||||
|
|
||||||
func (p *MemePlugin) bully(c bot.Connector, format, id string) image.Image {
|
func (p *MemePlugin) bully(c bot.Connector, format, id string) image.Image {
|
||||||
bullyIcon := ""
|
bullyIcon := ""
|
||||||
|
|
||||||
|
@ -185,27 +161,33 @@ func (p *MemePlugin) sendMeme(c bot.Connector, channel, channelName, msgID strin
|
||||||
message += c.Text + "\n"
|
message += c.Text + "\n"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
top, bottom := "", message
|
|
||||||
if strings.Contains(message, "||") {
|
if strings.Contains(message, "||") {
|
||||||
parts = strings.Split(message, "||")
|
parts = strings.Split(message, "||")
|
||||||
} else {
|
} else {
|
||||||
parts = strings.Split(message, "\n")
|
parts = strings.Split(message, "\n")
|
||||||
}
|
}
|
||||||
if len(parts) > 1 {
|
|
||||||
top, bottom = parts[0], parts[1]
|
allConfigs := p.c.GetMap("meme.memeconfigs", map[string]string{})
|
||||||
|
configtxt, ok := allConfigs[format]
|
||||||
|
if !ok {
|
||||||
|
config = defaultFormatConfig
|
||||||
|
log.Debug().Msgf("Did not find %s in %+v", format, allConfigs)
|
||||||
|
} else {
|
||||||
|
err = json.Unmarshal([]byte(configtxt), &config)
|
||||||
|
if err != nil {
|
||||||
|
log.Error().Err(err).Msgf("Could not parse config for %s:\n%s", format, configtxt)
|
||||||
|
config = defaultFormatConfig
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if top == "_" {
|
j := 0
|
||||||
message = bottom
|
for i := range config {
|
||||||
} else if bottom == "_" {
|
if len(parts) > i {
|
||||||
message = top
|
if parts[j] != "_" {
|
||||||
|
config[i].Text = parts[j]
|
||||||
|
}
|
||||||
|
j++
|
||||||
}
|
}
|
||||||
|
|
||||||
topPos := p.bot.Config().GetFloat64("meme.top", 0.05)
|
|
||||||
bottomPos := p.bot.Config().GetFloat64("meme.bottom", 0.95)
|
|
||||||
config = []memeText{
|
|
||||||
{Text: top, XPerc: 0.5, YPerc: topPos},
|
|
||||||
{Text: bottom, XPerc: 0.5, YPerc: bottomPos},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -343,6 +325,11 @@ func (p *MemePlugin) findFontSize(config []memeText, w, h int, sizes []float64)
|
||||||
return fontSize
|
return fontSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var defaultFormatConfig = []memeText{
|
||||||
|
{XPerc: 0.5, YPerc: 0.05},
|
||||||
|
{XPerc: 0.5, YPerc: 0.95},
|
||||||
|
}
|
||||||
|
|
||||||
func (p *MemePlugin) genMeme(meme string, bully image.Image, config []memeText) (string, int, int, error) {
|
func (p *MemePlugin) genMeme(meme string, bully image.Image, config []memeText) (string, int, int, error) {
|
||||||
fontSizes := []float64{48, 36, 24, 16, 12}
|
fontSizes := []float64{48, 36, 24, 16, 12}
|
||||||
formats := p.c.GetMap("meme.memes", defaultFormats)
|
formats := p.c.GetMap("meme.memes", defaultFormats)
|
||||||
|
|
|
@ -38,13 +38,16 @@ var memeIndex = `
|
||||||
<b-form @submit="addMeme">
|
<b-form @submit="addMeme">
|
||||||
<b-container>
|
<b-container>
|
||||||
<b-row>
|
<b-row>
|
||||||
<b-col cols="5">
|
<b-col cols="3">
|
||||||
<b-input placeholder="Name..." v-model="name"></b-input>
|
<b-input placeholder="Name..." v-model="name"></b-input>
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col cols="5">
|
<b-col cols="3">
|
||||||
<b-input placeholder="URL..." v-model="url"></b-input>
|
<b-input placeholder="URL..." v-model="url"></b-input>
|
||||||
</b-col>
|
</b-col>
|
||||||
<b-col cols="2">
|
<b-col cols="3">
|
||||||
|
<b-input placeholder="Config..." v-model="config"></b-input>
|
||||||
|
</b-col>
|
||||||
|
<b-col cols="3">
|
||||||
<b-button type="submit">Add Meme</b-button>
|
<b-button type="submit">Add Meme</b-button>
|
||||||
</b-col>
|
</b-col>
|
||||||
</b-row>
|
</b-row>
|
||||||
|
@ -54,6 +57,9 @@ var memeIndex = `
|
||||||
fixed
|
fixed
|
||||||
:items="results"
|
:items="results"
|
||||||
:fields="fields">
|
:fields="fields">
|
||||||
|
<template v-slot:cell(config)="data">
|
||||||
|
<pre>{{ "{{data.item.config}}" }}</pre>
|
||||||
|
</template>
|
||||||
<template v-slot:cell(image)="data">
|
<template v-slot:cell(image)="data">
|
||||||
<b-img :src="data.item.url" rounded block fluid />
|
<b-img :src="data.item.url" rounded block fluid />
|
||||||
</template>
|
</template>
|
||||||
|
@ -77,10 +83,12 @@ var memeIndex = `
|
||||||
nav: {{ .Nav }},
|
nav: {{ .Nav }},
|
||||||
name: "",
|
name: "",
|
||||||
url: "",
|
url: "",
|
||||||
|
config: "",
|
||||||
results: [],
|
results: [],
|
||||||
fields: [
|
fields: [
|
||||||
{ key: 'name', sortable: true },
|
{ key: 'name', sortable: true },
|
||||||
{ key: 'url', sortable: true },
|
{ key: 'url', sortable: true },
|
||||||
|
{ key: 'config' },
|
||||||
{ key: 'image' }
|
{ key: 'image' }
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
@ -103,11 +111,12 @@ var memeIndex = `
|
||||||
evt.stopPropagation()
|
evt.stopPropagation()
|
||||||
}
|
}
|
||||||
if (this.name && this.url)
|
if (this.name && this.url)
|
||||||
axios.post('/meme/add', {Name: this.name, URL: this.url})
|
axios.post('/meme/add', {name: this.name, url: this.url, config: this.config})
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
this.results = resp.data;
|
this.results = resp.data;
|
||||||
this.name = "";
|
this.name = "";
|
||||||
this.url = "";
|
this.url = "";
|
||||||
|
this.config = "";
|
||||||
this.refresh();
|
this.refresh();
|
||||||
})
|
})
|
||||||
.catch(err => (this.err = err));
|
.catch(err => (this.err = err));
|
||||||
|
|
|
@ -14,21 +14,52 @@ import (
|
||||||
"github.com/velour/catbase/bot"
|
"github.com/velour/catbase/bot"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (p *MemePlugin) registerWeb(c bot.Connector) {
|
||||||
|
http.HandleFunc("/slash/meme", p.slashMeme(c))
|
||||||
|
http.HandleFunc("/meme/img/", p.img)
|
||||||
|
http.HandleFunc("/meme/all", p.all)
|
||||||
|
http.HandleFunc("/meme/add", p.addMeme)
|
||||||
|
http.HandleFunc("/meme/rm", p.rmMeme)
|
||||||
|
http.HandleFunc("/meme", p.webRoot)
|
||||||
|
p.bot.RegisterWeb("/meme", "Memes")
|
||||||
|
}
|
||||||
|
|
||||||
|
type webResp struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
URL string `json:"url"`
|
||||||
|
Config string `json:"config"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type webResps []webResp
|
||||||
|
|
||||||
|
func (w webResps) Len() int { return len(w) }
|
||||||
|
func (w webResps) Swap(i, j int) { w[i], w[j] = w[j], w[i] }
|
||||||
|
|
||||||
|
type ByName struct{ webResps }
|
||||||
|
|
||||||
|
func (s ByName) Less(i, j int) bool { return s.webResps[i].Name < s.webResps[j].Name }
|
||||||
|
|
||||||
func (p *MemePlugin) all(w http.ResponseWriter, r *http.Request) {
|
func (p *MemePlugin) all(w http.ResponseWriter, r *http.Request) {
|
||||||
memes := p.c.GetMap("meme.memes", defaultFormats)
|
memes := p.c.GetMap("meme.memes", defaultFormats)
|
||||||
|
configs := p.c.GetMap("meme.memeconfigs", map[string]string{})
|
||||||
|
|
||||||
values := webResps{}
|
values := webResps{}
|
||||||
for n, u := range memes {
|
for n, u := range memes {
|
||||||
|
config, ok := configs[n]
|
||||||
|
if !ok {
|
||||||
|
b, _ := json.Marshal(defaultFormatConfig)
|
||||||
|
config = string(b)
|
||||||
|
}
|
||||||
realURL, err := url.Parse(u)
|
realURL, err := url.Parse(u)
|
||||||
if err != nil || realURL.Scheme == "" {
|
if err != nil || realURL.Scheme == "" {
|
||||||
realURL, err = url.Parse("https://imgflip.com/s/meme/" + u)
|
realURL, err = url.Parse("https://imgflip.com/s/meme/" + u)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
values = append(values, webResp{n, "404.png"})
|
values = append(values, webResp{n, "404.png", config})
|
||||||
log.Error().Err(err).Msgf("invalid URL")
|
log.Error().Err(err).Msgf("invalid URL")
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
values = append(values, webResp{n, realURL.String()})
|
values = append(values, webResp{n, realURL.String(), config})
|
||||||
}
|
}
|
||||||
sort.Sort(ByName{values})
|
sort.Sort(ByName{values})
|
||||||
|
|
||||||
|
@ -84,12 +115,18 @@ func (p *MemePlugin) addMeme(w http.ResponseWriter, r *http.Request) {
|
||||||
values := webResp{}
|
values := webResp{}
|
||||||
err := decoder.Decode(&values)
|
err := decoder.Decode(&values)
|
||||||
if checkError(err) {
|
if checkError(err) {
|
||||||
|
log.Error().Err(err).Msgf("could not decode body")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
log.Debug().Msgf("POSTed values: %+v", values)
|
||||||
formats := p.c.GetMap("meme.memes", defaultFormats)
|
formats := p.c.GetMap("meme.memes", defaultFormats)
|
||||||
formats[values.Name] = values.URL
|
formats[values.Name] = values.URL
|
||||||
err = p.c.SetMap("meme.memes", formats)
|
err = p.c.SetMap("meme.memes", formats)
|
||||||
checkError(err)
|
checkError(err)
|
||||||
|
configs := p.c.GetMap("meme.memeconfigs", map[string]string{})
|
||||||
|
configs[values.Name] = values.Config
|
||||||
|
err = p.c.SetMap("meme.memeconfigs", configs)
|
||||||
|
checkError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *MemePlugin) webRoot(w http.ResponseWriter, r *http.Request) {
|
func (p *MemePlugin) webRoot(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
Loading…
Reference in New Issue