package aoc import ( "fmt" "regexp" "sort" "strconv" "strings" "time" "code.chrissexton.org/cws/getaoc" "github.com/velour/catbase/bot" "github.com/velour/catbase/config" ) type AOC struct { b bot.Bot c *config.Config } func New(b bot.Bot) *AOC { aoc := &AOC{ b: b, c: b.Config(), } b.RegisterRegexCmd(aoc, bot.Message, aocRegex, aoc.aocCmd) return aoc } var aocRegex = regexp.MustCompile(`(?i)^aoc\s?(?P\S+)?$`) func (p *AOC) aocCmd(r bot.Request) bool { year := time.Now().Year() if time.Now().Month() < 11 { year-- } if r.Values["year"] != "" { year, _ = strconv.Atoi(r.Values["year"]) } boardId := p.c.GetInt("aoc.board", 0) var err error session := p.c.Get("aoc.session", "") if session == "" { p.b.Send(r.Conn, bot.Message, r.Msg.Channel, "Error getting leaderboard: must have a session ID.") return true } if boardId == 0 { p.b.Send(r.Conn, bot.Message, r.Msg.Channel, "Error getting leaderboard: must have a board ID.") return true } board, err := getaoc.GetLeaderboard(session, year, boardId) if err != nil { p.b.Send(r.Conn, bot.Message, r.Msg.Channel, fmt.Sprintf("Error getting leaderboard: %s", err)) return true } members := []getaoc.Member{} for _, m := range board.Members { members = append(members, m) } sort.Slice(members, func(i, j int) bool { return members[i].LocalScore > members[j].LocalScore }) gold, silver, bronze := -1, -1, -1 goldID, silverID, bronzeID := "", "", "" for _, m := range members { if m.LocalScore > gold { gold = m.LocalScore goldID = m.ID } if m.LocalScore < gold && m.LocalScore > silver { silver = m.LocalScore silverID = m.ID } if m.LocalScore < silver && m.LocalScore > bronze { bronze = m.LocalScore bronzeID = m.ID } } link := r.Conn.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 } trophy := "" switch m.ID { case goldID: trophy = r.Conn.Emojy(":gold-trophy:") case silverID: trophy = r.Conn.Emojy(":silver-trophy:") case bronzeID: trophy = r.Conn.Emojy(":bronze-trophy:") } msg += fmt.Sprintf("%s has %d :star: for a score of %d%s\n", m.Name, m.Stars, m.LocalScore, trophy) } msg = strings.TrimSpace(msg) p.b.Send(r.Conn, bot.Message, r.Msg.Channel, msg) return true }