Beispiel #1
0
        public async Task UserEmojiStatsAsync(
            [Summary("The user to retrieve stats for.")]
            IUser user)
        {
            var userId  = user.Id;
            var guildId = Context.Guild.Id;

            var emojiStats = await _emojiRepository.GetEmojiStatsAsync(guildId, SortDirection.Ascending, 10, userId : userId);

            var userTotalUses = await _emojiRepository.GetGuildStatsAsync(guildId, userId);

            var numberOfDays = Math.Max((DateTime.Now - userTotalUses.OldestTimestamp).Days, 1);

            var sb = new StringBuilder();

            BuildEmojiStatString(sb, userTotalUses.TotalUses, emojiStats, (emoji) => (double)emoji.Uses / numberOfDays);

            var totalEmojiUsesPerDay = (double)userTotalUses.TotalUses / numberOfDays;

            await ReplyAsync(embed : new EmbedBuilder()
                             .WithAuthor($"{user.GetFullUsername()} - Emoji statistics", user.GetDefiniteAvatarUrl())
                             .WithColor(Color.Blue)
                             .WithDescription(sb.ToString())
                             .WithFooter($"{"unique emoji".ToQuantity(userTotalUses.UniqueEmojis)} used {"time".ToQuantity(userTotalUses.TotalUses)} ({totalEmojiUsesPerDay.ToString("0.0")}/day) since {userTotalUses.OldestTimestamp.ToString("yyyy-MM-dd")}")
                             .Build());
        }
Beispiel #2
0
        public async Task AppendGuildParticipationAsync(StringBuilder stringBuilder, SocketGuild guild)
        {
            var weekTotal = await _messageRepository.GetTotalMessageCountAsync(guild.Id, TimeSpan.FromDays(7));

            var monthTotal = await _messageRepository.GetTotalMessageCountAsync(guild.Id, TimeSpan.FromDays(30));

            var channelCounts = await _messageRepository.GetTotalMessageCountByChannelAsync(guild.Id, TimeSpan.FromDays(30));

            var orderedChannelCounts = channelCounts.OrderByDescending(x => x.Value);
            var mostActiveChannel    = orderedChannelCounts.First();

            stringBuilder
            .AppendLine(Format.Bold("\u276F Guild Participation"))
            .AppendLine($"Last 7 days: {"message".ToQuantity(weekTotal, "n0")}")
            .AppendLine($"Last 30 days: {"message".ToQuantity(monthTotal, "n0")}")
            .AppendLine($"Avg. per day: {"message".ToQuantity(monthTotal / 30, "n0")}")
            .AppendLine($"Most active channel: {MentionUtils.MentionChannel(mostActiveChannel.Key)} ({"message".ToQuantity(mostActiveChannel.Value, "n0")} in 30 days)");

            var emojiCounts = await _emojiRepository.GetEmojiStatsAsync(guild.Id, SortDirection.Ascending, 1);

            if (emojiCounts.Any())
            {
                var favoriteEmoji = emojiCounts.First();

                var emojiFormatted = ((SocketSelfUser)Context.Client.CurrentUser).CanAccessEmoji(favoriteEmoji.Emoji)
                    ? Format.Url(favoriteEmoji.Emoji.ToString(), favoriteEmoji.Emoji.Url)
                    : $"{Format.Url("❔", favoriteEmoji.Emoji.Url)} (`{favoriteEmoji.Emoji.Name}`)";

                stringBuilder.AppendLine($"Favorite reaction: {emojiFormatted} ({"time".ToQuantity(favoriteEmoji.Uses)})");
            }

            stringBuilder.AppendLine();
        }
Beispiel #3
0
        public async Task GetUserInfoAsync(
            [Summary("The user to retrieve information about, if any.")]
            [Remainder] DiscordUserOrMessageAuthorEntity user = null)
        {
            var userId = user?.UserId ?? Context.User.Id;

            var timer = Stopwatch.StartNew();

            var userInfo = await _userService.GetUserInformationAsync(Context.Guild.Id, userId);

            if (userInfo == null)
            {
                var embed = new EmbedBuilder()
                            .WithTitle("Retrieval Error")
                            .WithColor(Color.Red)
                            .WithDescription("Sorry, we don't have any data for that user - and we couldn't find any, either.")
                            .AddField("User Id", userId);
                await _autoRemoveMessageService.RegisterRemovableMessageAsync(
                    Context.User,
                    embed,
                    async (embedBuilder) => await ReplyAsync(embed: embedBuilder.Build()));

                return;
            }

            var builder = new StringBuilder();

            builder.AppendLine("**\u276F User Information**");
            builder.AppendLine("ID: " + userId);
            builder.AppendLine("Profile: " + MentionUtils.MentionUser(userId));

            var embedBuilder = new EmbedBuilder()
                               .WithUserAsAuthor(userInfo)
                               .WithTimestamp(_utcNow);

            var avatar = userInfo.GetDefiniteAvatarUrl();

            embedBuilder.ThumbnailUrl   = avatar;
            embedBuilder.Author.IconUrl = avatar;

            ValueTask <Color> colorTask = default;

            if ((userInfo.GetAvatarUrl(size: 16) ?? userInfo.GetDefaultAvatarUrl()) is { } avatarUrl)
            {
                colorTask = _imageService.GetDominantColorAsync(new Uri(avatarUrl));
            }

            var moderationRead = await _authorizationService.HasClaimsAsync(Context.User as IGuildUser, AuthorizationClaim.ModerationRead);

            var promotions = await _promotionsService.GetPromotionsForUserAsync(Context.Guild.Id, userId);

            if (userInfo.IsBanned)
            {
                builder.AppendLine("Status: **Banned** \\🔨");

                if (moderationRead)
                {
                    builder.AppendLine($"Ban Reason: {userInfo.BanReason}");
                }
            }

            if (userInfo.FirstSeen is DateTimeOffset firstSeen)
            {
                builder.AppendLine($"First Seen: {FormatUtilities.FormatTimeAgo(_utcNow, firstSeen)}");
            }

            if (userInfo.LastSeen is DateTimeOffset lastSeen)
            {
                builder.AppendLine($"Last Seen: {FormatUtilities.FormatTimeAgo(_utcNow, lastSeen)}");
            }

            try
            {
                var userRank = await _messageRepository.GetGuildUserParticipationStatistics(Context.Guild.Id, userId);

                var messagesByDate = await _messageRepository.GetGuildUserMessageCountByDate(Context.Guild.Id, userId, TimeSpan.FromDays(30));

                var messageCountsByChannel = await _messageRepository.GetGuildUserMessageCountByChannel(Context.Guild.Id, userId, TimeSpan.FromDays(30));

                var emojiCounts = await _emojiRepository.GetEmojiStatsAsync(Context.Guild.Id, SortDirection.Ascending, 1, userId : userId);

                await AddParticipationToEmbedAsync(userId, builder, userRank, messagesByDate, messageCountsByChannel, emojiCounts);
            }
            catch (Exception ex)
            {
                _log.LogError(ex, "An error occured while retrieving a user's message count.");
            }

            AddMemberInformationToEmbed(userInfo, builder);
            AddPromotionsToEmbed(builder, promotions);

            if (moderationRead)
            {
                await AddInfractionsToEmbedAsync(userId, builder);
            }

            embedBuilder.Description = builder.ToString();

            embedBuilder.WithColor(await colorTask);

            timer.Stop();
            embedBuilder.WithFooter(footer => footer.Text = $"Completed after {timer.ElapsedMilliseconds} ms");

            await _autoRemoveMessageService.RegisterRemovableMessageAsync(
                userInfo.Id == Context.User.Id?new[] { userInfo } : new[] { userInfo, Context.User },
                embedBuilder,
                async (embedBuilder) => await ReplyAsync(embed: embedBuilder.Build()));
        }
Beispiel #4
0
        private async Task AddParticipationToEmbedAsync(ulong userId, StringBuilder builder)
        {
            var userRank = await _messageRepository.GetGuildUserParticipationStatistics(Context.Guild.Id, userId);

            var messagesByDate = await _messageRepository.GetGuildUserMessageCountByDate(Context.Guild.Id, userId, TimeSpan.FromDays(30));

            var lastWeek = _utcNow - TimeSpan.FromDays(7);

            var weekTotal  = 0;
            var monthTotal = 0;

            foreach (var kvp in messagesByDate)
            {
                if (kvp.Key >= lastWeek)
                {
                    weekTotal += kvp.Value;
                }

                monthTotal += kvp.Value;
            }

            builder.AppendLine();
            builder.AppendLine("**\u276F Guild Participation**");

            if (userRank?.Rank > 0)
            {
                builder.AppendFormat("Rank: {0} {1}\n", userRank.Rank.Ordinalize(), GetParticipationEmoji(userRank));
            }

            var weekParticipation = "Last 7 days: " + weekTotal + " messages";

            if (weekTotal > 0 && monthTotal > 0)
            {
                var percentage = (int)((decimal)weekTotal / monthTotal * 100);
                weekParticipation += string.Format(" ({0}%)", percentage);
            }

            builder.AppendLine(weekParticipation);
            builder.AppendLine("Last 30 days: " + monthTotal + " messages");

            if (monthTotal > 0)
            {
                builder.AppendFormat(
                    "Avg. per day: {0} messages (top {1} percentile)\n",
                    decimal.Round(userRank.AveragePerDay, 3),
                    userRank.Percentile.Ordinalize());

                try
                {
                    var channels = await _messageRepository.GetGuildUserMessageCountByChannel(Context.Guild.Id, userId, TimeSpan.FromDays(30));

                    foreach (var kvp in channels.OrderByDescending(x => x.Value))
                    {
                        var channel = await Context.Guild.GetChannelAsync(kvp.Key);

                        if (channel.IsPublic())
                        {
                            builder.AppendLine($"Most active channel: {MentionUtils.MentionChannel(channel.Id)} ({kvp.Value} messages)");
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    _log.LogDebug(ex, "Unable to get the most active channel for {UserId}.", userId);
                }
            }

            var emojiCounts = await _emojiRepository.GetEmojiStatsAsync(Context.Guild.Id, SortDirection.Ascending, 1, userId : userId);

            if (emojiCounts.Any())
            {
                var favoriteEmoji = emojiCounts.First();

                var emojiFormatted = ((SocketSelfUser)Context.Client.CurrentUser).CanAccessEmoji(favoriteEmoji.Emoji)
                    ? Format.Url(favoriteEmoji.Emoji.ToString(), favoriteEmoji.Emoji.Url)
                    : $"{Format.Url("❔", favoriteEmoji.Emoji.Url)} (`{favoriteEmoji.Emoji.Name}`)";

                builder.AppendLine($"Favorite emoji: {emojiFormatted} ({"time".ToQuantity(favoriteEmoji.Uses)})");
            }
        }