Beispiel #1
0
        /// <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);
        }
Beispiel #2
0
 internal static EmojiUsageStatistics FromDto(EmojiStatsDto emojiStatsDto)
 => new EmojiUsageStatistics()
 {
     Emoji = EphemeralEmoji.FromRawData(emojiStatsDto.EmojiName, emojiStatsDto.EmojiId, emojiStatsDto.IsAnimated),
     Rank  = emojiStatsDto.Rank,
     Uses  = emojiStatsDto.Uses,
 };
Beispiel #3
0
 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,
 };
Beispiel #4
0
        /// <summary>
        /// Determines whether the current user can access the supplied emoji
        /// </summary>
        /// <param name="user">The user for whom to determine emoji access.</param>
        /// <param name="emoji">The emoji that the user is attempting to access</param>
        /// <returns>A flag indicating whether the user can access the supplied emoji.</returns>
        public static bool CanAccessEmoji(this SocketSelfUser user, EphemeralEmoji emoji)
        {
            if (user is null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            if (emoji is null)
            {
                throw new ArgumentNullException(nameof(emoji));
            }

            if (emoji.Id is null)
            {
                return(!(emoji.Name is null));
            }

            var accessibleEmotes = user.MutualGuilds.SelectMany(x => x.Emotes);

            return(accessibleEmotes.Any(x => x.Id == emoji.Id));
        }
Beispiel #5
0
        /// <inheritdoc />
        public async Task <SingleEmojiUsageStatistics> GetEmojiStatsAsync(ulong guildId, EphemeralEmoji emoji, TimeSpan?dateFilter = null)
        {
            var query      = GetQuery();
            var parameters = GetParameters();

            var stats = await ModixContext
                        .Set <SingleEmojiStatsDto>()
                        .FromSqlRaw(query, parameters)
                        .AsNoTracking()
                        .FirstOrDefaultAsync();

            return(SingleEmojiUsageStatistics.FromDto(stats ?? new SingleEmojiStatsDto()));

            NpgsqlParameter[] GetParameters() =>
            new[]
Beispiel #6
0
        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());
        }