/// <summary> /// Participation points overview /// </summary> /// <param name="commandContext">Command context</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task PostParticipationOverview(CommandContextContainer commandContext) { using (var dbFactory = RepositoryFactory.CreateInstance()) { var users = dbFactory.GetRepository <RaidCurrentUserPointsRepository>() .GetQuery() .OrderByDescending(obj => obj.Points) .Select(obj => new { UserId = obj.User .DiscordAccounts .Select(obj2 => obj2.Id) .FirstOrDefault(), Points = obj.Points * 100.0 }) .ToList(); if (users.Count > 0) { var embedBuilder = new DiscordEmbedBuilder(); var messageBuilder = new DiscordMessageBuilder(); embedBuilder.WithTitle(LocalizationGroup.GetText("ParticipationOverview", "Participation points overview")); embedBuilder.WithColor(DiscordColor.DarkBlue); embedBuilder.WithImageUrl("attachment://chart.png"); var userNames = new List <string>(); foreach (var user in users) { var member = await commandContext.Guild .GetMemberAsync(user.UserId) .ConfigureAwait(false); userNames.Add($"{(string.IsNullOrWhiteSpace(member.Nickname) ? string.IsNullOrWhiteSpace(member.DisplayName) ? member.Username : member.DisplayName : member.Nickname)} [{user.Points:0.00}]"); } var chartConfiguration = new ChartConfigurationData { Type = "horizontalBar", Data = new Data.Json.QuickChart.Data { DataSets = new List <DataSet> { new DataSet <double> { BackgroundColor = users.Select(obj => "#316ed5") .ToList(), BorderColor = "#274d85", Data = users.Select(obj => obj.Points) .ToList() } }, Labels = userNames }, Options = new OptionsCollection { Scales = new ScalesCollection { XAxes = new List <XAxis> { new () { Ticks = new AxisTicks <double> { MinValue = 0, MaxValue = Math.Ceiling(((users.Max(obj => obj.Points) / 10) + 1) * 10), FontColor = "#b3b3b3" } } },
/// <summary> /// Post a overview of the current points /// </summary> /// <param name="commandContext">Command context</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task PostOverview(CommandContextContainer commandContext) { using (var dbFactory = RepositoryFactory.CreateInstance()) { foreach (var configuration in dbFactory.GetRepository <GuildSpecialRankConfigurationRepository>() .GetQuery() .Where(obj => obj.IsDeleted == false && obj.Guild.DiscordServerId == commandContext.Guild.Id) .Select(obj => new { obj.Description, obj.DiscordRoleId, obj.GrantThreshold, obj.RemoveThreshold, Users = obj.GuildSpecialRankPoints.Where(obj2 => obj2.Points > 0) .Select(obj2 => new { UserId = obj2.User .DiscordAccounts .Select(obj3 => obj3.Id) .FirstOrDefault(), obj2.Points }) .ToList() }) .ToList()) { if (configuration.Users.Count > 0) { var embedBuilder = new DiscordEmbedBuilder(); var messageBuilder = new DiscordMessageBuilder(); embedBuilder.WithTitle(LocalizationGroup.GetText("Overview", "Points overview")); embedBuilder.WithDescription($"{configuration.Description} ({commandContext.Guild.GetRole(configuration.DiscordRoleId).Mention})"); embedBuilder.WithColor(DiscordColor.DarkBlue); embedBuilder.WithImageUrl("attachment://chart.png"); var users = new List <string>(); foreach (var user in configuration.Users .OrderByDescending(obj => obj.Points) .ThenBy(obj => obj.UserId)) { var member = await commandContext.Guild .GetMemberAsync(user.UserId) .ConfigureAwait(false); users.Add($"{(string.IsNullOrWhiteSpace(member.Nickname) ? string.IsNullOrWhiteSpace(member.DisplayName) ? member.Username : member.DisplayName : member.Nickname)} ({user.Points:0.##})"); } var chartConfiguration = new ChartConfigurationData { Type = "bar", Data = new Data.Json.QuickChart.Data { DataSets = new List <DataSet> { new DataSet <double> { BackgroundColor = configuration.Users .Select(obj => "#316ed5") .ToList(), BorderColor = "#274d85", Data = configuration.Users .OrderByDescending(obj => obj.Points) .ThenBy(obj => obj.UserId) .Select(obj => obj.Points) .ToList() } }, Labels = users }, Options = new OptionsCollection { Annotation = new AnnotationsCollection { Annotations = new List <Annotation> { new () { BorderColor = "#f45b5b", BorderWidth = 2, Mode = "horizontal", ScaleID = "y-axis-0", Type = "line", Value = configuration.RemoveThreshold }, new () { BorderColor = "#90ee7e", BorderWidth = 2, Mode = "horizontal", ScaleID = "y-axis-0", Type = "line", Value = configuration.GrantThreshold } } },
/// <summary> /// Post personal overview /// </summary> /// <param name="commandContext">Command context</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task PostMeOverview(CommandContextContainer commandContext) { using (var dbFactory = RepositoryFactory.CreateInstance()) { var now = DateTime.Now; var messageBuilder = new DiscordMessageBuilder(); var embedBuilder = new DiscordEmbedBuilder() .WithThumbnail(commandContext.User.AvatarUrl) .WithTitle(LocalizationGroup.GetText("MeOverviewTitle", "Personal Statistics")) .WithColor(DiscordColor.Green) .WithFooter("Scruffy", "https://cdn.discordapp.com/app-icons/838381119585648650/823930922cbe1e5a9fa8552ed4b2a392.png?size=64") .WithTimestamp(now); var stringBuilder = new StringBuilder(); stringBuilder.AppendLine($"{commandContext.User.Mention} ({commandContext.User.Username}#{commandContext.User.Discriminator})"); stringBuilder.AppendLine(); stringBuilder.AppendLine(LocalizationGroup.GetText("MeOverviewDescription", "Personal statistics of the last 60 Days.")); stringBuilder.AppendLine(); embedBuilder.WithDescription(stringBuilder.ToString()); stringBuilder = new StringBuilder(); stringBuilder.Append(LocalizationGroup.GetText("MeOverviewJoined", "Joined:")); stringBuilder.Append(' '); stringBuilder.Append(Formatter.InlineCode(commandContext.Member.JoinedAt.LocalDateTime.ToString("g"))); stringBuilder.Append(Environment.NewLine); stringBuilder.Append(LocalizationGroup.GetText("MeOverviewCreated", "Created:")); stringBuilder.Append(' '); stringBuilder.Append(Formatter.InlineCode(commandContext.User.CreationTimestamp.LocalDateTime.ToString("g"))); stringBuilder.Append(Environment.NewLine); stringBuilder.Append(LocalizationGroup.GetText("MeOverviewUserId", "User ID:")); stringBuilder.Append(' '); stringBuilder.Append(Formatter.InlineCode(commandContext.User.Id.ToString())); stringBuilder.Append(Environment.NewLine); embedBuilder.AddField(LocalizationGroup.GetText("MeOverviewUserInfo", "User Info"), stringBuilder.ToString()); stringBuilder = new StringBuilder(); var mostActive = dbFactory.GetRepository <DiscordMessageRepository>() .GetQuery() .Where(obj => obj.DiscordServerId == commandContext.Guild.Id && obj.DiscordAccountId == commandContext.User.Id) .GroupBy(obj => obj.DiscordChannelId) .Select(obj => new { Channeld = obj.Key, Count = obj.Count() }) .OrderByDescending(obj => obj.Count) .FirstOrDefault(); if (mostActive != null) { var channel = commandContext.Guild.GetChannel(mostActive.Channeld); if (channel != null) { stringBuilder.Append(LocalizationGroup.GetText("MeOverviewMessage", "Message:")); stringBuilder.Append(' '); stringBuilder.Append(channel.Mention); stringBuilder.Append(' '); stringBuilder.Append(Formatter.InlineCode(mostActive.Count.ToString() + ' ' + LocalizationGroup.GetText("MeOverviewMessages", "messages"))); } } stringBuilder.Append("\u200b"); embedBuilder.AddField(LocalizationGroup.GetText("MeOverviewMostActive", "Most Active Channel"), stringBuilder.ToString()); stringBuilder = new StringBuilder(); stringBuilder.Append(LocalizationGroup.GetText("MeOverview60Days", "60 Days:")); stringBuilder.Append(' '); var limit = now.AddDays(-60); stringBuilder.Append(Formatter.InlineCode(dbFactory.GetRepository <DiscordMessageRepository>() .GetQuery() .Count(obj => obj.DiscordServerId == commandContext.Guild.Id && obj.DiscordAccountId == commandContext.User.Id && obj.TimeStamp > limit) .ToString() + ' ' + LocalizationGroup.GetText("MeOverviewMessages", "messages"))); stringBuilder.Append(Environment.NewLine); stringBuilder.Append(LocalizationGroup.GetText("MeOverview7Days", "7 Days:")); stringBuilder.Append(' '); limit = now.AddDays(-7); stringBuilder.Append(Formatter.InlineCode(dbFactory.GetRepository <DiscordMessageRepository>() .GetQuery() .Count(obj => obj.DiscordServerId == commandContext.Guild.Id && obj.DiscordAccountId == commandContext.User.Id && obj.TimeStamp > limit) .ToString() + ' ' + LocalizationGroup.GetText("MeOverviewMessages", "messages"))); stringBuilder.Append(Environment.NewLine); stringBuilder.Append(LocalizationGroup.GetText("MeOverview24Hours", "24 Hours:")); stringBuilder.Append(' '); limit = now.AddDays(-1); stringBuilder.Append(Formatter.InlineCode(dbFactory.GetRepository <DiscordMessageRepository>() .GetQuery() .Count(obj => obj.DiscordServerId == commandContext.Guild.Id && obj.DiscordAccountId == commandContext.User.Id && obj.TimeStamp > limit) .ToString() + ' ' + LocalizationGroup.GetText("MeOverviewMessages", "messages"))); stringBuilder.Append(Environment.NewLine); embedBuilder.AddField(LocalizationGroup.GetText("MeOverviewMessagesField", "Messages"), stringBuilder.ToString()); var messageChannels = dbFactory.GetRepository <DiscordMessageRepository>() .GetQuery() .Where(obj => obj.DiscordServerId == commandContext.Guild.Id && obj.DiscordAccountId == commandContext.User.Id) .GroupBy(obj => obj.DiscordChannelId) .Select(obj => new { Channeld = obj.Key, Count = obj.Count() }) .OrderByDescending(obj => obj.Count) .ToList(); var messagesSum = messageChannels.Sum(obj => obj.Count); var messagesData = new List <int>(); var messagesLabels = new List <string>(); var messagesOther = 0; foreach (var messageChannel in messageChannels) { if (messageChannel.Count / (double)messagesSum > 0.1) { messagesData.Add(messageChannel.Count); messagesLabels.Add(commandContext.Guild.GetChannel(messageChannel.Channeld) .Name); } else { messagesOther += messageChannel.Count; } } if (messagesOther > 0) { messagesData.Add(messagesOther); messagesLabels.Add(LocalizationGroup.GetText("MeOverviewOtherMessages", "Other")); } var chartConfiguration = new ChartConfigurationData { Type = "outlabeledDoughnut", Data = new Data.Json.QuickChart.Data { DataSets = new List <DataSet> { new DataSet <int> { BorderColor = "#333333", BackgroundColor = new List <string> { "#0d1c26", "#142b39", "#1d3e53", "#21475e", "#2e6384", "#357197", "#3c80aa", "#428ebd", "#5599c3", "#68a4ca" }, Data = messagesData } }, Labels = messagesLabels }, Options = new OptionsCollection { Plugins = new PluginsCollection { Legend = false, OutLabels = new OutLabelsCollection { Text = "%l (%v)", Stretch = 40 }, DoughnutLabel = new DoughnutLabelCollection { Labels = new List <Label> { new () { Color = "white", Text = messagesSum.ToString() }, new () { Color = "white", Text = LocalizationGroup.GetText("MeOverviewMessages", "messages") }, } }, },
/// <summary> /// Post worlds overview /// </summary> /// <param name="commandContext">Command context</param> /// <returns>A <see cref="Task"/> representing the asynchronous operation.</returns> public async Task PostWorldsOverview(CommandContextContainer commandContext) { using (var dbFactory = RepositoryFactory.CreateInstance()) { var worldsQuery = dbFactory.GetRepository <GuildWarsWorldRepository>() .GetQuery() .Select(obj => obj); var worlds = dbFactory.GetRepository <AccountRepository>() .GetQuery() .Where(obj => obj.WorldId != null) .GroupBy(obj => obj.WorldId) .Select(obj => new { WorldId = obj.Key, Count = obj.Count(), Name = worldsQuery.Where(obj2 => obj2.Id == obj.Key) .Select(obj2 => obj2.Name) .FirstOrDefault() }) .ToList(); if (worlds.Count > 0) { var embedBuilder = new DiscordEmbedBuilder(); var messageBuilder = new DiscordMessageBuilder(); embedBuilder.WithTitle(LocalizationGroup.GetText("Overview", "Worlds overview")); embedBuilder.WithColor(DiscordColor.DarkBlue); embedBuilder.WithImageUrl("attachment://chart.png"); var chartConfiguration = new ChartConfigurationData { Type = "bar", Data = new Data.Json.QuickChart.Data { DataSets = new List <DataSet> { new DataSet <int> { BackgroundColor = worlds.Select(obj => "#316ed5") .ToList(), BorderColor = "#274d85", Data = worlds.OrderByDescending(obj => obj.Count) .ThenBy(obj => obj.Name) .Select(obj => obj.Count) .ToList() } }, Labels = worlds.OrderByDescending(obj => obj.Count) .ThenBy(obj => obj.Name) .Select(obj => obj.Name) .ToList() }, Options = new OptionsCollection { Scales = new ScalesCollection { XAxes = new List <XAxis> { new () { Ticks = new AxisTicks { FontColor = "#b3b3b3" } } },