connectors: add translation layer

* URLs can be translated to slack/discord compatible
* Emojy have a connector-specific translation configuration
* Advent of Code plugin respects emojy and URLs
* Config can be wrapped in `` for JSON
This commit is contained in:
Chris Sexton 2020-12-02 09:53:57 -05:00
parent c8e1956099
commit 9dbdd1f9a3
10 changed files with 107 additions and 17 deletions

View File

@ -142,6 +142,12 @@ type Connector interface {
// Profile returns a user's information given an ID
Profile(string) (user.User, error)
// URL Format utility
URLFormat(title, url string) string
// Translate emojy to/from services
Emojy(string) string
}
// Plugin interface used for compatibility with the Plugin interface

View File

@ -117,3 +117,4 @@ func (mb *MockBot) GetPluginNames() []string { return nil }
func (mb *MockBot) RefreshPluginBlacklist() error { return nil }
func (mb *MockBot) RefreshPluginWhitelist() error { return nil }
func (mb *MockBot) GetWhitelist() []string { return []string{} }
func (mb *MockBot) URLFormat(title, url string) string { return title + url }

View File

@ -144,6 +144,7 @@ func (c *Config) Unset(key string) error {
// Note, this is always a string. Use the SetArray for an array helper
func (c *Config) Set(key, value string) error {
key = strings.ToLower(key)
value = strings.Trim(value, "`")
q := `insert into config (key,value) values (?, ?)
on conflict(key) do update set value=?;`
tx, err := c.Begin()

View File

@ -219,3 +219,15 @@ func (d *Discord) messageCreate(s *discordgo.Session, m *discordgo.MessageCreate
d.event(d, bot.Message, msg)
}
func (d *Discord) Emojy(name string) string {
e := d.config.GetMap("discord.emojy", map[string]string{})
if emojy, ok := e[name]; ok {
return emojy
}
return name
}
func (d *Discord) URLFormat(title, url string) string {
return fmt.Sprintf("%s (%s)", title, url)
}

View File

@ -314,3 +314,15 @@ func (i Irc) Who(channel string) []string {
func (i Irc) Profile(string) (user.User, error) {
return user.User{}, fmt.Errorf("unimplemented")
}
func (i Irc) URLFormat(title, url string) string {
return fmt.Sprintf("%s (%s)", title, url)
}
func (i Irc) Emojy(name string) string {
e := i.config.GetMap("irc.emojy", map[string]string{})
if emojy, ok := e[name]; ok {
return emojy
}
return name
}

View File

@ -734,3 +734,15 @@ func (s *Slack) Who(id string) []string {
func (s *Slack) Profile(string) (user.User, error) {
return user.User{}, fmt.Errorf("unimplemented")
}
func (s *Slack) Emojy(name string) string {
e := s.config.GetMap("slack.emojy", map[string]string{})
if emojy, ok := e[name]; ok {
return emojy
}
return name
}
func (s *Slack) URLFormat(title, url string) string {
return fmt.Sprintf("<%s|%s>", url, title)
}

View File

@ -682,3 +682,17 @@ func (s *SlackApp) Profile(identifier string) (user.User, error) {
return user.User{}, fmt.Errorf("user %s not found", err)
}
func (s *SlackApp) Emojy(name string) string {
e := s.config.GetMap("slack.emojy", map[string]string{})
if emojy, ok := e[name]; ok {
log.Debug().Msgf("Found emoji %s for %s", emojy, name)
return emojy
}
log.Debug().Msgf("Found no emojy for %s", name)
return name
}
func (s *SlackApp) URLFormat(title, url string) string {
return fmt.Sprintf("<%s|%s>", url, title)
}

View File

@ -88,7 +88,8 @@ func (p *AOC) message(c bot.Connector, kind bot.Kind, message msg.Message, args
}
}
msg := fmt.Sprintf("AoC <https://adventofcode.com/%d/leaderboard/private/view/%d|Leaderboard>:\n", year, boardId)
link := c.URLFormat("leaderboard", fmt.Sprintf("https://adventofcode.com/%d/leaderboard/private/view/%d", year, boardId))
msg := fmt.Sprintf("AoC %s:\n", link)
for _, m := range members {
if m.Stars == 0 {
continue
@ -96,11 +97,11 @@ func (p *AOC) message(c bot.Connector, kind bot.Kind, message msg.Message, args
trophy := ""
switch m.ID {
case goldID:
trophy = ":gold-trophy:"
trophy = c.Emojy(":gold-trophy:")
case silverID:
trophy = ":silver-trophy:"
trophy = c.Emojy(":silver-trophy:")
case bronzeID:
trophy = ":bronze-trophy:"
trophy = c.Emojy(":bronze-trophy:")
}
msg += fmt.Sprintf("%s has %d :star: for a score of %d%s\n", m.Name, m.Stars, m.LocalScore, trophy)
}

View File

@ -117,6 +117,10 @@ func (p *CliPlugin) Send(kind bot.Kind, args ...interface{}) (string, error) {
func (p *CliPlugin) GetEmojiList() map[string]string { return nil }
func (p *CliPlugin) Serve() error { return nil }
func (p *CliPlugin) Who(s string) []string { return nil }
func (s *CliPlugin) Profile(name string) (user.User, error) {
func (p *CliPlugin) Profile(name string) (user.User, error) {
return user.User{}, fmt.Errorf("unimplemented")
}
func (p *CliPlugin) Emojy(name string) string { return name }
func (p *CliPlugin) URLFormat(title, url string) string {
return fmt.Sprintf("%s (%s)", title, url)
}

View File

@ -11,6 +11,7 @@ import (
"path/filepath"
"strconv"
"strings"
"time"
"github.com/rs/zerolog"
"github.com/rs/zerolog/log"
@ -20,16 +21,22 @@ var (
token = flag.String("token", "", "Slack API token")
channel = flag.String("channel", "", "Slack channel ID")
limit = flag.Int("limit", 10000, "Number of items to return")
types = flag.String("types", "images,pdfs", "Type of object")
types = flag.String("types", "images,pdfs,video", "Type of object")
path = flag.String("path", "./", "Path to save files")
to = flag.String("to", "", "Time limit in '2006-01-02T15:04:05Z07:00' format. Default -30d")
rateLimit = flag.Int("rate", 1, "rate limit in seconds")
)
func main() {
flag.Parse()
log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stderr})
ticker := time.NewTicker(time.Second * time.Duration(*rateLimit))
defer ticker.Stop()
for {
files, count := getFiles()
log.Debug().Msgf("Got %d files, count is %d", len(files), count)
for _, f := range files {
downloadFile(f)
deleteFile(f)
@ -37,27 +44,47 @@ func main() {
if count == 1 {
break
}
<-ticker.C
}
}
func getFiles() ([]slackFile, int) {
files := fileResp{}
var toTime time.Time
var err error
if *to == "" {
toTime = time.Now().Add(time.Hour * 24 * 30 * -1)
} else {
toTime, err = time.Parse(time.RFC3339, *to)
if err != nil {
log.Fatal().Err(err).Msg("Error reading time format")
}
}
log.Debug().Msg("Getting files")
body := mkReq("https://slack.com/api/files.list",
"token", *token,
"count", strconv.Itoa(*limit),
"types", *types,
"ts_to", strconv.FormatInt(toTime.Unix(), 10),
)
err := json.Unmarshal(body, &files)
err = json.Unmarshal(body, &files)
checkErr(err)
log.Info().
Int("count", files.Paging.Count).
Bool("ok", files.Ok)
Int("total", files.Paging.Total).
Bool("ok", files.Ok).
Msg("file result")
if !files.Ok {
log.Error().Interface("files", files)
log.Error().
Interface("files", files).
Str("body", string(body)).
Msg("Error getting files")
os.Exit(1)
}
return files.Files, files.Paging.Pages