diff --git a/src/Bot/Commands/User/Ranking/Rank.cs b/src/Bot/Commands/User/Ranking/Rank.cs index afa0439..e9aac67 100644 --- a/src/Bot/Commands/User/Ranking/Rank.cs +++ b/src/Bot/Commands/User/Ranking/Rank.cs @@ -1,7 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; using System.Threading.Tasks; using Discord.Commands; using Geekbot.Core; @@ -9,10 +6,8 @@ using Geekbot.Core.CommandPreconditions; using Geekbot.Core.Converters; using Geekbot.Core.Database; using Geekbot.Core.ErrorHandling; -using Geekbot.Core.Extensions; using Geekbot.Core.GuildSettingsManager; using Geekbot.Core.Highscores; -using Localization = Geekbot.Core.Localization; namespace Geekbot.Bot.Commands.User.Ranking { @@ -40,85 +35,9 @@ namespace Geekbot.Bot.Commands.User.Ranking { try { - HighscoreTypes type; - try - { - type = Enum.Parse(typeUnformated, true); - if (!Enum.IsDefined(typeof(HighscoreTypes), type)) throw new Exception(); - } - catch - { - await ReplyAsync(Localization.Rank.InvalidType); - return; - } - - var replyBuilder = new StringBuilder(); - if (amount > 20) - { - await ReplyAsync(Localization.Rank.LimitingTo20Warning); - amount = 20; - } - - var guildId = Context.Guild.Id; - Dictionary highscoreUsers; - try - { - highscoreUsers = _highscoreManager.GetHighscoresWithUserData(type, guildId, amount, season); - } - catch (HighscoreListEmptyException) - { - await ReplyAsync(string.Format(Localization.Rank.NoTypeFoundForServer, type)); - return; - } - - var guildMessages = 0; - if (type == HighscoreTypes.messages) - { - guildMessages = _database.Messages - .Where(e => e.GuildId.Equals(Context.Guild.Id.AsLong())) - .Select(e => e.MessageCount) - .Sum(); - } - - var failedToRetrieveUser = highscoreUsers.Any(e => string.IsNullOrEmpty(e.Key.Username)); - - if (failedToRetrieveUser) replyBuilder.AppendLine(Localization.Rank.FailedToResolveAllUsernames).AppendLine(); - - if (type == HighscoreTypes.seasons) - { - if (string.IsNullOrEmpty(season)) - { - season = SeasonsUtils.GetCurrentSeason(); - } - replyBuilder.AppendLine(string.Format(Localization.Rank.HighscoresFor, $"{type.ToString().CapitalizeFirst()} ({season})", Context.Guild.Name)); - } - else - { - replyBuilder.AppendLine(string.Format(Localization.Rank.HighscoresFor, type.ToString().CapitalizeFirst(), Context.Guild.Name)); - } - - var highscorePlace = 1; - foreach (var (user, value) in highscoreUsers) - { - replyBuilder.Append(highscorePlace < 11 - ? $"{_emojiConverter.NumberToEmoji(highscorePlace)} " - : $"`{highscorePlace}.` "); - - replyBuilder.Append(user.Username != null - ? $"**{user.Username}#{user.Discriminator}**" - : $"**{user.Id}**"); - - replyBuilder.Append(type switch - { - HighscoreTypes.messages => $" - {value} {HighscoreTypes.messages} - {Math.Round((double) (100 * value) / guildMessages, 2)}%\n", - HighscoreTypes.seasons => $" - {value} {HighscoreTypes.messages}\n", - _ => $" - {value} {type}\n" - }); - - highscorePlace++; - } - - await ReplyAsync(replyBuilder.ToString()); + var res = new Geekbot.Commands.Rank(_database, _emojiConverter, _highscoreManager) + .Run(typeUnformated, amount, season, Context.Guild.Id, Context.Guild.Name); + await ReplyAsync(res); } catch (Exception e) { diff --git a/src/Commands/Rank.cs b/src/Commands/Rank.cs new file mode 100644 index 0000000..2612e97 --- /dev/null +++ b/src/Commands/Rank.cs @@ -0,0 +1,107 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Geekbot.Core.Converters; +using Geekbot.Core.Database; +using Geekbot.Core.Extensions; +using Geekbot.Core.Highscores; +using Localization = Geekbot.Core.Localization; + +namespace Geekbot.Commands +{ + public class Rank + { + private readonly DatabaseContext _database; + private readonly IEmojiConverter _emojiConverter; + private readonly IHighscoreManager _highscoreManager; + + public Rank(DatabaseContext database, IEmojiConverter emojiConverter, IHighscoreManager highscoreManager) + { + _database = database; + _emojiConverter = emojiConverter; + _highscoreManager = highscoreManager; + } + + public string Run(string typeUnformated, int amount, string season, ulong guildId, string guildName) + { + HighscoreTypes type; + try + { + type = Enum.Parse(typeUnformated, true); + if (!Enum.IsDefined(typeof(HighscoreTypes), type)) throw new Exception(); + } + catch + { + return Localization.Rank.InvalidType; + } + + var replyBuilder = new StringBuilder(); + if (amount > 20) + { + replyBuilder.AppendLine(Localization.Rank.LimitingTo20Warning); + amount = 20; + } + + Dictionary highscoreUsers; + try + { + highscoreUsers = _highscoreManager.GetHighscoresWithUserData(type, guildId, amount, season); + } + catch (HighscoreListEmptyException) + { + return string.Format(Core.Localization.Rank.NoTypeFoundForServer, type); + } + + var guildMessages = 0; + if (type == HighscoreTypes.messages) + { + guildMessages = _database.Messages + .Where(e => e.GuildId.Equals(guildId.AsLong())) + .Select(e => e.MessageCount) + .Sum(); + } + + var failedToRetrieveUser = highscoreUsers.Any(e => string.IsNullOrEmpty(e.Key.Username)); + + if (failedToRetrieveUser) replyBuilder.AppendLine(Core.Localization.Rank.FailedToResolveAllUsernames).AppendLine(); + + if (type == HighscoreTypes.seasons) + { + if (string.IsNullOrEmpty(season)) + { + season = SeasonsUtils.GetCurrentSeason(); + } + + replyBuilder.AppendLine(string.Format(Core.Localization.Rank.HighscoresFor, $"{type.ToString().CapitalizeFirst()} ({season})", guildName)); + } + else + { + replyBuilder.AppendLine(string.Format(Core.Localization.Rank.HighscoresFor, type.ToString().CapitalizeFirst(), guildName)); + } + + var highscorePlace = 1; + foreach (var (user, value) in highscoreUsers) + { + replyBuilder.Append(highscorePlace < 11 + ? $"{_emojiConverter.NumberToEmoji(highscorePlace)} " + : $"`{highscorePlace}.` "); + + replyBuilder.Append(user.Username != null + ? $"**{user.Username}#{user.Discriminator}**" + : $"**{user.Id}**"); + + replyBuilder.Append(type switch + { + HighscoreTypes.messages => $" - {value} {HighscoreTypes.messages} - {Math.Round((double)(100 * value) / guildMessages, 2)}%\n", + HighscoreTypes.seasons => $" - {value} {HighscoreTypes.messages}\n", + _ => $" - {value} {type}\n" + }); + + highscorePlace++; + } + + return replyBuilder.ToString(); + } + } +} \ No newline at end of file diff --git a/src/Core/Interactions/ApplicationCommand/OptionChoice.cs b/src/Core/Interactions/ApplicationCommand/OptionChoice.cs index 345d1ff..d10e6ec 100644 --- a/src/Core/Interactions/ApplicationCommand/OptionChoice.cs +++ b/src/Core/Interactions/ApplicationCommand/OptionChoice.cs @@ -13,5 +13,11 @@ namespace Geekbot.Core.Interactions.ApplicationCommand /// [JsonPropertyName("name")] public string Name { get; set; } + + /// + /// value of the choice, up to 100 characters if string + /// + [JsonPropertyName("value")] + public string Value { get; set; } } } \ No newline at end of file diff --git a/src/Web/Commands/Rank.cs b/src/Web/Commands/Rank.cs new file mode 100644 index 0000000..419e7d5 --- /dev/null +++ b/src/Web/Commands/Rank.cs @@ -0,0 +1,102 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Geekbot.Core.Converters; +using Geekbot.Core.Database; +using Geekbot.Core.Highscores; +using Geekbot.Core.Interactions; +using Geekbot.Core.Interactions.ApplicationCommand; +using Geekbot.Core.Interactions.Request; +using Geekbot.Core.Interactions.Response; + +namespace Geekbot.Web.Commands +{ + public class Rank : InteractionBase + { + private readonly DatabaseContext _database; + private readonly IEmojiConverter _emojiConverter; + private readonly IHighscoreManager _highscoreManager; + + public Rank(DatabaseContext database, IEmojiConverter emojiConverter, IHighscoreManager highscoreManager) + { + _database = database; + _emojiConverter = emojiConverter; + _highscoreManager = highscoreManager; + } + + private enum Options + { + Counter, + Amount, + Season + } + + public override Command GetCommandInfo() + { + return new Command() + { + Name = "rank", + Description = "BETA: Highscores for various counters", + Type = CommandType.ChatInput, + Options = new List