>pollstats added
This commit is contained in:
		@@ -7,6 +7,7 @@ using System;
 | 
				
			|||||||
using System.Collections.Concurrent;
 | 
					using System.Collections.Concurrent;
 | 
				
			||||||
using System.Collections.Generic;
 | 
					using System.Collections.Generic;
 | 
				
			||||||
using System.Linq;
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
using System.Threading;
 | 
					using System.Threading;
 | 
				
			||||||
using System.Threading.Tasks;
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -17,7 +18,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
        [Group]
 | 
					        [Group]
 | 
				
			||||||
        public class PollCommands : ModuleBase
 | 
					        public class PollCommands : ModuleBase
 | 
				
			||||||
        {
 | 
					        {
 | 
				
			||||||
            public static ConcurrentDictionary<IGuild, Poll> ActivePolls = new ConcurrentDictionary<IGuild, Poll>();
 | 
					            public static ConcurrentDictionary<ulong, Poll> ActivePolls = new ConcurrentDictionary<ulong, Poll>();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            [NadekoCommand, Usage, Description, Aliases]
 | 
					            [NadekoCommand, Usage, Description, Aliases]
 | 
				
			||||||
            [RequireUserPermission(GuildPermission.ManageMessages)]
 | 
					            [RequireUserPermission(GuildPermission.ManageMessages)]
 | 
				
			||||||
@@ -31,6 +32,18 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
            public Task PublicPoll([Remainder] string arg = null)
 | 
					            public Task PublicPoll([Remainder] string arg = null)
 | 
				
			||||||
                => InternalStartPoll(arg, isPublic: true);
 | 
					                => InternalStartPoll(arg, isPublic: true);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            [NadekoCommand, Usage, Description, Aliases]
 | 
				
			||||||
 | 
					            [RequireUserPermission(GuildPermission.ManageMessages)]
 | 
				
			||||||
 | 
					            [RequireContext(ContextType.Guild)]
 | 
				
			||||||
 | 
					            public async Task PollStats()
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                Games.Poll poll;
 | 
				
			||||||
 | 
					                if (!ActivePolls.TryGetValue(Context.Guild.Id, out poll))
 | 
				
			||||||
 | 
					                    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                await Context.Channel.EmbedAsync(poll.GetStats("Current Poll Results"));
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            private async Task InternalStartPoll(string arg, bool isPublic = false)
 | 
					            private async Task InternalStartPoll(string arg, bool isPublic = false)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                var channel = (ITextChannel)Context.Channel;
 | 
					                var channel = (ITextChannel)Context.Channel;
 | 
				
			||||||
@@ -44,7 +57,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                    return;
 | 
					                    return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                var poll = new Poll(Context.Message, data[0], data.Skip(1), isPublic: isPublic);
 | 
					                var poll = new Poll(Context.Message, data[0], data.Skip(1), isPublic: isPublic);
 | 
				
			||||||
                if (ActivePolls.TryAdd(channel.Guild, poll))
 | 
					                if (ActivePolls.TryAdd(channel.Guild.Id, poll))
 | 
				
			||||||
                {
 | 
					                {
 | 
				
			||||||
                    await poll.StartPoll().ConfigureAwait(false);
 | 
					                    await poll.StartPoll().ConfigureAwait(false);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
@@ -60,7 +73,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                var channel = (ITextChannel)Context.Channel;
 | 
					                var channel = (ITextChannel)Context.Channel;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Poll poll;
 | 
					                Poll poll;
 | 
				
			||||||
                ActivePolls.TryRemove(channel.Guild, out poll);
 | 
					                ActivePolls.TryRemove(channel.Guild.Id, out poll);
 | 
				
			||||||
                await poll.StopPoll().ConfigureAwait(false);
 | 
					                await poll.StopPoll().ConfigureAwait(false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@@ -69,20 +82,55 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
        {
 | 
					        {
 | 
				
			||||||
            private readonly IUserMessage originalMessage;
 | 
					            private readonly IUserMessage originalMessage;
 | 
				
			||||||
            private readonly IGuild guild;
 | 
					            private readonly IGuild guild;
 | 
				
			||||||
            private readonly string[] answers;
 | 
					            private string[] Answers { get; }
 | 
				
			||||||
            private ConcurrentDictionary<ulong, int> participants = new ConcurrentDictionary<ulong, int>();
 | 
					            private ConcurrentDictionary<ulong, int> participants = new ConcurrentDictionary<ulong, int>();
 | 
				
			||||||
            private readonly string question;
 | 
					            private readonly string question;
 | 
				
			||||||
            private DateTime started;
 | 
					            private DateTime started;
 | 
				
			||||||
            private CancellationTokenSource pollCancellationSource = new CancellationTokenSource();
 | 
					            private CancellationTokenSource pollCancellationSource = new CancellationTokenSource();
 | 
				
			||||||
            private readonly bool isPublic;
 | 
					            public bool IsPublic { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            public Poll(IUserMessage umsg, string question, IEnumerable<string> enumerable, bool isPublic = false)
 | 
					            public Poll(IUserMessage umsg, string question, IEnumerable<string> enumerable, bool isPublic = false)
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                this.originalMessage = umsg;
 | 
					                this.originalMessage = umsg;
 | 
				
			||||||
                this.guild = ((ITextChannel)umsg.Channel).Guild;
 | 
					                this.guild = ((ITextChannel)umsg.Channel).Guild;
 | 
				
			||||||
                this.question = question;
 | 
					                this.question = question;
 | 
				
			||||||
                this.answers = enumerable as string[] ?? enumerable.ToArray();
 | 
					                this.Answers = enumerable as string[] ?? enumerable.ToArray();
 | 
				
			||||||
                this.isPublic = isPublic;
 | 
					                this.IsPublic = isPublic;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            public EmbedBuilder GetStats(string title)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var results = participants.GroupBy(kvp => kvp.Value)
 | 
				
			||||||
 | 
					                                    .ToDictionary(x => x.Key, x => x.Sum(kvp => 1))
 | 
				
			||||||
 | 
					                                    .OrderByDescending(kvp => kvp.Value)
 | 
				
			||||||
 | 
					                                    .ToArray();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var eb = new EmbedBuilder().WithTitle(title);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var sb = new StringBuilder()
 | 
				
			||||||
 | 
					                    .AppendLine(Format.Bold(question))
 | 
				
			||||||
 | 
					                    .AppendLine();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                var totalVotesCast = 0;
 | 
				
			||||||
 | 
					                if (results.Length == 0)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    sb.AppendLine("No votes cast.");
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    for (int i = 0; i < results.Length; i++)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        var result = results[i];
 | 
				
			||||||
 | 
					                        sb.AppendLine($"`{i + 1}.` {Format.Bold(Answers[result.Key - 1])} with {Format.Bold(result.Value.ToString())} votes.");
 | 
				
			||||||
 | 
					                        totalVotesCast += result.Value;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                eb.WithDescription(sb.ToString())
 | 
				
			||||||
 | 
					                  .WithFooter(efb => efb.WithText(totalVotesCast + " total votes cast."));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                return eb;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            public async Task StartPoll()
 | 
					            public async Task StartPoll()
 | 
				
			||||||
@@ -91,8 +139,8 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                NadekoBot.Client.MessageReceived += Vote;
 | 
					                NadekoBot.Client.MessageReceived += Vote;
 | 
				
			||||||
                var msgToSend = $"📃**{originalMessage.Author.Username}** has created a poll which requires your attention:\n\n**{question}**\n";
 | 
					                var msgToSend = $"📃**{originalMessage.Author.Username}** has created a poll which requires your attention:\n\n**{question}**\n";
 | 
				
			||||||
                var num = 1;
 | 
					                var num = 1;
 | 
				
			||||||
                msgToSend = answers.Aggregate(msgToSend, (current, answ) => current + $"`{num++}.` **{answ}**\n");
 | 
					                msgToSend = Answers.Aggregate(msgToSend, (current, answ) => current + $"`{num++}.` **{answ}**\n");
 | 
				
			||||||
                if (!isPublic)
 | 
					                if (!IsPublic)
 | 
				
			||||||
                    msgToSend += "\n**Private Message me with the corresponding number of the answer.**";
 | 
					                    msgToSend += "\n**Private Message me with the corresponding number of the answer.**";
 | 
				
			||||||
                else
 | 
					                else
 | 
				
			||||||
                    msgToSend += "\n**Send a Message here with the corresponding number of the answer.**";
 | 
					                    msgToSend += "\n**Send a Message here with the corresponding number of the answer.**";
 | 
				
			||||||
@@ -102,30 +150,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
            public async Task StopPoll()
 | 
					            public async Task StopPoll()
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                NadekoBot.Client.MessageReceived -= Vote;
 | 
					                NadekoBot.Client.MessageReceived -= Vote;
 | 
				
			||||||
                try
 | 
					                await originalMessage.Channel.EmbedAsync(GetStats("POLL CLOSED")).ConfigureAwait(false);
 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    var results = participants.GroupBy(kvp => kvp.Value)
 | 
					 | 
				
			||||||
                                    .ToDictionary(x => x.Key, x => x.Sum(kvp => 1))
 | 
					 | 
				
			||||||
                                    .OrderByDescending(kvp => kvp.Value);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    var totalVotesCast = results.Sum(kvp => kvp.Value);
 | 
					 | 
				
			||||||
                    if (totalVotesCast == 0)
 | 
					 | 
				
			||||||
                    {
 | 
					 | 
				
			||||||
                        await originalMessage.Channel.SendMessageAsync("📄 **No votes have been cast.**").ConfigureAwait(false);
 | 
					 | 
				
			||||||
                        return;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    var closeMessage = $"--------------**POLL CLOSED**--------------\n" +
 | 
					 | 
				
			||||||
                                       $"📄 , here are the results:\n";
 | 
					 | 
				
			||||||
                    closeMessage = results.Aggregate(closeMessage, (current, kvp) => current + $"`{kvp.Key}.` **[{answers[kvp.Key - 1]}]**" +
 | 
					 | 
				
			||||||
                                                                                     $" has {kvp.Value} votes." +
 | 
					 | 
				
			||||||
                                                                                     $"({kvp.Value * 1.0f / totalVotesCast * 100}%)\n");
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
                    await originalMessage.Channel.SendConfirmAsync($"📄 **Total votes cast**: {totalVotesCast}\n{closeMessage}").ConfigureAwait(false);
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                catch (Exception ex)
 | 
					 | 
				
			||||||
                {
 | 
					 | 
				
			||||||
                    Console.WriteLine($"Error in poll game {ex}");
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            private async void Vote(SocketMessage imsg)
 | 
					            private async void Vote(SocketMessage imsg)
 | 
				
			||||||
@@ -141,11 +166,11 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                    int vote;
 | 
					                    int vote;
 | 
				
			||||||
                    if (!int.TryParse(imsg.Content, out vote))
 | 
					                    if (!int.TryParse(imsg.Content, out vote))
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
                    if (vote < 1 || vote > answers.Length)
 | 
					                    if (vote < 1 || vote > Answers.Length)
 | 
				
			||||||
                        return;
 | 
					                        return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                    IMessageChannel ch;
 | 
					                    IMessageChannel ch;
 | 
				
			||||||
                    if (isPublic)
 | 
					                    if (IsPublic)
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        //if public, channel must be the same the poll started in
 | 
					                        //if public, channel must be the same the poll started in
 | 
				
			||||||
                        if (originalMessage.Channel.Id != imsg.Channel.Id)
 | 
					                        if (originalMessage.Channel.Id != imsg.Channel.Id)
 | 
				
			||||||
@@ -167,7 +192,7 @@ namespace NadekoBot.Modules.Games
 | 
				
			|||||||
                    //user can vote only once
 | 
					                    //user can vote only once
 | 
				
			||||||
                    if (participants.TryAdd(msg.Author.Id, vote))
 | 
					                    if (participants.TryAdd(msg.Author.Id, vote))
 | 
				
			||||||
                    {
 | 
					                    {
 | 
				
			||||||
                        if (!isPublic)
 | 
					                        if (!IsPublic)
 | 
				
			||||||
                        {
 | 
					                        {
 | 
				
			||||||
                            await ch.SendConfirmAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false);
 | 
					                            await ch.SendConfirmAsync($"Thanks for voting **{msg.Author.Username}**.").ConfigureAwait(false);
 | 
				
			||||||
                        }
 | 
					                        }
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										27
									
								
								src/NadekoBot/Resources/CommandStrings.Designer.cs
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										27
									
								
								src/NadekoBot/Resources/CommandStrings.Designer.cs
									
									
									
										generated
									
									
									
								
							@@ -5162,6 +5162,33 @@ namespace NadekoBot.Resources {
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///    Looks up a localized string similar to pollstats.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public static string pollstats_cmd {
 | 
				
			||||||
 | 
					            get {
 | 
				
			||||||
 | 
					                return ResourceManager.GetString("pollstats_cmd", resourceCulture);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///    Looks up a localized string similar to Shows the poll results without stopping the poll on this server..
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public static string pollstats_desc {
 | 
				
			||||||
 | 
					            get {
 | 
				
			||||||
 | 
					                return ResourceManager.GetString("pollstats_desc", resourceCulture);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        ///    Looks up a localized string similar to `{0}pollstats`.
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public static string pollstats_usage {
 | 
				
			||||||
 | 
					            get {
 | 
				
			||||||
 | 
					                return ResourceManager.GetString("pollstats_usage", resourceCulture);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        /// <summary>
 | 
					        /// <summary>
 | 
				
			||||||
        ///    Looks up a localized string similar to prune clr.
 | 
					        ///    Looks up a localized string similar to prune clr.
 | 
				
			||||||
        /// </summary>
 | 
					        /// </summary>
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2880,4 +2880,13 @@
 | 
				
			|||||||
  <data name="createinvite_usage" xml:space="preserve">
 | 
					  <data name="createinvite_usage" xml:space="preserve">
 | 
				
			||||||
    <value>`{0}crinv`</value>
 | 
					    <value>`{0}crinv`</value>
 | 
				
			||||||
  </data>
 | 
					  </data>
 | 
				
			||||||
 | 
					  <data name="pollstats_cmd" xml:space="preserve">
 | 
				
			||||||
 | 
					    <value>pollstats</value>
 | 
				
			||||||
 | 
					  </data>
 | 
				
			||||||
 | 
					  <data name="pollstats_desc" xml:space="preserve">
 | 
				
			||||||
 | 
					    <value>Shows the poll results without stopping the poll on this server.</value>
 | 
				
			||||||
 | 
					  </data>
 | 
				
			||||||
 | 
					  <data name="pollstats_usage" xml:space="preserve">
 | 
				
			||||||
 | 
					    <value>`{0}pollstats`</value>
 | 
				
			||||||
 | 
					  </data>
 | 
				
			||||||
</root>
 | 
					</root>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user