From 6145d2316db1b1bc807c370a7c025cfb7b905650 Mon Sep 17 00:00:00 2001 From: "Mark Fischer, Jr" Date: Fri, 30 May 2025 22:23:47 -0400 Subject: [PATCH 1/6] Generating stock charts using ScottPlot instead of using the Image Charts API. --- .../FischBot.UnitTests.csproj | 2 +- src/FischBot/FischBot.csproj | 29 ++--- src/FischBot/Handlers/InteractionHandler.cs | 19 +-- src/FischBot/Modules/StocksModule.cs | 116 +++++++++++------- .../ImageChartService/IImageChartService.cs | 6 +- .../ImageChartService/ImageChartService.cs | 75 ++++++++--- 6 files changed, 160 insertions(+), 87 deletions(-) diff --git a/src/FischBot.UnitTests/FischBot.UnitTests.csproj b/src/FischBot.UnitTests/FischBot.UnitTests.csproj index 8317358..feffd2d 100644 --- a/src/FischBot.UnitTests/FischBot.UnitTests.csproj +++ b/src/FischBot.UnitTests/FischBot.UnitTests.csproj @@ -1,7 +1,7 @@ - net6.0 + net9.0 false diff --git a/src/FischBot/FischBot.csproj b/src/FischBot/FischBot.csproj index a80e528..d33bb86 100644 --- a/src/FischBot/FischBot.csproj +++ b/src/FischBot/FischBot.csproj @@ -1,24 +1,25 @@ Exe - net6.0 + net9.0 0.4.5 0.4-dragonfish-rev5 false - - - - - - - - - - - - - + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/FischBot/Handlers/InteractionHandler.cs b/src/FischBot/Handlers/InteractionHandler.cs index 6039f4e..109dde5 100644 --- a/src/FischBot/Handlers/InteractionHandler.cs +++ b/src/FischBot/Handlers/InteractionHandler.cs @@ -19,7 +19,7 @@ public class InteractionHandler private readonly ILogger _logger; private readonly IConfiguration _configuration; - public InteractionHandler(IConfiguration configuration, DiscordSocketClient discordClient, InteractionService commands, IServiceProvider services, ILogger logger) + public InteractionHandler(IConfiguration configuration, DiscordSocketClient discordClient, InteractionService commands, IServiceProvider services, ILogger logger) { _discordClient = discordClient; _commands = commands; @@ -27,8 +27,8 @@ public InteractionHandler(IConfiguration configuration, DiscordSocketClient disc _logger = logger; _configuration = configuration; } - - public async Task InitializeAsync() + + public async Task InitializeAsync() { await _commands.AddModulesAsync(Assembly.GetEntryAssembly(), _services); @@ -41,7 +41,7 @@ public async Task InitializeAsync() _discordClient.Ready += async () => { // If running the bot with DEBUG flag, register all commands to guild specified in config - if (IsDebug()) + if (IsDebug()) { var testGuildId = _configuration.GetValue("FischBot:testGuildId"); @@ -51,7 +51,7 @@ public async Task InitializeAsync() Console.WriteLine($"Registered the following interaction commands: {string.Join(',', registeredCommands.Select(command => command.Name))}"); } - else + else { await _services .GetRequiredService() @@ -60,11 +60,11 @@ await _services }; } - private async Task HandleInteraction(SocketInteraction interaction) + private async Task HandleInteraction(SocketInteraction interaction) { var context = new SocketInteractionContext(_discordClient, interaction); - try + try { await _commands.ExecuteCommandAsync(context, _services); } @@ -112,7 +112,10 @@ private async Task SlashCommandExecuted(SlashCommandInfo command, Discord.IInter else { _logger.LogError($"Slash command failed to execute for [{context.User.Username}] <-> [{result}]!"); - await context.Interaction.RespondAsync($"Sorry, {context.User.Username}... something went wrong -> [{result}]!", ephemeral: true); + if (context.Interaction.HasResponded) + await context.Interaction.RespondAsync($"Sorry, {context.User.Username}... something went wrong -> [{result}]!", ephemeral: true); + else + await context.Interaction.FollowupAsync($"Sorry, {context.User.Username}... something went wrong -> [{result}]!", ephemeral: true); } } diff --git a/src/FischBot/Modules/StocksModule.cs b/src/FischBot/Modules/StocksModule.cs index 447226f..3eee604 100644 --- a/src/FischBot/Modules/StocksModule.cs +++ b/src/FischBot/Modules/StocksModule.cs @@ -6,6 +6,8 @@ using System.Linq; using FischBot.Services.ImageChartService; using Discord.Interactions; +using System.Collections.Generic; +using FischBot.Models.Finance; namespace FischBot.Modules { @@ -19,6 +21,7 @@ public enum TimePeriod { Week, Month, + SixMonths, Year } @@ -66,59 +69,86 @@ public async Task DisplayRealtimeStockInfo([Summary(description: "Stock to get i } [SlashCommand("chart", "Displays a chart for the specified stock.")] - public async Task DisplayStockChart([Summary(description: "Stock symbol")] string symbol, [Summary(description: "Time period to display for (optional)")] TimePeriod period = TimePeriod.Week) + public async Task DisplayStockChart([Summary(description: "Stock symbol")] string symbol, + [Summary(description: "Time period to display for (optional)")] TimePeriod period = TimePeriod.Month) { - var dataset = await GetDataSet(symbol, period); - var lineColor = dataset.First() < dataset.Last() ? "2ECC71" : "E74C3C"; + var timeSeriesValues = await GetTimeSeriesValues(symbol, period); - var chartImage = _imageChartService.CreateLineChart( - dataset, - lineColor, - 500, - 100); + var span = period switch + { + TimePeriod.Week => TimeSpan.FromDays(7), + TimePeriod.Month => TimeSpan.FromDays(30), + TimePeriod.SixMonths => TimeSpan.FromDays(180), + TimePeriod.Year => TimeSpan.FromDays(365), + _ => throw new NotImplementedException() + }; + + var showYearInXAxis = period == TimePeriod.Year || period == TimePeriod.SixMonths; + + var chartImageStream = _imageChartService.CreateStockChart( + timeSeriesValues, + span, + showYearInXAxis); - await RespondWithFileAsync(chartImage, "chart.png"); + await RespondWithFileAsync(chartImageStream, "chart.png"); } - private async Task GetDataSet(string symbol, TimePeriod period) + + private async Task> GetTimeSeriesValues(string symbol, TimePeriod period) { - if (period == TimePeriod.Week) + switch (period) { - var timeSeries = await _financeService.GetTimeSeries(symbol, "2h"); - - return timeSeries.Values - .Where(value => value.Datetime > DateTime.Now.AddDays(-7)) - .OrderBy(value => value.Datetime) - .Select(value => value.Open) - .Take(7) - .ToArray(); - } + case TimePeriod.Week: + { + var timeSeries = await _financeService.GetTimeSeries(symbol, "1h"); - if (period == TimePeriod.Month) - { - var timeSeries = await _financeService.GetTimeSeries(symbol, "1day"); - - return timeSeries.Values - .Where(value => value.Datetime > DateTime.Now.AddMonths(-1)) - .OrderBy(value => value.Datetime) - .Select(value => value.Open) - .Take(7) - .ToArray(); - } + var values = timeSeries.Values + .Where(value => value.Datetime > DateTime.Now.AddDays(-7)) + .OrderBy(value => value.Datetime.DateTime) + .ToList(); - if (period == TimePeriod.Year) - { - var timeSeries = await _financeService.GetTimeSeries(symbol, "1month"); - - return timeSeries.Values - .Where(value => value.Datetime > DateTime.Now.AddYears(-1)) - .OrderBy(value => value.Datetime) - .Select(value => value.Open) - .Take(7) - .ToArray(); - } + return values; + } + + case TimePeriod.Month: + { + var timeSeries = await _financeService.GetTimeSeries(symbol, "1day"); - throw new NotImplementedException(); + var values = timeSeries.Values + .Where(value => value.Datetime > DateTime.Now.AddDays(-30)) + .OrderBy(value => value.Datetime.DateTime) + .ToList(); + + return values; + } + + case TimePeriod.SixMonths: + { + var timeSeries = await _financeService.GetTimeSeries(symbol, "1week"); + + var values = timeSeries.Values + .Where(value => value.Datetime > DateTime.Now.AddYears(-1)) + .OrderBy(value => value.Datetime.DateTime) + .ToList(); + + return values; + } + + case TimePeriod.Year: + { + var timeSeries = await _financeService.GetTimeSeries(symbol, "1month"); + + var values = timeSeries.Values + .Where(value => value.Datetime > DateTime.Now.AddYears(-1)) + .OrderBy(value => value.Datetime.DateTime) + .ToList(); + + return values; + } + + default: + throw new NotImplementedException(); + } } } } \ No newline at end of file diff --git a/src/FischBot/Services/ImageChartService/IImageChartService.cs b/src/FischBot/Services/ImageChartService/IImageChartService.cs index dcc2d6b..932a465 100644 --- a/src/FischBot/Services/ImageChartService/IImageChartService.cs +++ b/src/FischBot/Services/ImageChartService/IImageChartService.cs @@ -1,9 +1,13 @@ +using System; +using System.Collections.Generic; using System.IO; +using System.Threading.Tasks; +using FischBot.Models.Finance; namespace FischBot.Services.ImageChartService { public interface IImageChartService { - Stream CreateLineChart(decimal[] data, string lineColor, int width, int height); + MemoryStream CreateStockChart(IEnumerable timeSeriesValues, TimeSpan span, bool showYearInXAxis); } } \ No newline at end of file diff --git a/src/FischBot/Services/ImageChartService/ImageChartService.cs b/src/FischBot/Services/ImageChartService/ImageChartService.cs index 4183dce..929de78 100644 --- a/src/FischBot/Services/ImageChartService/ImageChartService.cs +++ b/src/FischBot/Services/ImageChartService/ImageChartService.cs @@ -1,32 +1,67 @@ using System; +using System.Collections.Generic; using System.IO; using System.Linq; -using ImageChartsLib; +using System.Threading.Tasks; +using FischBot.Models.Finance; +using ScottPlot; namespace FischBot.Services.ImageChartService { public class ImageChartService : IImageChartService { - public Stream CreateLineChart(decimal[] data, string lineColor, int width, int height) + public MemoryStream CreateStockChart(IEnumerable timeSeriesValues, TimeSpan span, bool showYearInXAxis) { - var serializedData = $"a:{string.Join(',', data)}"; - var dataRange = $"0,{Math.Floor(data.Min())},{Math.Ceiling(data.Max())}"; - - var lineChart = new ImageCharts() - .cht("ls") - .chco(lineColor) - .chls("2") - .chf("bg,s,00000000") - .chs($"{width}x{height}") - .chxt("y") - .chxs("0N*cUSD2sz*,666666") - .chxr(dataRange) - .chd(serializedData); - - var buffer = lineChart.toBuffer(); - var stream = new MemoryStream(buffer); - - return stream; + var ohlcs = timeSeriesValues + .Select(price => new OHLC( + (double)price.Open, + (double)price.High, + (double)price.Low, + (double)price.Close, + price.Datetime.DateTime, + span)) + .ToList(); + + var plot = new Plot(); + + var candlePlot = plot.Add.Candlestick(ohlcs); + + // enable sequential mode to place candles at X = 0, 1, 2, ... + candlePlot.Sequential = true; + + // Since we are using sequential mode, we have to set the X axis manually. + ConfigureXAxisLabels(plot, ohlcs, showYearInXAxis); + + // Putting the Y axis on the right side and formatting it as currency + candlePlot.Axes.YAxis = plot.Axes.Right; + plot.Axes.Right.TickGenerator = new ScottPlot.TickGenerators.NumericAutomatic() + { + LabelFormatter = (double value) => value.ToString("C") + }; + + var chartImage = plot.GetImageBytes(800, 400, ImageFormat.Png); + return new MemoryStream(chartImage); + } + + private static void ConfigureXAxisLabels(Plot plot, List ohlcs, bool showYearInXAxis) + { + // determine a few candles to display ticks for + int tickCount = 5; + int tickDelta = ohlcs.Count / tickCount; + DateTime[] tickDates = ohlcs + .Where((x, i) => i % tickDelta == 0) + .Select(x => x.DateTime) + .ToArray(); + + // By default, horizontal tick labels will be numbers (1, 2, 3...) + // We can use a manual tick generator to display dates on the horizontal axis + double[] tickPositions = Generate.Consecutive(tickDates.Length, tickDelta); + + var dateFormat = showYearInXAxis ? "MM/dd/yyyy" : "MM/dd"; + string[] tickLabels = tickDates.Select(x => x.ToString(dateFormat)).ToArray(); + + ScottPlot.TickGenerators.NumericManual tickGen = new(tickPositions, tickLabels); + plot.Axes.Bottom.TickGenerator = tickGen; } } } \ No newline at end of file From d709e3c27380ea63fa065f628b93b55b6e7b63a3 Mon Sep 17 00:00:00 2001 From: "Mark Fischer, Jr" Date: Fri, 30 May 2025 22:25:11 -0400 Subject: [PATCH 2/6] Simplified stock price strings --- src/FischBot/Modules/StocksModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FischBot/Modules/StocksModule.cs b/src/FischBot/Modules/StocksModule.cs index 3eee604..830e7cd 100644 --- a/src/FischBot/Modules/StocksModule.cs +++ b/src/FischBot/Modules/StocksModule.cs @@ -47,13 +47,13 @@ public async Task DisplayRealtimeStockInfo([Summary(description: "Stock to get i .AddField( "Price", - $"{price.ToString("C")} {(quote.Change > 0 ? "▲" : "▼")}{quote.Change.ToString("C")} ({quote.PercentChange.ToString("F2")}%)" + $"{price:C} {(quote.Change > 0 ? "▲" : "▼")}{quote.Change:C} ({quote.PercentChange:F2}%)" ) .AddField("Trading info for last trading day", quote.Datetime.ToString("d")) - .AddField("Open/Close", $"{quote.Open.ToString("C")}/{quote.Close.ToString("C")}") - .AddField("High/Low", $"{quote.High.ToString("C")}/{quote.Low.ToString("C")}") + .AddField("Open/Close", $"{quote.Open:C}/{quote.Close:C}") + .AddField("High/Low", $"{quote.High:C}/{quote.Low:C}") .AddField("Volume", quote.Volume, inline: false) From b724d16d371b4d6a8176a594b6230ba23f3a8a83 Mon Sep 17 00:00:00 2001 From: "Mark Fischer, Jr" Date: Fri, 30 May 2025 22:27:19 -0400 Subject: [PATCH 3/6] simplified string interpolation for the cryptocurrency module --- src/FischBot/Modules/CryptocurrencyModule.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FischBot/Modules/CryptocurrencyModule.cs b/src/FischBot/Modules/CryptocurrencyModule.cs index c32c4b5..2f4df2d 100644 --- a/src/FischBot/Modules/CryptocurrencyModule.cs +++ b/src/FischBot/Modules/CryptocurrencyModule.cs @@ -33,13 +33,13 @@ public async Task DisplayRealtimeCryptoInfo([Summary(description: "Crypto symbol .AddField( "Price", - $"{price.ToString("C")} {(quote.Change > 0 ? "▲" : "▼")}{quote.Change.ToString("C")} ({quote.PercentChange.ToString("F2")}%)" + $"{price:C} {(quote.Change > 0 ? "▲" : "▼")}{quote.Change:C} ({quote.PercentChange:F2}%)" ) .AddField("Trading info for last trading day", quote.Datetime.ToString("d")) - .AddField("Open/Close", $"{quote.Open.ToString("C")}/{quote.Close.ToString("C")}") - .AddField("High/Low", $"{quote.High.ToString("C")}/{quote.Low.ToString("C")}") + .AddField("Open/Close", $"{quote.Open:C}/{quote.Close:C}") + .AddField("High/Low", $"{quote.High:C}/{quote.Low:C}") .WithFooter($"Source: twelvedata | Daily usage: {usageStats.daily_usage}/{usageStats.plan_daily_limit}") .Build(); From 59398e0bae70553c82d0f55adb515238576917c6 Mon Sep 17 00:00:00 2001 From: "Mark Fischer, Jr" Date: Fri, 30 May 2025 22:46:43 -0400 Subject: [PATCH 4/6] added an embed to the chart command as a caption for the chart image --- src/FischBot/Modules/StocksModule.cs | 79 ++++++++-------------------- 1 file changed, 21 insertions(+), 58 deletions(-) diff --git a/src/FischBot/Modules/StocksModule.cs b/src/FischBot/Modules/StocksModule.cs index 830e7cd..43d6c11 100644 --- a/src/FischBot/Modules/StocksModule.cs +++ b/src/FischBot/Modules/StocksModule.cs @@ -72,7 +72,14 @@ public async Task DisplayRealtimeStockInfo([Summary(description: "Stock to get i public async Task DisplayStockChart([Summary(description: "Stock symbol")] string symbol, [Summary(description: "Time period to display for (optional)")] TimePeriod period = TimePeriod.Month) { - var timeSeriesValues = await GetTimeSeriesValues(symbol, period); + var interval = period switch + { + TimePeriod.Week => "1h", + TimePeriod.Month => "1day", + TimePeriod.SixMonths => "1week", + TimePeriod.Year => "1month", + _ => throw new NotImplementedException() + }; var span = period switch { @@ -83,6 +90,11 @@ public async Task DisplayStockChart([Summary(description: "Stock symbol")] strin _ => throw new NotImplementedException() }; + var timeSeries = await _financeService.GetTimeSeries(symbol, interval); + var timeSeriesValues = timeSeries.Values + .OrderBy(value => value.Datetime.DateTime) + .ToList(); + var showYearInXAxis = period == TimePeriod.Year || period == TimePeriod.SixMonths; var chartImageStream = _imageChartService.CreateStockChart( @@ -90,65 +102,16 @@ public async Task DisplayStockChart([Summary(description: "Stock symbol")] strin span, showYearInXAxis); - await RespondWithFileAsync(chartImageStream, "chart.png"); - } - - - private async Task> GetTimeSeriesValues(string symbol, TimePeriod period) - { - switch (period) - { - case TimePeriod.Week: - { - var timeSeries = await _financeService.GetTimeSeries(symbol, "1h"); - - var values = timeSeries.Values - .Where(value => value.Datetime > DateTime.Now.AddDays(-7)) - .OrderBy(value => value.Datetime.DateTime) - .ToList(); + var usageStats = await _financeService.GetApiUsageStats(); - return values; - } + var embed = new EmbedBuilder() + .WithTitle($"{timeSeries.Symbol} Stock Chart") + .WithFooter($"Source: twelvedata | Daily usage: {usageStats.daily_usage}/{usageStats.plan_daily_limit}") + .Build(); - case TimePeriod.Month: - { - var timeSeries = await _financeService.GetTimeSeries(symbol, "1day"); - - var values = timeSeries.Values - .Where(value => value.Datetime > DateTime.Now.AddDays(-30)) - .OrderBy(value => value.Datetime.DateTime) - .ToList(); - - return values; - } - - case TimePeriod.SixMonths: - { - var timeSeries = await _financeService.GetTimeSeries(symbol, "1week"); - - var values = timeSeries.Values - .Where(value => value.Datetime > DateTime.Now.AddYears(-1)) - .OrderBy(value => value.Datetime.DateTime) - .ToList(); - - return values; - } - - case TimePeriod.Year: - { - var timeSeries = await _financeService.GetTimeSeries(symbol, "1month"); - - var values = timeSeries.Values - .Where(value => value.Datetime > DateTime.Now.AddYears(-1)) - .OrderBy(value => value.Datetime.DateTime) - .ToList(); - - return values; - } - - default: - throw new NotImplementedException(); - } + await RespondWithFileAsync(chartImageStream, + "chart.png", + embed: embed); } } } \ No newline at end of file From bc4c6b5e679958a3487515bed5c0bc974c8bb96d Mon Sep 17 00:00:00 2001 From: "Mark Fischer, Jr" Date: Fri, 30 May 2025 22:55:21 -0400 Subject: [PATCH 5/6] Tech Debt removal - removed dead dependency: ImageCharts - removed unused using statements --- src/FischBot.UnitTests/Modules/InfoModuleTests.cs | 2 -- .../CalendarificHolidaysApiClient.cs | 1 - src/FischBot/Api/DeepAiApiClient/IDeepAiApiClient.cs | 2 -- .../HalfStaffJsScraperClient/HalfStaffJsScraperClient.cs | 4 ---- src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Clouds.cs | 4 +--- .../Api/OpenWeatherMapApiClient/Dtos/Coordinates.cs | 4 +--- src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Main.cs | 4 +--- .../Dtos/OpenWeatherMapApiResponse.cs | 7 +------ .../Api/OpenWeatherMapApiClient/Dtos/Precipitation.cs | 4 +--- src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Sys.cs | 4 +--- src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Weather.cs | 4 +--- src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Wind.cs | 4 +--- src/FischBot/FischBot.csproj | 1 - src/FischBot/Handlers/CommandHandler.cs | 1 - src/FischBot/Models/Weather/CurrentWeather.cs | 6 +----- src/FischBot/Modules/HalfMastModule.cs | 3 --- src/FischBot/Modules/InfoModule.cs | 6 ++---- src/FischBot/Modules/StocksModule.cs | 3 --- src/FischBot/Program.cs | 1 - .../IArtificialIntelligenceService.cs | 2 -- src/FischBot/Services/HalfMastService/HalfMastService.cs | 3 --- .../Services/ImageChartService/IImageChartService.cs | 1 - .../Services/ImageChartService/ImageChartService.cs | 1 - src/FischBot/Services/LoggingService.cs | 1 - 24 files changed, 11 insertions(+), 62 deletions(-) diff --git a/src/FischBot.UnitTests/Modules/InfoModuleTests.cs b/src/FischBot.UnitTests/Modules/InfoModuleTests.cs index df40cc9..fdbe9b1 100644 --- a/src/FischBot.UnitTests/Modules/InfoModuleTests.cs +++ b/src/FischBot.UnitTests/Modules/InfoModuleTests.cs @@ -1,9 +1,7 @@ using System.Threading.Tasks; using Discord; -using Discord.Commands; using FischBot.Modules; using FischBot.Services.DiscordModuleService; -using Microsoft.Extensions.Configuration; using Microsoft.VisualStudio.TestTools.UnitTesting; using Moq; diff --git a/src/FischBot/Api/CalendarificHolidaysApiClient/CalendarificHolidaysApiClient.cs b/src/FischBot/Api/CalendarificHolidaysApiClient/CalendarificHolidaysApiClient.cs index f5b08bd..926c577 100644 --- a/src/FischBot/Api/CalendarificHolidaysApiClient/CalendarificHolidaysApiClient.cs +++ b/src/FischBot/Api/CalendarificHolidaysApiClient/CalendarificHolidaysApiClient.cs @@ -1,4 +1,3 @@ -using System; using System.Net.Http; using System.Threading.Tasks; using FischBot.Api.CalendarificHolidaysApiClient.Dtos; diff --git a/src/FischBot/Api/DeepAiApiClient/IDeepAiApiClient.cs b/src/FischBot/Api/DeepAiApiClient/IDeepAiApiClient.cs index d965640..4859db4 100644 --- a/src/FischBot/Api/DeepAiApiClient/IDeepAiApiClient.cs +++ b/src/FischBot/Api/DeepAiApiClient/IDeepAiApiClient.cs @@ -1,5 +1,3 @@ -using System; -using System.IO; using System.Threading.Tasks; using FischBot.Api.DeepAiApiClient.Dtos; diff --git a/src/FischBot/Api/HalfStaffJsScraperClient/HalfStaffJsScraperClient.cs b/src/FischBot/Api/HalfStaffJsScraperClient/HalfStaffJsScraperClient.cs index 546fd23..1afe250 100644 --- a/src/FischBot/Api/HalfStaffJsScraperClient/HalfStaffJsScraperClient.cs +++ b/src/FischBot/Api/HalfStaffJsScraperClient/HalfStaffJsScraperClient.cs @@ -1,11 +1,7 @@ -using System; using System.Net.Http; using System.Text.RegularExpressions; using System.Threading.Tasks; -using Discord; using FischBot.Api.HalfStaffJsScraperClient.Dtos; -using FischBot.Api.NasaApiClient.Dtos; -using Microsoft.Extensions.Configuration; namespace FischBot.Api.HalfStaffJsScraperClient { diff --git a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Clouds.cs b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Clouds.cs index adec13a..17552c1 100644 --- a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Clouds.cs +++ b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Clouds.cs @@ -1,6 +1,4 @@ -using System; -using System.Linq; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace FischBot.Api.OpenWeatherMapApiClient.Dtos { diff --git a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Coordinates.cs b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Coordinates.cs index fe06917..5a0cc6b 100644 --- a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Coordinates.cs +++ b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Coordinates.cs @@ -1,6 +1,4 @@ -using System; -using System.Linq; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace FischBot.Api.OpenWeatherMapApiClient.Dtos { diff --git a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Main.cs b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Main.cs index 30de395..856ea06 100644 --- a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Main.cs +++ b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Main.cs @@ -1,6 +1,4 @@ -using System; -using System.Linq; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace FischBot.Api.OpenWeatherMapApiClient.Dtos { diff --git a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/OpenWeatherMapApiResponse.cs b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/OpenWeatherMapApiResponse.cs index cd1b7bb..34d7c3d 100644 --- a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/OpenWeatherMapApiResponse.cs +++ b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/OpenWeatherMapApiResponse.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Text.Json.Serialization; -using System.Threading.Tasks; +using System.Text.Json.Serialization; namespace FischBot.Api.OpenWeatherMapApiClient.Dtos { diff --git a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Precipitation.cs b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Precipitation.cs index 1face02..437ae6c 100644 --- a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Precipitation.cs +++ b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Precipitation.cs @@ -1,6 +1,4 @@ -using System; -using System.Linq; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace FischBot.Api.OpenWeatherMapApiClient.Dtos { diff --git a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Sys.cs b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Sys.cs index e60216d..b5e3c96 100644 --- a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Sys.cs +++ b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Sys.cs @@ -1,6 +1,4 @@ -using System; -using System.Linq; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace FischBot.Api.OpenWeatherMapApiClient.Dtos { diff --git a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Weather.cs b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Weather.cs index fcb0943..d9d9dde 100644 --- a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Weather.cs +++ b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Weather.cs @@ -1,6 +1,4 @@ -using System; -using System.Linq; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace FischBot.Api.OpenWeatherMapApiClient.Dtos { diff --git a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Wind.cs b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Wind.cs index 74fac91..3bb738c 100644 --- a/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Wind.cs +++ b/src/FischBot/Api/OpenWeatherMapApiClient/Dtos/Wind.cs @@ -1,6 +1,4 @@ -using System; -using System.Linq; -using System.Text.Json.Serialization; +using System.Text.Json.Serialization; namespace FischBot.Api.OpenWeatherMapApiClient.Dtos { diff --git a/src/FischBot/FischBot.csproj b/src/FischBot/FischBot.csproj index d33bb86..88d9f31 100644 --- a/src/FischBot/FischBot.csproj +++ b/src/FischBot/FischBot.csproj @@ -9,7 +9,6 @@ - diff --git a/src/FischBot/Handlers/CommandHandler.cs b/src/FischBot/Handlers/CommandHandler.cs index e194d5d..412d44a 100644 --- a/src/FischBot/Handlers/CommandHandler.cs +++ b/src/FischBot/Handlers/CommandHandler.cs @@ -5,7 +5,6 @@ using Discord.Commands; using Discord.WebSocket; using Microsoft.Extensions.Configuration; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace FischBot.Handlers diff --git a/src/FischBot/Models/Weather/CurrentWeather.cs b/src/FischBot/Models/Weather/CurrentWeather.cs index 7d10e32..d8e966e 100644 --- a/src/FischBot/Models/Weather/CurrentWeather.cs +++ b/src/FischBot/Models/Weather/CurrentWeather.cs @@ -1,8 +1,4 @@ using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace FischBot.Models.Weather { @@ -11,7 +7,7 @@ public class CurrentWeather public string CityName { get; set; } public string CountryCode { get; set; } public string Location => $"{CityName}, {CountryCode}"; - public string WeatherIconUrl { get; set; } + public string WeatherIconUrl { get; set; } public string Weather { get; set; } public string WeatherDescription { get; set; } public DateTimeOffset DateCalculated { get; set; } diff --git a/src/FischBot/Modules/HalfMastModule.cs b/src/FischBot/Modules/HalfMastModule.cs index 7d3a500..e5b29d8 100644 --- a/src/FischBot/Modules/HalfMastModule.cs +++ b/src/FischBot/Modules/HalfMastModule.cs @@ -1,6 +1,3 @@ -using System; -using System.Linq; -using System.Threading; using System.Threading.Tasks; using Discord; using Discord.Interactions; diff --git a/src/FischBot/Modules/InfoModule.cs b/src/FischBot/Modules/InfoModule.cs index eb4ef13..db6adb8 100644 --- a/src/FischBot/Modules/InfoModule.cs +++ b/src/FischBot/Modules/InfoModule.cs @@ -1,11 +1,9 @@ using System; -using System.Linq; using System.Reflection; using System.Threading.Tasks; using Discord; using Discord.Interactions; using FischBot.Services.DiscordModuleService; -using Microsoft.Extensions.Configuration; namespace FischBot.Modules { @@ -16,14 +14,14 @@ public InfoModule(IDiscordModuleService moduleService) : base(moduleService) } [SlashCommand("say", "Echoes a message.")] - public async Task SayAsync([Summary(description: "The text to echo.")] string echo, [Summary(description: "Whether to show your identity. (optional)")]bool anonymous = false) + public async Task SayAsync([Summary(description: "The text to echo.")] string echo, [Summary(description: "Whether to show your identity. (optional)")] bool anonymous = false) { if (anonymous) { await ReplyAsync(echo); await RespondAsync("_Shhh... I've said your super secret message._", ephemeral: true); } - else + else { await RespondAsync(echo); } diff --git a/src/FischBot/Modules/StocksModule.cs b/src/FischBot/Modules/StocksModule.cs index 43d6c11..9a2af28 100644 --- a/src/FischBot/Modules/StocksModule.cs +++ b/src/FischBot/Modules/StocksModule.cs @@ -6,8 +6,6 @@ using System.Linq; using FischBot.Services.ImageChartService; using Discord.Interactions; -using System.Collections.Generic; -using FischBot.Models.Finance; namespace FischBot.Modules { @@ -25,7 +23,6 @@ public enum TimePeriod Year } - public StocksModule(IDiscordModuleService moduleService, IFinanceService financeService, IImageChartService imageChartService) : base(moduleService) { _financeService = financeService; diff --git a/src/FischBot/Program.cs b/src/FischBot/Program.cs index 20a6afc..f9872e6 100644 --- a/src/FischBot/Program.cs +++ b/src/FischBot/Program.cs @@ -1,6 +1,5 @@ using System; using System.IO; -using System.Linq; using System.Net.Http; using System.Threading; using System.Threading.Tasks; diff --git a/src/FischBot/Services/ArtificialIntelligenceService/IArtificialIntelligenceService.cs b/src/FischBot/Services/ArtificialIntelligenceService/IArtificialIntelligenceService.cs index 79a89b9..14c9e29 100644 --- a/src/FischBot/Services/ArtificialIntelligenceService/IArtificialIntelligenceService.cs +++ b/src/FischBot/Services/ArtificialIntelligenceService/IArtificialIntelligenceService.cs @@ -1,5 +1,3 @@ -using System; -using System.IO; using System.Threading.Tasks; using FischBot.Models.ArtificialIntelligence; diff --git a/src/FischBot/Services/HalfMastService/HalfMastService.cs b/src/FischBot/Services/HalfMastService/HalfMastService.cs index f15d083..cd8d344 100644 --- a/src/FischBot/Services/HalfMastService/HalfMastService.cs +++ b/src/FischBot/Services/HalfMastService/HalfMastService.cs @@ -1,6 +1,3 @@ -using System.Linq; -using System.Net; -using System.Threading; using System.Threading.Tasks; using FischBot.Api.HalfStaffJsScraperClient; using FischBot.Models; diff --git a/src/FischBot/Services/ImageChartService/IImageChartService.cs b/src/FischBot/Services/ImageChartService/IImageChartService.cs index 932a465..6b1a91a 100644 --- a/src/FischBot/Services/ImageChartService/IImageChartService.cs +++ b/src/FischBot/Services/ImageChartService/IImageChartService.cs @@ -1,7 +1,6 @@ using System; using System.Collections.Generic; using System.IO; -using System.Threading.Tasks; using FischBot.Models.Finance; namespace FischBot.Services.ImageChartService diff --git a/src/FischBot/Services/ImageChartService/ImageChartService.cs b/src/FischBot/Services/ImageChartService/ImageChartService.cs index 929de78..ae2a0c9 100644 --- a/src/FischBot/Services/ImageChartService/ImageChartService.cs +++ b/src/FischBot/Services/ImageChartService/ImageChartService.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Threading.Tasks; using FischBot.Models.Finance; using ScottPlot; diff --git a/src/FischBot/Services/LoggingService.cs b/src/FischBot/Services/LoggingService.cs index f3de2c5..20315ff 100644 --- a/src/FischBot/Services/LoggingService.cs +++ b/src/FischBot/Services/LoggingService.cs @@ -3,7 +3,6 @@ using Discord; using Discord.Commands; using Discord.WebSocket; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; namespace FischBot.Services From fee51f444e5ef7e1fead06fec6340b8e8100ac58 Mon Sep 17 00:00:00 2001 From: "Mark Fischer, Jr" Date: Fri, 30 May 2025 22:57:15 -0400 Subject: [PATCH 6/6] updated github build config for dotnet 9.0 --- .github/workflows/dotnet.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dotnet.yml b/.github/workflows/dotnet.yml index da284e5..fd932f9 100644 --- a/.github/workflows/dotnet.yml +++ b/.github/workflows/dotnet.yml @@ -16,7 +16,7 @@ jobs: - name: Setup .NET uses: actions/setup-dotnet@v1 with: - dotnet-version: 6.0.x + dotnet-version: 9.0.x - name: Restore dependencies run: dotnet restore - name: Build