From d5be506af5093ffa89efe3c41fffdf674dba35dd Mon Sep 17 00:00:00 2001 From: Harold Pulcher Date: Sun, 9 Jun 2024 21:54:20 -0500 Subject: [PATCH 1/8] catching up to mr. big head --- MrBigHead.Web/Pages/Quips.razor | 9 ++++++++- MrBigHead.Web/Services/UserInformationProvider.cs | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/MrBigHead.Web/Pages/Quips.razor b/MrBigHead.Web/Pages/Quips.razor index 0e927c0..813355a 100644 --- a/MrBigHead.Web/Pages/Quips.razor +++ b/MrBigHead.Web/Pages/Quips.razor @@ -1,6 +1,9 @@ @page "/quips" @using Microsoft.AspNetCore.Components.QuickGrid +@using MrBigHead.Shared +@using MrBigHead.Web.Services @inject HttpClient Http +@inject UserInformationProvider UserInformationProvider

Phrases

@@ -15,7 +18,7 @@ else - @if (isAdmin) + @if (userInformation.Tier == "3000") { @@ -30,11 +33,15 @@ else @code { private IEnumerable sayings; PaginationState pagination = new PaginationState { ItemsPerPage = 20 }; + UserInformation userInformation { get; set; } bool isAdmin { get; set; } = true; protected override async Task OnInitializedAsync() { sayings = await Http.GetFromJsonAsync>("https://bigheadfuncs.azurewebsites.net/api/getallphrases"); + + userInformation = await UserInformationProvider.GetUserInformation(null); + Console.WriteLine($"Tier: {userInformation.Tier}"); } public class Sayings diff --git a/MrBigHead.Web/Services/UserInformationProvider.cs b/MrBigHead.Web/Services/UserInformationProvider.cs index 05ac66f..9b75170 100644 --- a/MrBigHead.Web/Services/UserInformationProvider.cs +++ b/MrBigHead.Web/Services/UserInformationProvider.cs @@ -36,7 +36,8 @@ public async Task GetUserInformation(ClaimsPrincipal principal) } else { - await Console.Out.WriteLineAsync($"no username or other information"); + await Console.Out.WriteLineAsync($"return whatever userinformation we have."); + return UserInformation; } await Console.Out.WriteLineAsync($"Image: {UserInformation.ImageUrl}"); From a3ca958f3946f23cce5c637c878befa25a234a2d Mon Sep 17 00:00:00 2001 From: Harold Pulcher Date: Tue, 11 Jun 2024 00:28:56 -0500 Subject: [PATCH 2/8] Added CanExecute and CoolDownService --- Magic8HeadService/Commands/AskCommand.cs | 5 +++ Magic8HeadService/Commands/DadCommand.cs | 32 ++++++++++++++--- Magic8HeadService/Commands/HelpCommand.cs | 5 +++ Magic8HeadService/Commands/IMbhCommand.cs | 1 + .../Commands/InspirationalCommand.cs | 5 +++ Magic8HeadService/Commands/MbhCommand.cs | 34 +++++++++++++++++-- Magic8HeadService/Commands/NullCommand.cs | 5 +++ Magic8HeadService/Commands/SayCommand.cs | 10 ++++++ Magic8HeadService/Services/CoolDownService.cs | 12 +++++++ 9 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 Magic8HeadService/Services/CoolDownService.cs diff --git a/Magic8HeadService/Commands/AskCommand.cs b/Magic8HeadService/Commands/AskCommand.cs index 21d8b5b..93c7147 100644 --- a/Magic8HeadService/Commands/AskCommand.cs +++ b/Magic8HeadService/Commands/AskCommand.cs @@ -26,6 +26,11 @@ public AskCommand(ITwitchClient client, ISayingResponse sayingResponse, string m this.mood = mood; } + public bool CanExecute() + { + throw new System.NotImplementedException(); + } + public void Handle(OnChatCommandReceivedArgs cmd) { var message = GetRandomAnswer().ToLower(); diff --git a/Magic8HeadService/Commands/DadCommand.cs b/Magic8HeadService/Commands/DadCommand.cs index ac850c4..6671fa0 100644 --- a/Magic8HeadService/Commands/DadCommand.cs +++ b/Magic8HeadService/Commands/DadCommand.cs @@ -12,23 +12,47 @@ internal class DadCommand : IMbhCommand private ITwitchClient client; private ISayingResponse sayingResponse; private readonly IDadJokeService dadJokeService; + private TimeSpan coolDownTimeSpan = TimeSpan.FromSeconds(15); + private DateTime coolDown = DateTime.MinValue; private ILogger logger; private string alternateSite = "https://karljoke.herokuapp.com/jokes/random"; //= string.Empty; - public DadCommand(ITwitchClient client, ISayingResponse sayingResponse, IDadJokeService dadJokeService, ILogger logger) + public DadCommand(ITwitchClient client, ISayingResponse sayingResponse, IDadJokeService dadJokeService, DateTime coolDown, ILogger logger) { this.client = client; this.sayingResponse = sayingResponse; this.dadJokeService = dadJokeService; this.logger = logger; + this.coolDown = coolDown; } public void Handle(OnChatCommandReceivedArgs cmd) { - var dadJoke = dadJokeService.GetDadJoke(); + if (CanExecute()) + { + //coolDown = DateTime.UtcNow.AddMinutes(1); + //logger.Log(LogLevel.Debug, "Setting the next available DadJoke to {coolDown}", coolDown); - sayingResponse.SaySomethingNiceAsync(dadJoke, client, cmd.Command.ChatMessage.Channel, cmd.Command.ChatMessage.Username); - client.SendMessage(cmd.Command.ChatMessage.Channel, $"Q: {dadJoke}"); + var dadJoke = dadJokeService.GetDadJoke(); + + sayingResponse.SaySomethingNiceAsync(dadJoke, client, cmd.Command.ChatMessage.Channel, cmd.Command.ChatMessage.Username); + client.SendMessage(cmd.Command.ChatMessage.Channel, $"Q: {dadJoke}"); + } + else + { + client.SendMessage(cmd.Command.ChatMessage.Channel, $"Pull my finger is brewin'"); + } + } + + public bool CanExecute() + { + var currentTime = DateTime.UtcNow; + if ( currentTime < coolDown ) + { + return false; + } + + return true; } } } diff --git a/Magic8HeadService/Commands/HelpCommand.cs b/Magic8HeadService/Commands/HelpCommand.cs index a56d875..b863231 100644 --- a/Magic8HeadService/Commands/HelpCommand.cs +++ b/Magic8HeadService/Commands/HelpCommand.cs @@ -45,5 +45,10 @@ private string GetHelpMessage() trimmedResult += ". To help code me or request another feature head over to my repository at https://github.com/pulcher/TalkingHead"; return trimmedResult; } + + public bool CanExecute() + { + return true; + } } } \ No newline at end of file diff --git a/Magic8HeadService/Commands/IMbhCommand.cs b/Magic8HeadService/Commands/IMbhCommand.cs index 5e93e7e..58f9b8b 100644 --- a/Magic8HeadService/Commands/IMbhCommand.cs +++ b/Magic8HeadService/Commands/IMbhCommand.cs @@ -4,6 +4,7 @@ namespace Magic8HeadService { public interface IMbhCommand { + bool CanExecute(); void Handle(OnChatCommandReceivedArgs cmd); } } diff --git a/Magic8HeadService/Commands/InspirationalCommand.cs b/Magic8HeadService/Commands/InspirationalCommand.cs index ac21d56..cd82823 100644 --- a/Magic8HeadService/Commands/InspirationalCommand.cs +++ b/Magic8HeadService/Commands/InspirationalCommand.cs @@ -19,6 +19,11 @@ public InspirationalCommand(ITwitchClient client, ISayingResponse sayingResponse this.logger = logger; } + public bool CanExecute() + { + throw new System.NotImplementedException(); + } + public void Handle(OnChatCommandReceivedArgs cmd) { var message = GetRandomAnswer(); diff --git a/Magic8HeadService/Commands/MbhCommand.cs b/Magic8HeadService/Commands/MbhCommand.cs index 21f790b..63fbe1e 100644 --- a/Magic8HeadService/Commands/MbhCommand.cs +++ b/Magic8HeadService/Commands/MbhCommand.cs @@ -3,6 +3,8 @@ using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Logging; using MrBigHead.Shared; +using System; +using System.Collections.Generic; using System.Linq; using TwitchLib.Client.Events; using TwitchLib.Client.Interfaces; @@ -18,6 +20,7 @@ public class MbhCommand : ICommandMbhToTwitch private IMbhCommand action; private string mood= Moods.Snarky; private ICommandTracker commandTracker; + private Dictionary coolDownTimes = new Dictionary(); public string Name => "mbh"; @@ -36,8 +39,10 @@ public MbhCommand(ITwitchClient client, IConfiguration config, ISayingResponse s public void Handle(OnChatCommandReceivedArgs args) { action = new NullCommand(logger); + + var commandToExecute = args.Command.ArgumentsAsList.FirstOrDefault()?.ToLower(); - switch (args.Command.ArgumentsAsList.FirstOrDefault()?.ToLower()) + switch (commandToExecute) { case AvailableCommands.Help: // case null: @@ -47,7 +52,8 @@ public void Handle(OnChatCommandReceivedArgs args) action = new AskCommand(client, sayingResponse, mood, logger); break; case AvailableCommands.Dad: - action = new DadCommand(client, sayingResponse, dadJokeService, logger); + action = new DadCommand(client, sayingResponse, dadJokeService, + GetCoolDown(commandToExecute), logger); break; case AvailableCommands.Inspire: action = new InspirationalCommand(client, sayingResponse, logger); @@ -59,7 +65,31 @@ public void Handle(OnChatCommandReceivedArgs args) break; } + UpdateCooldown(commandToExecute); + action.Handle(args); return; } + + private DateTime GetCoolDown(string commandToExecute) + { + if (coolDownTimes.TryGetValue(commandToExecute, out var cooldown)) { + return cooldown; + } + + return DateTime.MinValue; + } + + private DateTime UpdateCooldown(string commandToExecute) + { + var nextExecuteTime = DateTime.UtcNow.AddMinutes(1); + + if (!coolDownTimes.TryAdd(commandToExecute, nextExecuteTime)) + { + coolDownTimes[commandToExecute] = nextExecuteTime; + } + + return nextExecuteTime; + + } } diff --git a/Magic8HeadService/Commands/NullCommand.cs b/Magic8HeadService/Commands/NullCommand.cs index f7a6deb..a129a94 100644 --- a/Magic8HeadService/Commands/NullCommand.cs +++ b/Magic8HeadService/Commands/NullCommand.cs @@ -12,6 +12,11 @@ public NullCommand(ILogger logger) this.logger = logger; } + public bool CanExecute() + { + return false; + } + public void Handle(OnChatCommandReceivedArgs cmd) { logger.LogInformation($"Nope.... not gonna do it!"); diff --git a/Magic8HeadService/Commands/SayCommand.cs b/Magic8HeadService/Commands/SayCommand.cs index 78f4f4f..f353738 100644 --- a/Magic8HeadService/Commands/SayCommand.cs +++ b/Magic8HeadService/Commands/SayCommand.cs @@ -49,5 +49,15 @@ public void Handle(OnChatCommandReceivedArgs cmd) var check = string.Empty; } + + bool IMbhCommand.CanExecute() + { + throw new System.NotImplementedException(); + } + + void IMbhCommand.Handle(OnChatCommandReceivedArgs cmd) + { + throw new System.NotImplementedException(); + } } } \ No newline at end of file diff --git a/Magic8HeadService/Services/CoolDownService.cs b/Magic8HeadService/Services/CoolDownService.cs new file mode 100644 index 0000000..31c42b3 --- /dev/null +++ b/Magic8HeadService/Services/CoolDownService.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Magic8HeadService.Services +{ + internal class CoolDownService + { + } +} From 5c5e4ccd71582fc5dfda2b350b3e700b439d88e3 Mon Sep 17 00:00:00 2001 From: Harold Pulcher Date: Tue, 11 Jun 2024 21:39:14 -0500 Subject: [PATCH 3/8] adding in a CoolDownService --- Magic8HeadService/Commands/DadCommand.cs | 6 ++-- Magic8HeadService/Commands/MbhCommand.cs | 32 +++---------------- Magic8HeadService/Program.cs | 1 + Magic8HeadService/Services/CoolDownService.cs | 2 +- Magic8HeadService/TwitchBot.cs | 5 ++- Magic8HeadService/Worker.cs | 8 ++++- 6 files changed, 22 insertions(+), 32 deletions(-) diff --git a/Magic8HeadService/Commands/DadCommand.cs b/Magic8HeadService/Commands/DadCommand.cs index 6671fa0..aa10034 100644 --- a/Magic8HeadService/Commands/DadCommand.cs +++ b/Magic8HeadService/Commands/DadCommand.cs @@ -1,4 +1,5 @@ -using Microsoft.Extensions.Logging; +using Magic8HeadService.Services; +using Microsoft.Extensions.Logging; using System; using System.Threading.Tasks; using TwitchLib.Client; @@ -17,7 +18,8 @@ internal class DadCommand : IMbhCommand private ILogger logger; private string alternateSite = "https://karljoke.herokuapp.com/jokes/random"; //= string.Empty; - public DadCommand(ITwitchClient client, ISayingResponse sayingResponse, IDadJokeService dadJokeService, DateTime coolDown, ILogger logger) + public DadCommand(ITwitchClient client, ISayingResponse sayingResponse, IDadJokeService dadJokeService, + CoolDownService coolDownService, ILogger logger) { this.client = client; this.sayingResponse = sayingResponse; diff --git a/Magic8HeadService/Commands/MbhCommand.cs b/Magic8HeadService/Commands/MbhCommand.cs index 63fbe1e..c27b281 100644 --- a/Magic8HeadService/Commands/MbhCommand.cs +++ b/Magic8HeadService/Commands/MbhCommand.cs @@ -20,12 +20,13 @@ public class MbhCommand : ICommandMbhToTwitch private IMbhCommand action; private string mood= Moods.Snarky; private ICommandTracker commandTracker; - private Dictionary coolDownTimes = new Dictionary(); + private readonly CoolDownService coolDownService; public string Name => "mbh"; public MbhCommand(ITwitchClient client, IConfiguration config, ISayingResponse sayingResponse, - IDadJokeService dadJokeService, IMessageChecker messageChecker, ICommandTracker commandTracker, ILogger logger) + IDadJokeService dadJokeService, IMessageChecker messageChecker, ICommandTracker commandTracker, + CoolDownService coolDownService, ILogger logger) { this.client = client; this.config = config; @@ -33,6 +34,7 @@ public MbhCommand(ITwitchClient client, IConfiguration config, ISayingResponse s this.dadJokeService = dadJokeService; this.messageChecker = messageChecker; this.commandTracker = commandTracker; + this.coolDownService = coolDownService; this.logger = logger; } @@ -53,7 +55,7 @@ public void Handle(OnChatCommandReceivedArgs args) break; case AvailableCommands.Dad: action = new DadCommand(client, sayingResponse, dadJokeService, - GetCoolDown(commandToExecute), logger); + coolDownService, logger); break; case AvailableCommands.Inspire: action = new InspirationalCommand(client, sayingResponse, logger); @@ -65,31 +67,7 @@ public void Handle(OnChatCommandReceivedArgs args) break; } - UpdateCooldown(commandToExecute); - action.Handle(args); return; } - - private DateTime GetCoolDown(string commandToExecute) - { - if (coolDownTimes.TryGetValue(commandToExecute, out var cooldown)) { - return cooldown; - } - - return DateTime.MinValue; - } - - private DateTime UpdateCooldown(string commandToExecute) - { - var nextExecuteTime = DateTime.UtcNow.AddMinutes(1); - - if (!coolDownTimes.TryAdd(commandToExecute, nextExecuteTime)) - { - coolDownTimes[commandToExecute] = nextExecuteTime; - } - - return nextExecuteTime; - - } } diff --git a/Magic8HeadService/Program.cs b/Magic8HeadService/Program.cs index d5ee8d5..b45d9b2 100644 --- a/Magic8HeadService/Program.cs +++ b/Magic8HeadService/Program.cs @@ -102,6 +102,7 @@ public static IHostBuilder CreateHostBuilder(string[] args) => services.AddScoped(); services.AddScoped(); services.AddScoped(); + services.AddScoped(); services.AddHostedService(); diff --git a/Magic8HeadService/Services/CoolDownService.cs b/Magic8HeadService/Services/CoolDownService.cs index 31c42b3..0c178e7 100644 --- a/Magic8HeadService/Services/CoolDownService.cs +++ b/Magic8HeadService/Services/CoolDownService.cs @@ -6,7 +6,7 @@ namespace Magic8HeadService.Services { - internal class CoolDownService + public class CoolDownService { } } diff --git a/Magic8HeadService/TwitchBot.cs b/Magic8HeadService/TwitchBot.cs index 930cab1..2dce1b8 100644 --- a/Magic8HeadService/TwitchBot.cs +++ b/Magic8HeadService/TwitchBot.cs @@ -1,4 +1,5 @@ using Magic8HeadService.MqttHandlers; +using Magic8HeadService.Services; using Microsoft.Extensions.Logging; using MQTTnet; using MQTTnet.Client; @@ -29,11 +30,12 @@ public class TwitchBot private readonly ISayingResponse sayingResponse; private readonly IDadJokeService dadJokeService; private readonly IMessageStackService messageStackService; + private readonly CoolDownService coolDownService; public TwitchBot(ITwitchClient client, ConnectionCredentials clientCredentials, TwitchBotConfiguration twitchBotConfiguration, ISayingResponse sayingResponse, IDadJokeService dadJokeService, IEnumerable listOfCommands, ICommandMbhTwitchHelp helpCommand, MqttFactory mqttFactory, IEnumerable mqttHandlers, - IMessageStackService messageStackService, ILogger logger) + IMessageStackService messageStackService, CoolDownService coolDownService, ILogger logger) { this.client = client; @@ -42,6 +44,7 @@ public TwitchBot(ITwitchClient client, ConnectionCredentials clientCredentials, this.sayingResponse = sayingResponse; this.dadJokeService = dadJokeService; this.messageStackService = messageStackService; + this.coolDownService = coolDownService; var listOfNames = listOfCommands.Select(x => x.Name); this.logger.LogInformation($"-------------- List of Names : {string.Join(',', listOfNames)}"); dictOfCommands = listOfCommands diff --git a/Magic8HeadService/Worker.cs b/Magic8HeadService/Worker.cs index b916fd8..54cd8e5 100644 --- a/Magic8HeadService/Worker.cs +++ b/Magic8HeadService/Worker.cs @@ -1,4 +1,5 @@ using Magic8HeadService.MqttHandlers; +using Magic8HeadService.Services; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Hosting; @@ -29,6 +30,7 @@ public class Worker : BackgroundService readonly IDadJokeService scopedDadJokeService; readonly MqttFactory scopedMqttFactory; readonly IMessageStackService scopedMessageStackService; + readonly CoolDownService scopedCoolDownService; public Worker(IServiceProvider service, IConfiguration config, TwitchBotConfiguration twitchBotConfiguration, ILogger logger) @@ -63,6 +65,10 @@ public Worker(IServiceProvider service, IConfiguration config, TwitchBotConfigur scope.ServiceProvider .GetRequiredService(); + scopedCoolDownService = + scope.ServiceProvider + .GetRequiredService(); + var listOfCommands = scope.ServiceProvider.GetServices(); var helpCommand = scope.ServiceProvider.GetService(); var mqttHandlers = scope.ServiceProvider.GetServices(); @@ -70,7 +76,7 @@ public Worker(IServiceProvider service, IConfiguration config, TwitchBotConfigur var twitchBot = new TwitchBot(twitchClient, connectionCredentials, twitchBotConfiguration, scopedSayingResponse, scopedDadJokeService, listOfCommands, helpCommand, scopedMqttFactory, mqttHandlers, scopedMessageStackService, - logger); + scopedCoolDownService, logger); SetupGPIO(); } From c65269c11dc93188ee71a4aa6af06e1e4952a3bc Mon Sep 17 00:00:00 2001 From: Harold Pulcher Date: Mon, 17 Jun 2024 20:45:51 -0500 Subject: [PATCH 4/8] got tests added back into the project and pass --- MrBigHead.sln | 6 ++++++ .../Magic8HeadServiceTests.csproj | 17 ++++++++++------- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/MrBigHead.sln b/MrBigHead.sln index 1dfc26e..361f390 100644 --- a/MrBigHead.sln +++ b/MrBigHead.sln @@ -22,6 +22,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MrBigHead.Services", "MrBig EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MrBigHead.VoiceChecker", "MrBigHead.VoiceChecker\MrBigHead.VoiceChecker.csproj", "{8DDE5BFD-B979-450A-9CDE-9D4BF0BBCF96}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Magic8HeadServiceTests", "Tests\Magic8HeadServiceTests\Magic8HeadServiceTests.csproj", "{18942CBD-9D97-4C76-B7AA-4E3B0B2018B9}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -52,6 +54,10 @@ Global {8DDE5BFD-B979-450A-9CDE-9D4BF0BBCF96}.Debug|Any CPU.Build.0 = Debug|Any CPU {8DDE5BFD-B979-450A-9CDE-9D4BF0BBCF96}.Release|Any CPU.ActiveCfg = Release|Any CPU {8DDE5BFD-B979-450A-9CDE-9D4BF0BBCF96}.Release|Any CPU.Build.0 = Release|Any CPU + {18942CBD-9D97-4C76-B7AA-4E3B0B2018B9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {18942CBD-9D97-4C76-B7AA-4E3B0B2018B9}.Debug|Any CPU.Build.0 = Debug|Any CPU + {18942CBD-9D97-4C76-B7AA-4E3B0B2018B9}.Release|Any CPU.ActiveCfg = Release|Any CPU + {18942CBD-9D97-4C76-B7AA-4E3B0B2018B9}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/Tests/Magic8HeadServiceTests/Magic8HeadServiceTests.csproj b/Tests/Magic8HeadServiceTests/Magic8HeadServiceTests.csproj index 24e7003..8c59868 100644 --- a/Tests/Magic8HeadServiceTests/Magic8HeadServiceTests.csproj +++ b/Tests/Magic8HeadServiceTests/Magic8HeadServiceTests.csproj @@ -1,19 +1,22 @@ - net6.0 + net8.0 enable false - - - - - - + + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + From ada75862edbee7a9c3524bef8c0b848e89a0e5ae Mon Sep 17 00:00:00 2001 From: Harold Pulcher Date: Mon, 17 Jun 2024 22:32:56 -0500 Subject: [PATCH 5/8] Adding in options for the configuration of cool downs for commands --- Magic8HeadService/Services/CoolDownOptions.cs | 8 +++ Magic8HeadService/Services/CoolDownService.cs | 30 +++++++- .../Commands/CoolDownServiceTests.cs | 72 +++++++++++++++++++ .../Magic8HeadServiceTests.csproj | 2 + Tests/Magic8HeadServiceTests/UnitTest1.cs | 12 ---- 5 files changed, 111 insertions(+), 13 deletions(-) create mode 100644 Magic8HeadService/Services/CoolDownOptions.cs create mode 100644 Tests/Magic8HeadServiceTests/Commands/CoolDownServiceTests.cs delete mode 100644 Tests/Magic8HeadServiceTests/UnitTest1.cs diff --git a/Magic8HeadService/Services/CoolDownOptions.cs b/Magic8HeadService/Services/CoolDownOptions.cs new file mode 100644 index 0000000..dfb0ce2 --- /dev/null +++ b/Magic8HeadService/Services/CoolDownOptions.cs @@ -0,0 +1,8 @@ +using Microsoft.Extensions.Options; + +namespace Magic8HeadService.Services +{ + public class CoolDownOptions + { + } +} \ No newline at end of file diff --git a/Magic8HeadService/Services/CoolDownService.cs b/Magic8HeadService/Services/CoolDownService.cs index 0c178e7..c23ac85 100644 --- a/Magic8HeadService/Services/CoolDownService.cs +++ b/Magic8HeadService/Services/CoolDownService.cs @@ -1,5 +1,7 @@ -using System; +using Microsoft.Extensions.Options; +using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -8,5 +10,31 @@ namespace Magic8HeadService.Services { public class CoolDownService { + private Dictionary CurrentCoolsDowns + = new Dictionary(); + private IOptionsSnapshot options; + + public CoolDownService(IOptionsSnapshot options) + { + this.options = options; + } + + public void Execute(string commandString) + { + if (CurrentCoolsDowns.ContainsKey(commandString)) + { + CurrentCoolsDowns[commandString] = DateTime.Now; + } + else + { + CurrentCoolsDowns.Add(commandString, DateTime.Now); + } + } + + public ReadOnlyDictionary GetAllCoolDowns() + { + var readOnlyCurrentCurrentCoolDowns = new ReadOnlyDictionary(CurrentCoolsDowns); + return readOnlyCurrentCurrentCoolDowns; + } } } diff --git a/Tests/Magic8HeadServiceTests/Commands/CoolDownServiceTests.cs b/Tests/Magic8HeadServiceTests/Commands/CoolDownServiceTests.cs new file mode 100644 index 0000000..416ae7e --- /dev/null +++ b/Tests/Magic8HeadServiceTests/Commands/CoolDownServiceTests.cs @@ -0,0 +1,72 @@ +using FluentAssertions; +using Magic8HeadService.Services; +using Microsoft.Extensions.Options; +using Microsoft.VisualStudio.TestTools.UnitTesting; +using NSubstitute; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Magic8HeadServiceTests +{ + [TestClass] + public class CoolDownServiceTests + { + private IOptionsSnapshot optionsSnapshot + = Substitute.For>(); + + [TestMethod] + public void CanInstance() + { + var cot = new CoolDownService(optionsSnapshot); + + cot.Should().NotBeNull(); + } + + [TestMethod] + public void GivenCommandExecutionWhenExcutedSetsCoolDown() + { + var cot = new CoolDownService(optionsSnapshot); + + cot.Execute("dad"); + + var results = cot.GetAllCoolDowns(); + + results.Should().NotBeNull(); + results.Should().HaveCount(1); + results.Keys.Should().Contain("dad"); + } + + [TestMethod] + public void GivenCommandExecutionWhenExcutedMultipleTimesSetsCoolDown() + { + var cot = new CoolDownService(optionsSnapshot); + + cot.Execute("dad"); + cot.Execute("dad"); + + var results = cot.GetAllCoolDowns(); + + results.Should().NotBeNull(); + results.Should().HaveCount(1); + results.Keys.Should().Contain("dad"); + } + + [TestMethod] + public void GivenCommandExecutionWhenExecutedThenCoolDownHasExpectedTime() + { + optionsSnapshot.Value.Returns(new CoolDownOptions { /* set your properties here */ }); + var cot = new CoolDownService(optionsSnapshot); + + cot.Execute("dad"); + + var results = cot.GetAllCoolDowns(); + + results.Should().NotBeNull(); + results.Keys.Should().Contain("dad"); + results["dad"].Should().Be(DateTime.Now); + } + } +} diff --git a/Tests/Magic8HeadServiceTests/Magic8HeadServiceTests.csproj b/Tests/Magic8HeadServiceTests/Magic8HeadServiceTests.csproj index 8c59868..9a4ef40 100644 --- a/Tests/Magic8HeadServiceTests/Magic8HeadServiceTests.csproj +++ b/Tests/Magic8HeadServiceTests/Magic8HeadServiceTests.csproj @@ -9,6 +9,7 @@ + @@ -16,6 +17,7 @@ all runtime; build; native; contentfiles; analyzers; buildtransitive + diff --git a/Tests/Magic8HeadServiceTests/UnitTest1.cs b/Tests/Magic8HeadServiceTests/UnitTest1.cs deleted file mode 100644 index b371a87..0000000 --- a/Tests/Magic8HeadServiceTests/UnitTest1.cs +++ /dev/null @@ -1,12 +0,0 @@ -using Microsoft.VisualStudio.TestTools.UnitTesting; - -namespace Magic8HeadServiceTests; - -[TestClass] -public class UnitTest1 -{ - [TestMethod] - public void TestMethod1() - { - } -} From e899dca940136916e8a6ce4bd9075cc56c2274b8 Mon Sep 17 00:00:00 2001 From: Harold Pulcher Date: Mon, 24 Jun 2024 22:45:25 -0500 Subject: [PATCH 6/8] added a getcooldown for a specific command --- Magic8HeadService/Commands/DadCommand.cs | 7 +- Magic8HeadService/Services/CoolDownOptions.cs | 6 +- Magic8HeadService/Services/CoolDownService.cs | 24 +++++-- .../Commands/CoolDownServiceTests.cs | 70 ++++++++++++++++--- 4 files changed, 87 insertions(+), 20 deletions(-) diff --git a/Magic8HeadService/Commands/DadCommand.cs b/Magic8HeadService/Commands/DadCommand.cs index aa10034..c654e12 100644 --- a/Magic8HeadService/Commands/DadCommand.cs +++ b/Magic8HeadService/Commands/DadCommand.cs @@ -13,6 +13,7 @@ internal class DadCommand : IMbhCommand private ITwitchClient client; private ISayingResponse sayingResponse; private readonly IDadJokeService dadJokeService; + private readonly CoolDownService coolDownService; private TimeSpan coolDownTimeSpan = TimeSpan.FromSeconds(15); private DateTime coolDown = DateTime.MinValue; private ILogger logger; @@ -24,8 +25,8 @@ public DadCommand(ITwitchClient client, ISayingResponse sayingResponse, IDadJoke this.client = client; this.sayingResponse = sayingResponse; this.dadJokeService = dadJokeService; + this.coolDownService = coolDownService; this.logger = logger; - this.coolDown = coolDown; } public void Handle(OnChatCommandReceivedArgs cmd) @@ -49,7 +50,9 @@ public void Handle(OnChatCommandReceivedArgs cmd) public bool CanExecute() { var currentTime = DateTime.UtcNow; - if ( currentTime < coolDown ) + var currentCoolDown = coolDownService.GetCurrentCoolDown("dad"); + + if (currentTime < currentCoolDown) { return false; } diff --git a/Magic8HeadService/Services/CoolDownOptions.cs b/Magic8HeadService/Services/CoolDownOptions.cs index dfb0ce2..d66087d 100644 --- a/Magic8HeadService/Services/CoolDownOptions.cs +++ b/Magic8HeadService/Services/CoolDownOptions.cs @@ -1,8 +1,10 @@ -using Microsoft.Extensions.Options; +using System; +using System.Collections.Generic; namespace Magic8HeadService.Services { public class CoolDownOptions { + public Dictionary Options { get; set; } } -} \ No newline at end of file +} diff --git a/Magic8HeadService/Services/CoolDownService.cs b/Magic8HeadService/Services/CoolDownService.cs index c23ac85..c560dff 100644 --- a/Magic8HeadService/Services/CoolDownService.cs +++ b/Magic8HeadService/Services/CoolDownService.cs @@ -12,23 +12,35 @@ public class CoolDownService { private Dictionary CurrentCoolsDowns = new Dictionary(); - private IOptionsSnapshot options; + private IOptions options; - public CoolDownService(IOptionsSnapshot options) + public CoolDownService(IOptions options) { this.options = options; } - public void Execute(string commandString) + public DateTime Execute(string commandString) { - if (CurrentCoolsDowns.ContainsKey(commandString)) + var nextExecutionTime = DateTime.UtcNow.AddSeconds(options.Value.Options[commandString]); + + if (CurrentCoolsDowns.TryGetValue(commandString, out DateTime coolDownDateTime)) { - CurrentCoolsDowns[commandString] = DateTime.Now; + if (DateTime.UtcNow > coolDownDateTime) + { + CurrentCoolsDowns[commandString] + = nextExecutionTime; + } + else + { + return coolDownDateTime; + } } else { - CurrentCoolsDowns.Add(commandString, DateTime.Now); + CurrentCoolsDowns.Add(commandString, nextExecutionTime); } + + return nextExecutionTime; } public ReadOnlyDictionary GetAllCoolDowns() diff --git a/Tests/Magic8HeadServiceTests/Commands/CoolDownServiceTests.cs b/Tests/Magic8HeadServiceTests/Commands/CoolDownServiceTests.cs index 416ae7e..6e64b64 100644 --- a/Tests/Magic8HeadServiceTests/Commands/CoolDownServiceTests.cs +++ b/Tests/Magic8HeadServiceTests/Commands/CoolDownServiceTests.cs @@ -1,4 +1,5 @@ using FluentAssertions; +using FluentAssertions.Extensions; using Magic8HeadService.Services; using Microsoft.Extensions.Options; using Microsoft.VisualStudio.TestTools.UnitTesting; @@ -14,13 +15,13 @@ namespace Magic8HeadServiceTests [TestClass] public class CoolDownServiceTests { - private IOptionsSnapshot optionsSnapshot - = Substitute.For>(); + private IOptions options + = Substitute.For>(); [TestMethod] public void CanInstance() { - var cot = new CoolDownService(optionsSnapshot); + var cot = new CoolDownService(options); cot.Should().NotBeNull(); } @@ -28,7 +29,8 @@ public void CanInstance() [TestMethod] public void GivenCommandExecutionWhenExcutedSetsCoolDown() { - var cot = new CoolDownService(optionsSnapshot); + options.Value.Returns(SetupOptions(2000)); + var cot = new CoolDownService(options); cot.Execute("dad"); @@ -42,7 +44,8 @@ public void GivenCommandExecutionWhenExcutedSetsCoolDown() [TestMethod] public void GivenCommandExecutionWhenExcutedMultipleTimesSetsCoolDown() { - var cot = new CoolDownService(optionsSnapshot); + options.Value.Returns(SetupOptions(2000)); + var cot = new CoolDownService(options); cot.Execute("dad"); cot.Execute("dad"); @@ -57,16 +60,63 @@ public void GivenCommandExecutionWhenExcutedMultipleTimesSetsCoolDown() [TestMethod] public void GivenCommandExecutionWhenExecutedThenCoolDownHasExpectedTime() { - optionsSnapshot.Value.Returns(new CoolDownOptions { /* set your properties here */ }); - var cot = new CoolDownService(optionsSnapshot); + options.Value.Returns(SetupOptions(2000)); + var cot = new CoolDownService(options); + + var expectedDateTime = cot.Execute("dad"); + + var results = cot.GetAllCoolDowns(); + + results.Should().NotBeNull() + .And.ContainKey("dad"); + + var diffDate = results["dad"] - expectedDateTime; + diffDate.Should().BeLessThan(1.Seconds()); + } + + [TestMethod] + public void GivenCommandExecutionWhenExecutedThenCoolDownDoesNotHaveUnexpectedKey() + { + options.Value.Returns(SetupOptions(2000)); + var cot = new CoolDownService(options); + + var expectedDateTime = cot.Execute("dad"); + + var results = cot.GetAllCoolDowns(); + + results.Should().NotContainKey("dad2"); + } + + [TestMethod] + public void GivenCommandExecutionTwiceWhenExecutedThenCoolDownsContainsCorrectEntry() + { + options.Value.Returns(SetupOptions(2000)); + var cot = new CoolDownService(options); + + var expectedDateTime = cot.Execute("dad"); cot.Execute("dad"); var results = cot.GetAllCoolDowns(); - results.Should().NotBeNull(); - results.Keys.Should().Contain("dad"); - results["dad"].Should().Be(DateTime.Now); + results.Should().NotBeNull() + .And.ContainKey("dad"); + + var diffDate = results["dad"] - expectedDateTime; + diffDate.Should().BeLessThan(1.Seconds()); + } + + private CoolDownOptions SetupOptions(int delay) + { + var newOptions = new Dictionary + { + { "dad", delay} + }; + + return new CoolDownOptions + { + Options = newOptions + }; } } } From 5c974973784a9a3fec713a99dc7df5d9529b1c76 Mon Sep 17 00:00:00 2001 From: Harold Pulcher Date: Mon, 1 Jul 2024 22:14:05 -0500 Subject: [PATCH 7/8] closer, but need to Figure more on IOptions --- Magic8HeadService/Program.cs | 8 +++++-- Magic8HeadService/Services/CoolDownService.cs | 14 +++++++++-- .../Commands/CoolDownServiceTests.cs | 24 +++++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) diff --git a/Magic8HeadService/Program.cs b/Magic8HeadService/Program.cs index b45d9b2..7234dce 100644 --- a/Magic8HeadService/Program.cs +++ b/Magic8HeadService/Program.cs @@ -44,12 +44,16 @@ public static IHostBuilder CreateHostBuilder(string[] args) => var configuration = services.BuildServiceProvider().GetService(); // probably could convert this into a bind and only need to pass around this object - // well, I believe Huga may have a better idea. :) aka IOptions + // well, I believe Hugo may have a better idea. :) aka IOptions var twitchBotConfiguration = new TwitchBotConfiguration(); configuration.GetSection("TwitchBotConfiguration").Bind(twitchBotConfiguration); - services.AddSingleton(twitchBotConfiguration); + var coolDownOptions = new CoolDownOptions(); + configuration.GetSection("CoolDownOptions").Bind(coolDownOptions); + services.AddSingleton(coolDownOptions); + + var credentials = new ConnectionCredentials(twitchBotConfiguration.UserName, twitchBotConfiguration.AccessToken); services.AddSingleton(credentials); diff --git a/Magic8HeadService/Services/CoolDownService.cs b/Magic8HeadService/Services/CoolDownService.cs index c560dff..fce29a8 100644 --- a/Magic8HeadService/Services/CoolDownService.cs +++ b/Magic8HeadService/Services/CoolDownService.cs @@ -10,7 +10,7 @@ namespace Magic8HeadService.Services { public class CoolDownService { - private Dictionary CurrentCoolsDowns + private Dictionary CurrentCoolsDowns = new Dictionary(); private IOptions options; @@ -25,7 +25,7 @@ public DateTime Execute(string commandString) if (CurrentCoolsDowns.TryGetValue(commandString, out DateTime coolDownDateTime)) { - if (DateTime.UtcNow > coolDownDateTime) + if (DateTime.UtcNow > coolDownDateTime) { CurrentCoolsDowns[commandString] = nextExecutionTime; @@ -48,5 +48,15 @@ public ReadOnlyDictionary GetAllCoolDowns() var readOnlyCurrentCurrentCoolDowns = new ReadOnlyDictionary(CurrentCoolsDowns); return readOnlyCurrentCurrentCoolDowns; } + + public DateTime GetCurrentCoolDown(string commandString) + { + if (CurrentCoolsDowns.TryGetValue(commandString, out DateTime coolDownDateTime)) + { + return coolDownDateTime; + } + + return DateTime.MinValue; + } } } diff --git a/Tests/Magic8HeadServiceTests/Commands/CoolDownServiceTests.cs b/Tests/Magic8HeadServiceTests/Commands/CoolDownServiceTests.cs index 6e64b64..070c889 100644 --- a/Tests/Magic8HeadServiceTests/Commands/CoolDownServiceTests.cs +++ b/Tests/Magic8HeadServiceTests/Commands/CoolDownServiceTests.cs @@ -106,6 +106,30 @@ public void GivenCommandExecutionTwiceWhenExecutedThenCoolDownsContainsCorrectEn diffDate.Should().BeLessThan(1.Seconds()); } + [TestMethod] + public void GivenEmptyConfigurationWhenGetCurrentCoolDownMinDateTimeIsReturned() + { + options.Value.Returns(SetupOptions(2000)); + var cot = new CoolDownService(options); + + var nextExecution = cot.GetCurrentCoolDown("dad2"); + + nextExecution.Should().Be(DateTime.MinValue); + } + + [TestMethod] + public void GivenConfigurationWhenGetCurrentCoolDownExpectedDateTimeIsReturned() + { + options.Value.Returns(SetupOptions(2000)); + var cot = new CoolDownService(options); + + var expectedDateTime = cot.Execute("dad"); + + var nextExecution = cot.GetCurrentCoolDown("dad"); + + nextExecution.Should().Be(expectedDateTime); + } + private CoolDownOptions SetupOptions(int delay) { var newOptions = new Dictionary From 2ecaa5f1d788ae02ca4df60c239e3181062785d4 Mon Sep 17 00:00:00 2001 From: Harold Pulcher Date: Mon, 8 Jul 2024 21:42:17 -0500 Subject: [PATCH 8/8] Seems to be working --- Magic8HeadService/Commands/DadCommand.cs | 4 +++- Magic8HeadService/Program.cs | 7 ++++--- Magic8HeadService/Services/CoolDownOptions.cs | 3 ++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/Magic8HeadService/Commands/DadCommand.cs b/Magic8HeadService/Commands/DadCommand.cs index c654e12..c36f96e 100644 --- a/Magic8HeadService/Commands/DadCommand.cs +++ b/Magic8HeadService/Commands/DadCommand.cs @@ -40,6 +40,8 @@ public void Handle(OnChatCommandReceivedArgs cmd) sayingResponse.SaySomethingNiceAsync(dadJoke, client, cmd.Command.ChatMessage.Channel, cmd.Command.ChatMessage.Username); client.SendMessage(cmd.Command.ChatMessage.Channel, $"Q: {dadJoke}"); + + coolDownService.Execute(AvailableCommands.Dad); } else { @@ -50,7 +52,7 @@ public void Handle(OnChatCommandReceivedArgs cmd) public bool CanExecute() { var currentTime = DateTime.UtcNow; - var currentCoolDown = coolDownService.GetCurrentCoolDown("dad"); + var currentCoolDown = coolDownService.GetCurrentCoolDown(AvailableCommands.Dad); if (currentTime < currentCoolDown) { diff --git a/Magic8HeadService/Program.cs b/Magic8HeadService/Program.cs index 7234dce..47cdecd 100644 --- a/Magic8HeadService/Program.cs +++ b/Magic8HeadService/Program.cs @@ -49,10 +49,11 @@ public static IHostBuilder CreateHostBuilder(string[] args) => configuration.GetSection("TwitchBotConfiguration").Bind(twitchBotConfiguration); services.AddSingleton(twitchBotConfiguration); - var coolDownOptions = new CoolDownOptions(); - configuration.GetSection("CoolDownOptions").Bind(coolDownOptions); - services.AddSingleton(coolDownOptions); + //var coolDownOptions = new CoolDownOptions(); + //configuration.GetSection("CoolDownOptions").Bind(coolDownOptions); + //services.AddSingleton(coolDownOptions); + services.Configure(configuration.GetSection("CoolDownOptions")); var credentials = new ConnectionCredentials(twitchBotConfiguration.UserName, twitchBotConfiguration.AccessToken); services.AddSingleton(credentials); diff --git a/Magic8HeadService/Services/CoolDownOptions.cs b/Magic8HeadService/Services/CoolDownOptions.cs index d66087d..e077488 100644 --- a/Magic8HeadService/Services/CoolDownOptions.cs +++ b/Magic8HeadService/Services/CoolDownOptions.cs @@ -1,4 +1,5 @@ -using System; +using Microsoft.Extensions.Options; +using System; using System.Collections.Generic; namespace Magic8HeadService.Services