/// <inheritdoc /> public async Task <IReadOnlyDictionary <EphemeralEmoji, int> > GetCountsAsync(EmojiSearchCriteria criteria) { if (criteria is null) { throw new ArgumentNullException(nameof(criteria)); } var emoji = await ModixContext.Emoji.AsNoTracking() .FilterBy(criteria) .GroupBy(x => new { x.EmojiId, EmojiName = x.EmojiId == null ? x.EmojiName : null }, x => new { x.EmojiId, x.EmojiName, x.IsAnimated, x.Timestamp }) .ToArrayAsync(); var counts = emoji.ToDictionary( x => { var mostRecentEmoji = x.OrderByDescending(y => y.Timestamp).First(); return(EphemeralEmoji.FromRawData(mostRecentEmoji.EmojiName, mostRecentEmoji.EmojiId, mostRecentEmoji.IsAnimated)); }, x => x.Count()); return(counts); }
internal static EmojiUsageStatistics FromDto(EmojiStatsDto emojiStatsDto) => new EmojiUsageStatistics() { Emoji = EphemeralEmoji.FromRawData(emojiStatsDto.EmojiName, emojiStatsDto.EmojiId, emojiStatsDto.IsAnimated), Rank = emojiStatsDto.Rank, Uses = emojiStatsDto.Uses, };
internal static SingleEmojiUsageStatistics FromDto(SingleEmojiStatsDto emojiStatsDto) => new SingleEmojiUsageStatistics() { Emoji = EphemeralEmoji.FromRawData(emojiStatsDto.EmojiName, emojiStatsDto.EmojiId, emojiStatsDto.IsAnimated), Rank = emojiStatsDto.Rank, Uses = emojiStatsDto.Uses, TopUserId = emojiStatsDto.TopUserId, TopUserUses = emojiStatsDto.TopUserUses, };
public async Task EmojiStatsAsync( [Summary("The emoji to retrieve information about.")] IEmote emoji) { // TODO: Abstract this as IEmoteEntity instead (actually not entirely sure how this would work, as it comes out of the commands module) var asEmote = emoji as Emote; var ephemeralEmoji = EphemeralEmoji.FromRawData(emoji.Name, asEmote?.Id, asEmote?.Animated ?? false); var guildId = Context.Guild.Id; var emojiStats = await _emojiRepository.GetEmojiStatsAsync(guildId, ephemeralEmoji); if (emojiStats.Uses == 0) { await ReplyAsync(embed : new EmbedBuilder() .WithTitle("Unknown Emoji") .WithDescription($"The emoji \"{ephemeralEmoji.Name}\" has never been used in this server.") .WithColor(Color.Red) .Build()); return; } var guildStats = await _emojiRepository.GetGuildStatsAsync(guildId); var emojiFormatted = ((SocketSelfUser)Context.Client.CurrentUser).CanAccessEmoji(ephemeralEmoji) ? ephemeralEmoji.ToString() : "❔"; var percentUsage = 100 * (double)emojiStats.Uses / guildStats.TotalUses; if (double.IsNaN(percentUsage)) { percentUsage = 0; } var emojiCreated = ephemeralEmoji.CreatedAt ?? guildStats.OldestTimestamp; var numberOfDays = Math.Max((DateTimeOffset.Now - emojiCreated).Days, 1); var perDay = (double)emojiStats.Uses / numberOfDays; var sb = new StringBuilder(emojiFormatted); if (ephemeralEmoji.Id != null) { sb.Append($" (`:{ephemeralEmoji.Name}:`)"); } sb.AppendLine() .AppendLine($"• {"use".ToQuantity(emojiStats.Uses)}") .AppendLine($"• {percentUsage.ToString("0.0")}% of all emoji uses") .AppendLine($"• {perDay.ToString("0.0/day")}"); if (emojiStats.TopUserId != default) { sb.AppendLine($"• Top user: {MentionUtils.MentionUser(emojiStats.TopUserId)} ({"use".ToQuantity(emojiStats.TopUserUses)})"); } var embed = new EmbedBuilder() .WithAuthor(Context.Guild.Name, Context.Guild.IconUrl) .WithColor(Color.Blue) .WithDescription(sb.ToString()); await ReplyAsync(embed : embed.Build()); }