diff --git a/bot/interfaces.go b/bot/interfaces.go index 4880d5c..6cc1e96 100644 --- a/bot/interfaces.go +++ b/bot/interfaces.go @@ -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 diff --git a/bot/mock.go b/bot/mock.go index 162b5fd..dbb7c5e 100644 --- a/bot/mock.go +++ b/bot/mock.go @@ -113,7 +113,8 @@ func NewMockBot() *MockBot { return &b } -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) 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 } diff --git a/config/config.go b/config/config.go index beec0a0..abfbdaa 100644 --- a/config/config.go +++ b/config/config.go @@ -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() diff --git a/connectors/discord/discord.go b/connectors/discord/discord.go index 4886c4a..7a8e232 100644 --- a/connectors/discord/discord.go +++ b/connectors/discord/discord.go @@ -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) +} diff --git a/connectors/irc/irc.go b/connectors/irc/irc.go index 397125b..489f264 100644 --- a/connectors/irc/irc.go +++ b/connectors/irc/irc.go @@ -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 +} diff --git a/connectors/slack/slack.go b/connectors/slack/slack.go index 816b1c0..8cb018b 100644 --- a/connectors/slack/slack.go +++ b/connectors/slack/slack.go @@ -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) +} diff --git a/connectors/slackapp/slackApp.go b/connectors/slackapp/slackApp.go index c150e02..6611fc9 100644 --- a/connectors/slackapp/slackApp.go +++ b/connectors/slackapp/slackApp.go @@ -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) +} diff --git a/plugins/aoc/aoc.go b/plugins/aoc/aoc.go index e71ce38..0d31ce5 100644 --- a/plugins/aoc/aoc.go +++ b/plugins/aoc/aoc.go @@ -88,7 +88,8 @@ func (p *AOC) message(c bot.Connector, kind bot.Kind, message msg.Message, args } } - msg := fmt.Sprintf("AoC :\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) } diff --git a/plugins/cli/cli.go b/plugins/cli/cli.go index b3a42ce..8b98f51 100644 --- a/plugins/cli/cli.go +++ b/plugins/cli/cli.go @@ -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) +} diff --git a/util/files/main.go b/util/files/main.go index b7a87c3..e12ed97 100644 --- a/util/files/main.go +++ b/util/files/main.go @@ -11,25 +11,32 @@ import ( "path/filepath" "strconv" "strings" + "time" "github.com/rs/zerolog" "github.com/rs/zerolog/log" ) 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") - path = flag.String("path", "./", "Path to save files") + 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,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