From 464fa00efa07b81098caaa67324053ad943f8144 Mon Sep 17 00:00:00 2001 From: Daniel Mason Date: Thu, 16 Jan 2025 00:32:32 +1300 Subject: [PATCH] Add more context --- src/internal/bot/commands.go | 95 ++++++++++++++++++++++++---------- src/internal/db/emoji_usage.go | 68 ++++++++++++++++++++---- 2 files changed, 125 insertions(+), 38 deletions(-) diff --git a/src/internal/bot/commands.go b/src/internal/bot/commands.go index e03d482..cd4151e 100644 --- a/src/internal/bot/commands.go +++ b/src/internal/bot/commands.go @@ -1,6 +1,7 @@ package bot import ( + "fmt" "log/slog" "strings" @@ -20,34 +21,8 @@ var ( } commandHandlers = map[string]func(s *discordgo.Session, i *discordgo.InteractionCreate){ - "show-top-emojis": func(s *discordgo.Session, i *discordgo.InteractionCreate) { - top, err := b.Db.GetTopEmojisForGuild(i.GuildID, 5) - if err != nil { - slog.Error("Error getting top emojis", "err", err) - return - } - - s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ - Type: discordgo.InteractionResponseChannelMessageWithSource, - Data: &discordgo.InteractionResponseData{ - Content: "Top Emojis:\n" + strings.Join(top, "\n"), - }, - }) - }, - "show-top-users": func(s *discordgo.Session, i *discordgo.InteractionCreate) { - top, err := b.Db.GetTopUsersForGuild(i.GuildID, 5) - if err != nil { - slog.Error("Error getting top users", "err", err) - return - } - - s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ - Type: discordgo.InteractionResponseChannelMessageWithSource, - Data: &discordgo.InteractionResponseData{ - Content: "Top Users:\n" + strings.Join(top, "\n"), - }, - }) - }, + "show-top-emojis": showTopEmojis, + "show-top-users": showTopUsers, } ) @@ -73,3 +48,67 @@ func (bot *Bot) DeregisterCommands() { } } } + +// showTopEmojis - Show top emojis with users +func showTopEmojis(s *discordgo.Session, i *discordgo.InteractionCreate) { + top, err := b.Db.GetTopEmojisForGuild(i.GuildID, 5) + if err != nil { + slog.Error("Error getting top emojis", "err", err) + return + } + + msg := "Most used emojis:\n" + for k, v := range top { + topUsers, err := b.Db.GetTopUsersForGuildEmoji(i.GuildID, k, 3) + if err != nil { + slog.Error("Error getting top users for guild emoji", "err", err) + continue + } + + users := []string{} + msg += fmt.Sprintf("%s: %d", k, v) + for sk, sv := range topUsers { + users = append(users, fmt.Sprintf("<@%s>: %d", sk, sv)) + } + msg += " (" + strings.Join(users, ", ") + ")\n" + } + + s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseChannelMessageWithSource, + Data: &discordgo.InteractionResponseData{ + Content: msg, + }, + }) +} + +// showTopUsers - Show top users with emojis +func showTopUsers(s *discordgo.Session, i *discordgo.InteractionCreate) { + top, err := b.Db.GetTopUsersForGuild(i.GuildID, 5) + if err != nil { + slog.Error("Error getting top users", "err", err) + return + } + + msg := "Users who use the most emojis:\n" + for k, v := range top { + topUsers, err := b.Db.GetTopEmojisForGuildUser(i.GuildID, k, 3) + if err != nil { + slog.Error("Error getting top emojis for guild user", "err", err) + continue + } + + users := []string{} + msg += fmt.Sprintf("<@%s>: %d", k, v) + for sk, sv := range topUsers { + users = append(users, fmt.Sprintf("%s: %d", sk, sv)) + } + msg += " (" + strings.Join(users, ", ") + ")\n" + } + + s.InteractionRespond(i.Interaction, &discordgo.InteractionResponse{ + Type: discordgo.InteractionResponseChannelMessageWithSource, + Data: &discordgo.InteractionResponseData{ + Content: msg, + }, + }) +} diff --git a/src/internal/db/emoji_usage.go b/src/internal/db/emoji_usage.go index e17319e..29d9e3c 100644 --- a/src/internal/db/emoji_usage.go +++ b/src/internal/db/emoji_usage.go @@ -1,7 +1,5 @@ package db -import "fmt" - // LogEmojiUsage - Log usage func (db *Database) LogEmojiUsage(guildID, channelID, userID, emojiID string) error { _, err := db.db.Exec( @@ -13,8 +11,8 @@ func (db *Database) LogEmojiUsage(guildID, channelID, userID, emojiID string) er } // GetTopUsersForGuild - Report usage -func (db *Database) GetTopUsersForGuild(guildID string, num int) ([]string, error) { - var data []string +func (db *Database) GetTopUsersForGuild(guildID string, num int) (map[string]int64, error) { + data := make(map[string]int64) row, err := db.db.Query( "SELECT user_id, count(*) FROM `emoji_usage` WHERE `guild_id` = ? GROUP BY user_id ORDER BY count(*) DESC LIMIT ?", guildID, @@ -30,18 +28,19 @@ func (db *Database) GetTopUsersForGuild(guildID string, num int) ([]string, erro var user string var count int64 row.Scan(&user, &count) - data = append(data, fmt.Sprintf("<@%s>: %d", user, count)) + data[user] = count } return data, nil } -// GetTopEmojisForGuild - Report usage -func (db *Database) GetTopEmojisForGuild(guildID string, num int) ([]string, error) { - var data []string +// GetTopUsersForGuildEmoji - Report usage +func (db *Database) GetTopUsersForGuildEmoji(guildID string, emojiID string, num int) (map[string]int64, error) { + data := make(map[string]int64) row, err := db.db.Query( - "SELECT emoji_id, count(*) FROM `emoji_usage` WHERE `guild_id` = ? GROUP BY emoji_id ORDER BY count(*) DESC LIMIT ?", + "SELECT user_id, count(*) FROM `emoji_usage` WHERE `guild_id` = ? AND `emoji_id` = ? GROUP BY emoji_id, user_id ORDER BY count(*) DESC LIMIT ?", guildID, + emojiID, num, ) @@ -54,7 +53,56 @@ func (db *Database) GetTopEmojisForGuild(guildID string, num int) ([]string, err var user string var count int64 row.Scan(&user, &count) - data = append(data, fmt.Sprintf("%s: %d", user, count)) + data[user] = count + } + + return data, nil +} + +// GetTopEmojisForGuild - Report usage +func (db *Database) GetTopEmojisForGuild(guildID string, num int) (map[string]int64, error) { + data := make(map[string]int64) + row, err := db.db.Query( + "SELECT emoji_id, count(*) FROM `emoji_usage` WHERE `guild_id` = ? GROUP BY emoji_id ORDER BY count(*) DESC LIMIT ?", + guildID, + num, + ) + + if err != nil { + return data, err + } + + defer row.Close() + for row.Next() { + var emoji string + var count int64 + row.Scan(&emoji, &count) + data[emoji] = count + } + + return data, nil +} + +// GetTopEmojisForGuildUser - Report usage +func (db *Database) GetTopEmojisForGuildUser(guildID string, userID string, num int) (map[string]int64, error) { + data := make(map[string]int64) + row, err := db.db.Query( + "SELECT emoji_id, count(*) FROM `emoji_usage` WHERE `guild_id` = ? AND `user_id` = ? GROUP BY emoji_id ORDER BY count(*) DESC LIMIT ?", + guildID, + userID, + num, + ) + + if err != nil { + return data, err + } + + defer row.Close() + for row.Next() { + var emoji string + var count int64 + row.Scan(&emoji, &count) + data[emoji] = count } return data, nil