From 6692823a46130df54e55dec39efff2166e7a0878 Mon Sep 17 00:00:00 2001 From: Twinki Date: Fri, 26 Jan 2024 21:49:05 -0500 Subject: [PATCH] Convert to .NET 8, with primary constructors --- .../GuildEvent/GuildEventCancelledConsumer.cs | 27 ++---- .../GuildEvent/GuildEventCreatedConsumer.cs | 27 ++---- .../GuildEvent/GuildEventStartedConsumer.cs | 29 ++----- .../GuildEvent/GuildEventUpdatedConsumer.cs | 27 ++---- src/Miha.Discord/Miha.Discord.csproj | 3 +- .../Modules/Guild/ConfigureModule.cs | 13 +-- .../Modules/User/BirthdayModule.cs | 53 ++++------- src/Miha.Discord/Modules/User/VrchatModule.cs | 15 +--- .../Services/GuildScheduledEventService.cs | 23 ++--- .../Hosted/GuildEventMonitorService.cs | 68 ++++++--------- .../Hosted/GuildEventScheduleService.cs | 87 ++++++++----------- .../Services/Hosted/InteractionHandler.cs | 32 +++---- .../Services/Hosted/SlimMessageBusService.cs | 23 ++--- src/Miha.Logic/Miha.Logic.csproj | 3 +- src/Miha.Logic/Services/BirthdayJobService.cs | 12 +-- src/Miha.Logic/Services/GuildService.cs | 49 +++++------ src/Miha.Logic/Services/UserService.cs | 19 ++-- src/Miha.Redis/Miha.Redis.csproj | 3 +- .../Repositories/BirthdayJobRepository.cs | 8 +- .../Repositories/DocumentRepository.cs | 19 ++-- .../Repositories/GuildRepository.cs | 8 +- src/Miha.Redis/Repositories/UserRepository.cs | 17 ++-- .../Services/RedisIndexCreationService.cs | 17 ++-- src/Miha.Redis/Services/RedisSeedService.cs | 31 +++---- src/Miha.Shared/Miha.Shared.csproj | 3 +- .../ZonedClocks/EasternStandardZonedClock.cs | 15 +--- src/Miha/Health/MihaHealthCheck.cs | 17 +--- src/Miha/Miha.csproj | 3 +- src/Miha/Services/BirthdayScannerService.cs | 55 +++++------- 29 files changed, 240 insertions(+), 466 deletions(-) diff --git a/src/Miha.Discord/Consumers/GuildEvent/GuildEventCancelledConsumer.cs b/src/Miha.Discord/Consumers/GuildEvent/GuildEventCancelledConsumer.cs index 03143d6..c7f6a67 100644 --- a/src/Miha.Discord/Consumers/GuildEvent/GuildEventCancelledConsumer.cs +++ b/src/Miha.Discord/Consumers/GuildEvent/GuildEventCancelledConsumer.cs @@ -7,34 +7,23 @@ namespace Miha.Discord.Consumers.GuildEvent; -public class GuildEventCancelledConsumer : IConsumer +public class GuildEventCancelledConsumer( + DiscordSocketClient client, + IGuildService guildService, + ILogger logger) : IConsumer { - private readonly DiscordSocketClient _client; - private readonly IGuildService _guildService; - private readonly ILogger _logger; - - public GuildEventCancelledConsumer( - DiscordSocketClient client, - IGuildService guildService, - ILogger logger) - { - _client = client; - _guildService = guildService; - _logger = logger; - } - public async Task OnHandle(IGuildScheduledEvent guildEvent) { - var loggingChannel = await _guildService.GetLoggingChannelAsync(guildEvent.Guild.Id); + var loggingChannel = await guildService.GetLoggingChannelAsync(guildEvent.Guild.Id); if (loggingChannel.IsFailed) { if (loggingChannel.Reasons.Any(m => m.Message == "Logging channel not set")) { - _logger.LogDebug("Guild logging channel not set {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); + logger.LogDebug("Guild logging channel not set {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); return; } - _logger.LogInformation("Failed getting logging channel for guild {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); + logger.LogInformation("Failed getting logging channel for guild {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); return; } @@ -51,7 +40,7 @@ public async Task OnHandle(IGuildScheduledEvent guildEvent) eventLocation: location, eventDescription: null, color: Color.Red, - authorAvatarUrl: guildEvent.Creator is null ? _client.CurrentUser.GetAvatarUrl() : guildEvent.Creator.GetAvatarUrl(), + authorAvatarUrl: guildEvent.Creator is null ? client.CurrentUser.GetAvatarUrl() : guildEvent.Creator.GetAvatarUrl(), authorUsername: guildEvent.Creator?.Username); await loggingChannel.Value.SendMessageAsync(embed: embed.Build()); diff --git a/src/Miha.Discord/Consumers/GuildEvent/GuildEventCreatedConsumer.cs b/src/Miha.Discord/Consumers/GuildEvent/GuildEventCreatedConsumer.cs index 30ed497..847cebd 100644 --- a/src/Miha.Discord/Consumers/GuildEvent/GuildEventCreatedConsumer.cs +++ b/src/Miha.Discord/Consumers/GuildEvent/GuildEventCreatedConsumer.cs @@ -7,34 +7,23 @@ namespace Miha.Discord.Consumers.GuildEvent; -public class GuildEventCreatedConsumer : IConsumer +public class GuildEventCreatedConsumer( + DiscordSocketClient client, + IGuildService guildService, + ILogger logger) : IConsumer { - private readonly DiscordSocketClient _client; - private readonly IGuildService _guildService; - private readonly ILogger _logger; - - public GuildEventCreatedConsumer( - DiscordSocketClient client, - IGuildService guildService, - ILogger logger) - { - _client = client; - _guildService = guildService; - _logger = logger; - } - public async Task OnHandle(IGuildScheduledEvent guildEvent) { - var loggingChannel = await _guildService.GetLoggingChannelAsync(guildEvent.Guild.Id); + var loggingChannel = await guildService.GetLoggingChannelAsync(guildEvent.Guild.Id); if (loggingChannel.IsFailed) { if (loggingChannel.Reasons.Any(m => m.Message == "Logging channel not set")) { - _logger.LogDebug("Guild logging channel not set {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); + logger.LogDebug("Guild logging channel not set {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); return; } - _logger.LogInformation("Failed getting logging channel for guild {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); + logger.LogInformation("Failed getting logging channel for guild {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); return; } @@ -83,7 +72,7 @@ public async Task OnHandle(IGuildScheduledEvent guildEvent) eventDescription: guildEvent.Description, eventImageUrl: coverImageUrl, color: Color.Purple, - authorAvatarUrl: guildEvent.Creator is null ? _client.CurrentUser.GetAvatarUrl() : guildEvent.Creator.GetAvatarUrl(), + authorAvatarUrl: guildEvent.Creator is null ? client.CurrentUser.GetAvatarUrl() : guildEvent.Creator.GetAvatarUrl(), authorUsername: guildEvent.Creator?.Username, fields: fields); diff --git a/src/Miha.Discord/Consumers/GuildEvent/GuildEventStartedConsumer.cs b/src/Miha.Discord/Consumers/GuildEvent/GuildEventStartedConsumer.cs index 4c18195..7a13fe7 100644 --- a/src/Miha.Discord/Consumers/GuildEvent/GuildEventStartedConsumer.cs +++ b/src/Miha.Discord/Consumers/GuildEvent/GuildEventStartedConsumer.cs @@ -7,35 +7,24 @@ namespace Miha.Discord.Consumers.GuildEvent; -public class GuildEventStartedConsumer : IConsumer +public class GuildEventStartedConsumer( + DiscordSocketClient client, + IGuildService guildService, + ILogger logger) : IConsumer { - private readonly DiscordSocketClient _client; - private readonly IGuildService _guildService; - private readonly ILogger _logger; - - public GuildEventStartedConsumer( - DiscordSocketClient client, - IGuildService guildService, - ILogger logger) - { - _client = client; - _guildService = guildService; - _logger = logger; - } - public async Task OnHandle(IGuildScheduledEvent guildEvent) { - var announcementRole = await _guildService.GetAnnouncementRoleAsync(guildEvent.Guild.Id); - var announcementChannel = await _guildService.GetAnnouncementChannelAsync(guildEvent.Guild.Id); + var announcementRole = await guildService.GetAnnouncementRoleAsync(guildEvent.Guild.Id); + var announcementChannel = await guildService.GetAnnouncementChannelAsync(guildEvent.Guild.Id); if (announcementChannel.IsFailed) { if (announcementChannel.Reasons.Any(m => m.Message == "Announcement channel not set")) { - _logger.LogDebug("Guild announcement channel not set {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); + logger.LogDebug("Guild announcement channel not set {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); return; } - _logger.LogInformation("Failed getting announcement channel for guild {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); + logger.LogInformation("Failed getting announcement channel for guild {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); return; } @@ -76,7 +65,7 @@ public async Task OnHandle(IGuildScheduledEvent guildEvent) eventDescription: guildEvent.Description, eventImageUrl: coverImageUrl, color: Color.Green, - authorAvatarUrl: guildEvent.Creator is null ? _client.CurrentUser.GetAvatarUrl() : guildEvent.Creator.GetAvatarUrl(), + authorAvatarUrl: guildEvent.Creator is null ? client.CurrentUser.GetAvatarUrl() : guildEvent.Creator.GetAvatarUrl(), authorUsername: guildEvent.Creator?.Username, fields: fields); diff --git a/src/Miha.Discord/Consumers/GuildEvent/GuildEventUpdatedConsumer.cs b/src/Miha.Discord/Consumers/GuildEvent/GuildEventUpdatedConsumer.cs index ace197f..c24521f 100644 --- a/src/Miha.Discord/Consumers/GuildEvent/GuildEventUpdatedConsumer.cs +++ b/src/Miha.Discord/Consumers/GuildEvent/GuildEventUpdatedConsumer.cs @@ -7,34 +7,23 @@ namespace Miha.Discord.Consumers.GuildEvent; -public class GuildEventUpdatedConsumer : IConsumer +public class GuildEventUpdatedConsumer( + DiscordSocketClient client, + IGuildService guildService, + ILogger logger) : IConsumer { - private readonly DiscordSocketClient _client; - private readonly IGuildService _guildService; - private readonly ILogger _logger; - - public GuildEventUpdatedConsumer( - DiscordSocketClient client, - IGuildService guildService, - ILogger logger) - { - _client = client; - _guildService = guildService; - _logger = logger; - } - public async Task OnHandle(IGuildScheduledEvent guildEvent) { - var loggingChannel = await _guildService.GetLoggingChannelAsync(guildEvent.Guild.Id); + var loggingChannel = await guildService.GetLoggingChannelAsync(guildEvent.Guild.Id); if (loggingChannel.IsFailed) { if (loggingChannel.Reasons.Any(m => m.Message == "Logging channel not set")) { - _logger.LogDebug("Guild logging channel not set {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); + logger.LogDebug("Guild logging channel not set {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); return; } - _logger.LogInformation("Failed getting logging channel for guild {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); + logger.LogInformation("Failed getting logging channel for guild {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); return; } @@ -84,7 +73,7 @@ public async Task OnHandle(IGuildScheduledEvent guildEvent) eventDescription: null, eventImageUrl: coverImageUrl, color: Color.LightOrange, - authorAvatarUrl: guildEvent.Creator is null ? _client.CurrentUser.GetAvatarUrl() : guildEvent.Creator.GetAvatarUrl(), + authorAvatarUrl: guildEvent.Creator is null ? client.CurrentUser.GetAvatarUrl() : guildEvent.Creator.GetAvatarUrl(), authorUsername: guildEvent.Creator?.Username, fields: fields); diff --git a/src/Miha.Discord/Miha.Discord.csproj b/src/Miha.Discord/Miha.Discord.csproj index 32058f2..eb7148f 100644 --- a/src/Miha.Discord/Miha.Discord.csproj +++ b/src/Miha.Discord/Miha.Discord.csproj @@ -1,9 +1,10 @@ - net7.0 + net8.0 enable enable + 12 diff --git a/src/Miha.Discord/Modules/Guild/ConfigureModule.cs b/src/Miha.Discord/Modules/Guild/ConfigureModule.cs index 7b8ad62..9ddce3d 100644 --- a/src/Miha.Discord/Modules/Guild/ConfigureModule.cs +++ b/src/Miha.Discord/Modules/Guild/ConfigureModule.cs @@ -11,21 +11,14 @@ namespace Miha.Discord.Modules.Guild; /// [Group("configure", "Set or update various bot settings and options")] [DefaultMemberPermissions(GuildPermission.Administrator)] -public class ConfigureModule : BaseInteractionModule +public class ConfigureModule(IGuildService guildService) : BaseInteractionModule { - private readonly IGuildService _guildService; - - public ConfigureModule(IGuildService guildService) - { - _guildService = guildService; - } - [SlashCommand("logging", "Sets or updates the event logging channel, where any event modifications are logged")] public async Task LoggingAsync( [Summary(description: "The channel newly Created, Modified, or Cancelled events will be posted")] ITextChannel channel, [Summary(description: "Setting this to true will disable event logging")] bool disable = false) { - var result = await _guildService.UpsertAsync(channel.GuildId, options => options.LogChannel = disable ? null : channel.Id); + var result = await guildService.UpsertAsync(channel.GuildId, options => options.LogChannel = disable ? null : channel.Id); if (result.IsFailed) { @@ -207,7 +200,7 @@ public async Task WeeklyScheduleAsync( [Summary(description: "The channel a weekly schedule of events will be posted")] ITextChannel channel, [Summary(description: "Setting this to true will disable the weekly event schedule")] bool disable = false) { - var result = await _guildService.UpsertAsync(channel.GuildId, options => options.WeeklyScheduleChannel = disable ? null : channel.Id); + var result = await guildService.UpsertAsync(channel.GuildId, options => options.WeeklyScheduleChannel = disable ? null : channel.Id); if (result.IsFailed) { diff --git a/src/Miha.Discord/Modules/User/BirthdayModule.cs b/src/Miha.Discord/Modules/User/BirthdayModule.cs index 2d2ed05..166e3d9 100644 --- a/src/Miha.Discord/Modules/User/BirthdayModule.cs +++ b/src/Miha.Discord/Modules/User/BirthdayModule.cs @@ -1,7 +1,6 @@ using System.Text; using Discord; using Discord.Interactions; -using Microsoft.Extensions.Logging; using Miha.Discord.Extensions; using Miha.Logic.Services.Interfaces; using NodaTime; @@ -15,32 +14,18 @@ namespace Miha.Discord.Modules.User; /// Birthday related interactions /// [Group("birthday", "Birthday related commands")] -public class BirthdayModule : BaseInteractionModule +public class BirthdayModule( + IClock clock, + IUserService userService, + IBirthdayJobService birthdayJobService) : BaseInteractionModule { private static readonly AnnualDatePattern BirthdatePattern = AnnualDatePattern.CreateWithInvariantCulture("MM/dd"); - private readonly IClock _clock; - private readonly IUserService _userService; - private readonly IBirthdayJobService _birthdayJobService; - private readonly ILogger _logger; - - public BirthdayModule( - IClock clock, - IUserService userService, - IBirthdayJobService birthdayJobService, - ILogger logger) - { - _clock = clock; - _userService = userService; - _birthdayJobService = birthdayJobService; - _logger = logger; - } - [SlashCommand("get", "Gets your, or another users, birthday")] public async Task GetAsync(IUser? user = null) { var targetUser = user ?? Context.User; - var result = await _userService.GetAsync(targetUser.Id); + var result = await userService.GetAsync(targetUser.Id); var userDoc = result.Value; var userTimezone = userDoc?.Timezone; @@ -65,13 +50,13 @@ public async Task GetAsync(IUser? user = null) } var userBirthdate = userDoc.AnnualBirthdate.Value; - var currentDateInTimezone = _clock.InZone(userTimezone).GetCurrentDate(); + var currentDateInTimezone = clock.InZone(userTimezone).GetCurrentDate(); var localBirthdate = new LocalDate(currentDateInTimezone.Year, userBirthdate.Month, userBirthdate.Day); var birthDateTime = localBirthdate.AtStartOfDayInZone(userTimezone).ToInstant(); var birthDateTimeOffset = birthDateTime.ToDateTimeOffset(); - var birthdayAlreadyHappened = _clock.InZone(userTimezone).GetCurrentInstant() > birthDateTime; + var birthdayAlreadyHappened = clock.InZone(userTimezone).GetCurrentInstant() > birthDateTime; var description = new StringBuilder() .Append(targetUser.Mention) @@ -123,7 +108,7 @@ public async Task SetAsync( return; } - var result = await _userService.UpsertAsync(Context.User.Id, doc => + var result = await userService.UpsertAsync(Context.User.Id, doc => { doc.AnnualBirthdate = birthDate; doc.Timezone = birthDateTimezone; @@ -142,13 +127,13 @@ public async Task SetAsync( .WithButton(new ButtonBuilder().WithLabel("No").WithCustomId("tz:n").WithStyle(ButtonStyle.Secondary)) .Build(); - var currentDateInTimezone = _clock.InZone(birthDateTimezone).GetCurrentDate(); + var currentDateInTimezone = clock.InZone(birthDateTimezone).GetCurrentDate(); var localBirthdate = new LocalDate(currentDateInTimezone.Year, birthDate.Month, birthDate.Day); var birthDateTime = localBirthdate.AtStartOfDayInZone(birthDateTimezone).ToInstant(); var birthDateTimeOffset = birthDateTime.ToDateTimeOffset(); - var birthdayAlreadyHappened = _clock.InZone(birthDateTimezone).GetCurrentInstant() > birthDateTime; + var birthdayAlreadyHappened = clock.InZone(birthDateTimezone).GetCurrentInstant() > birthDateTime; var description = new StringBuilder() .Append("You're birthday ").Append(birthdayAlreadyHappened ? " was " : " is ").Append(birthDateTimeOffset.ToDiscordTimestamp(TimestampTagStyles.Relative)) @@ -171,7 +156,7 @@ public async Task SetAsync( [SlashCommand("clear", "Clears your birthday")] public async Task ClearAsync() { - var deleteJobResult = await _birthdayJobService.DeleteAsync(Context.User.Id, true); + var deleteJobResult = await birthdayJobService.DeleteAsync(Context.User.Id, true); if (deleteJobResult.IsFailed) { @@ -179,7 +164,7 @@ public async Task ClearAsync() return; } - var result = await _userService.UpsertAsync(Context.User.Id, doc => + var result = await userService.UpsertAsync(Context.User.Id, doc => { doc.EnableBirthday = false; doc.Timezone = null; @@ -199,7 +184,7 @@ public async Task ClearAsync() [SlashCommand("enable", "Enables your birthday if previously disabled, when enabled it'll be announced the day-of")] public async Task EnableAsync() { - var userDoc = await _userService.GetAsync(Context.User.Id); + var userDoc = await userService.GetAsync(Context.User.Id); if (userDoc.IsFailed) { @@ -213,7 +198,7 @@ public async Task EnableAsync() return; } - var deleteJobResult = await _birthdayJobService.DeleteAsync(Context.User.Id, true); + var deleteJobResult = await birthdayJobService.DeleteAsync(Context.User.Id, true); if (deleteJobResult.IsFailed) { @@ -221,7 +206,7 @@ public async Task EnableAsync() return; } - var result = await _userService.UpsertAsync(Context.User.Id, doc => + var result = await userService.UpsertAsync(Context.User.Id, doc => { doc.EnableBirthday = true; }); @@ -238,7 +223,7 @@ public async Task EnableAsync() [SlashCommand("disable", "Disables your birthday if previously enabled, when disabled your birthday won't be announced")] public async Task DisableAsync() { - var userDoc = await _userService.GetAsync(Context.User.Id); + var userDoc = await userService.GetAsync(Context.User.Id); if (userDoc.IsFailed) { @@ -252,7 +237,7 @@ public async Task DisableAsync() return; } - var result = await _userService.UpsertAsync(Context.User.Id, doc => + var result = await userService.UpsertAsync(Context.User.Id, doc => { doc.EnableBirthday = false; }); @@ -275,7 +260,7 @@ public async Task HandleTimeZoneAsync(string confirm) if (confirmed) { - var deleteJobResult = await _birthdayJobService.DeleteAsync(Context.User.Id, true); + var deleteJobResult = await birthdayJobService.DeleteAsync(Context.User.Id, true); if (deleteJobResult.IsFailed) { @@ -283,7 +268,7 @@ public async Task HandleTimeZoneAsync(string confirm) return; } - var result = await _userService.UpsertAsync(Context.User.Id, doc => doc.EnableBirthday = true); + var result = await userService.UpsertAsync(Context.User.Id, doc => doc.EnableBirthday = true); if (result.IsFailed) { await ModifyOriginalResponseToErrorAsync(result.Errors); diff --git a/src/Miha.Discord/Modules/User/VrchatModule.cs b/src/Miha.Discord/Modules/User/VrchatModule.cs index ccf983f..41d56df 100644 --- a/src/Miha.Discord/Modules/User/VrchatModule.cs +++ b/src/Miha.Discord/Modules/User/VrchatModule.cs @@ -9,20 +9,13 @@ namespace Miha.Discord.Modules.User; /// VRChat related interactions /// [Group("vrchat", "Manage your VRChat user profile in relation to your Discord profile")] -public class VrchatModule : BaseInteractionModule +public class VrchatModule(IUserService userService) : BaseInteractionModule { - private readonly IUserService _userService; - - public VrchatModule(IUserService userService) - { - _userService = userService; - } - [SlashCommand("get", "Gets your, or another users, VRChat profile information")] public async Task GetAsync(IUser? user = null) { var targetUser = user ?? Context.User; - var result = await _userService.GetAsync(targetUser.Id); + var result = await userService.GetAsync(targetUser.Id); var userDoc = result.Value; if (result.IsFailed) @@ -56,7 +49,7 @@ public async Task GetAsync(IUser? user = null) public async Task SetAsync( [Summary("vrchatProfileUrl", "VRChat user link, ex https://vrchat.com/home/user/usr_666ca92f-ca50-4c25-994c-03d72842c92b")] string vrchatProfileUrl) { - var result = await _userService.UpsertVrchatUserIdAsync(Context.User.Id, vrchatProfileUrl); + var result = await userService.UpsertVrchatUserIdAsync(Context.User.Id, vrchatProfileUrl); if (result.IsFailed) { @@ -70,7 +63,7 @@ public async Task SetAsync( [SlashCommand("clear", "Clears your VRChat profile")] public async Task ClearAsync() { - var result = await _userService.UpsertAsync(Context.User.Id, doc => doc.VrcUserId = null); + var result = await userService.UpsertAsync(Context.User.Id, doc => doc.VrcUserId = null); if (result.IsFailed) { diff --git a/src/Miha.Discord/Services/GuildScheduledEventService.cs b/src/Miha.Discord/Services/GuildScheduledEventService.cs index 809b43e..3c96f51 100644 --- a/src/Miha.Discord/Services/GuildScheduledEventService.cs +++ b/src/Miha.Discord/Services/GuildScheduledEventService.cs @@ -1,7 +1,6 @@ using Discord; using Discord.WebSocket; using FluentResults; -using Microsoft.Extensions.Logging; using Miha.Discord.Services.Interfaces; using Miha.Shared.ZonedClocks.Interfaces; using NodaTime; @@ -9,27 +8,15 @@ namespace Miha.Discord.Services; -public class GuildScheduledEventService : IGuildScheduledEventService +public class GuildScheduledEventService( + DiscordSocketClient discordClient, + IEasternStandardZonedClock easternStandardZonedClock) : IGuildScheduledEventService { - private readonly DiscordSocketClient _discordClient; - private readonly IEasternStandardZonedClock _easternStandardZonedClock; - private readonly ILogger _logger; - - public GuildScheduledEventService( - DiscordSocketClient discordClient, - IEasternStandardZonedClock easternStandardZonedClock, - ILogger logger) - { - _discordClient = discordClient; - _easternStandardZonedClock = easternStandardZonedClock; - _logger = logger; - } - public async Task>> GetScheduledWeeklyEventsAsync(ulong guildId, LocalDate dateOfTheWeek) { var weekNumberInYear = WeekYearRules.Iso.GetWeekOfWeekYear(dateOfTheWeek); - var guild = _discordClient.GetGuild(guildId); + var guild = discordClient.GetGuild(guildId); if (guild is null) { @@ -40,7 +27,7 @@ public async Task>> GetScheduledWeeklyE var eventsThisWeek = events.Where(guildEvent => { - var estDate = _easternStandardZonedClock.ToZonedDateTime(guildEvent.StartTime).Date; + var estDate = easternStandardZonedClock.ToZonedDateTime(guildEvent.StartTime).Date; var weekOfDate = WeekYearRules.Iso.GetWeekOfWeekYear(estDate); diff --git a/src/Miha.Discord/Services/Hosted/GuildEventMonitorService.cs b/src/Miha.Discord/Services/Hosted/GuildEventMonitorService.cs index a8bbc21..af398c2 100644 --- a/src/Miha.Discord/Services/Hosted/GuildEventMonitorService.cs +++ b/src/Miha.Discord/Services/Hosted/GuildEventMonitorService.cs @@ -14,43 +14,27 @@ namespace Miha.Discord.Services.Hosted; -public partial class GuildEventMonitorService : DiscordClientService +public partial class GuildEventMonitorService( + DiscordSocketClient client, + IGuildService guildService, + IEasternStandardZonedClock easternStandardZonedClock, + IOptions discordOptions, + ILogger logger) : DiscordClientService(client, logger) { - private readonly DiscordOptions _discordOptions; - private readonly IGuildService _guildService; - private readonly IEasternStandardZonedClock _easternStandardZonedClock; - private readonly ILogger _logger; + private readonly DiscordOptions _discordOptions = discordOptions.Value; private const string Schedule = "0,5,10,15,20,25,30,35,40,45,50,55 ? * * *"; // https://crontab.cronhub.io/ - private readonly IMemoryCache _memoryCache; - private readonly MemoryCacheEntryOptions _memoryCacheEntryOptions; - private readonly CronExpression _cron; - - public GuildEventMonitorService( - DiscordSocketClient client, - IGuildService guildService, - IEasternStandardZonedClock easternStandardZonedClock, - IOptions discordOptions, - ILogger logger) : base(client, logger) - { - _discordOptions = discordOptions.Value; - _guildService = guildService; - _easternStandardZonedClock = easternStandardZonedClock; - _logger = logger; - - _memoryCache = new MemoryCache(new MemoryCacheOptions { SizeLimit = 32 }); - _memoryCacheEntryOptions = new MemoryCacheEntryOptions() - .SetSize(1) - .SetAbsoluteExpiration(TimeSpan.FromMinutes(25)) - .SetSlidingExpiration(TimeSpan.FromMinutes(15)); - - _cron = CronExpression.Parse(Schedule, CronFormat.Standard); - } + private readonly IMemoryCache _memoryCache = new MemoryCache(new MemoryCacheOptions { SizeLimit = 32 }); + private readonly MemoryCacheEntryOptions _memoryCacheEntryOptions = new MemoryCacheEntryOptions() + .SetSize(1) + .SetAbsoluteExpiration(TimeSpan.FromMinutes(25)) + .SetSlidingExpiration(TimeSpan.FromMinutes(15)); + private readonly CronExpression _cron = CronExpression.Parse(Schedule, CronFormat.Standard); protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - _logger.LogInformation("Waiting for client to be ready..."); + logger.LogInformation("Waiting for client to be ready..."); await Client.WaitForReadyAsync(stoppingToken); @@ -58,19 +42,19 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await CheckScheduledEventsAsync(); - var utcNow = _easternStandardZonedClock.GetCurrentInstant().ToDateTimeUtc(); - var nextUtc = _cron.GetNextOccurrence(DateTimeOffset.UtcNow, _easternStandardZonedClock.GetTimeZoneInfo()); + var utcNow = easternStandardZonedClock.GetCurrentInstant().ToDateTimeUtc(); + var nextUtc = _cron.GetNextOccurrence(DateTimeOffset.UtcNow, easternStandardZonedClock.GetTimeZoneInfo()); if (nextUtc is null) { - _logger.LogWarning("Next utc occurence is null"); + logger.LogWarning("Next utc occurence is null"); await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken); continue; } var next = nextUtc.Value - utcNow; - _logger.LogDebug("Waiting {Time} until next operation", next.Humanize(3)); + logger.LogDebug("Waiting {Time} until next operation", next.Humanize(3)); await Task.Delay(nextUtc.Value - utcNow, stoppingToken); } @@ -85,7 +69,7 @@ private async Task CheckScheduledEventsAsync() guild = Client.GetGuild(_discordOptions.Guild!.Value); if (guild is null) { - _logger.LogCritical("Guild is null {GuildId}", _discordOptions.Guild.Value); + logger.LogCritical("Guild is null {GuildId}", _discordOptions.Guild.Value); return; } } @@ -99,16 +83,16 @@ private async Task CheckScheduledEventsAsync() { try { - var announcementChannel = await _guildService.GetAnnouncementChannelAsync(guild.Id); + var announcementChannel = await guildService.GetAnnouncementChannelAsync(guild.Id); if (announcementChannel.IsFailed) { if (announcementChannel.Reasons.Any(m => m.Message == "Announcement channel not set")) { - _logger.LogDebug("Guild announcement channel not set {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); + logger.LogDebug("Guild announcement channel not set {GuildId} {EventId}", guildEvent.Guild.Id, guildEvent.Id); return; } - _logger.LogInformation("Failed getting announcement channel for guild {GuildId} {EventId}", guild.Id, guildEvent.Id); + logger.LogInformation("Failed getting announcement channel for guild {GuildId} {EventId}", guild.Id, guildEvent.Id); continue; } @@ -120,17 +104,17 @@ private async Task CheckScheduledEventsAsync() startsIn = new TimeSpan(startsIn.Days, startsIn.Hours, startsIn.Minutes + 1, 0); } - _logger.LogDebug("GuildEvent {EventId} starts in (rounded) {StartsInTotalMinutes}", guildEvent.Id, startsIn.TotalMinutes); + logger.LogDebug("GuildEvent {EventId} starts in (rounded) {StartsInTotalMinutes}", guildEvent.Id, startsIn.TotalMinutes); if (startsIn.TotalMinutes is < 5 or > 20 || _memoryCache.TryGetValue(guildEvent.Id, out bool notified) && notified) { - _logger.LogDebug("GuildEvent {EventId} starts too soon or is already notified", guildEvent.Id); + logger.LogDebug("GuildEvent {EventId} starts too soon or is already notified", guildEvent.Id); continue; } - if (_logger.IsEnabled(LogLevel.Debug)) + if (logger.IsEnabled(LogLevel.Debug)) { - _logger.LogDebug("GuildEvent {EventId} {GuildEventJson}", guildEvent.Id, JsonConvert.SerializeObject(new + logger.LogDebug("GuildEvent {EventId} {GuildEventJson}", guildEvent.Id, JsonConvert.SerializeObject(new { guildEvent.StartTime, guildEvent.Id, diff --git a/src/Miha.Discord/Services/Hosted/GuildEventScheduleService.cs b/src/Miha.Discord/Services/Hosted/GuildEventScheduleService.cs index 57ecb68..ff34f15 100644 --- a/src/Miha.Discord/Services/Hosted/GuildEventScheduleService.cs +++ b/src/Miha.Discord/Services/Hosted/GuildEventScheduleService.cs @@ -16,39 +16,24 @@ namespace Miha.Discord.Services.Hosted; -public partial class GuildEventScheduleService : DiscordClientService +public partial class GuildEventScheduleService( + DiscordSocketClient client, + IEasternStandardZonedClock easternStandardZonedClock, + IGuildService guildService, + IGuildScheduledEventService scheduledEventService, + IOptions discordOptions, + ILogger logger) : DiscordClientService(client, logger) { - private readonly DiscordSocketClient _client; - private readonly IEasternStandardZonedClock _easternStandardZonedClock; - private readonly IGuildService _guildService; - private readonly IGuildScheduledEventService _scheduledEventService; - private readonly DiscordOptions _discordOptions; - private readonly ILogger _logger; + private readonly DiscordSocketClient _client = client; + private readonly DiscordOptions _discordOptions = discordOptions.Value; + private const string Schedule = "0,5,10,15,20,25,30,35,40,45,50,55 * * * *"; // https://crontab.cronhub.io/ - - private readonly CronExpression _cron; - - public GuildEventScheduleService( - DiscordSocketClient client, - IEasternStandardZonedClock easternStandardZonedClock, - IGuildService guildService, - IGuildScheduledEventService scheduledEventService, - IOptions discordOptions, - ILogger logger) : base(client, logger) - { - _client = client; - _easternStandardZonedClock = easternStandardZonedClock; - _guildService = guildService; - _scheduledEventService = scheduledEventService; - _discordOptions = discordOptions.Value; - _logger = logger; - - _cron = CronExpression.Parse(Schedule, CronFormat.Standard); - } + + private readonly CronExpression _cron = CronExpression.Parse(Schedule, CronFormat.Standard); protected override async Task ExecuteAsync(CancellationToken stoppingToken) { - _logger.LogInformation("Waiting for client to be ready..."); + logger.LogInformation("Waiting for client to be ready..."); await Client.WaitForReadyAsync(stoppingToken); @@ -60,75 +45,75 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) } catch (HttpException e) { - _logger.LogWarning(e, "Discord dotnet http exception caught, likely caused by rate-limits, waiting a few minutes before continuing"); + logger.LogWarning(e, "Discord dotnet http exception caught, likely caused by rate-limits, waiting a few minutes before continuing"); await Task.Delay(TimeSpan.FromMinutes(3), stoppingToken); continue; } - var utcNow = _easternStandardZonedClock.GetCurrentInstant().ToDateTimeUtc(); - var nextUtc = _cron.GetNextOccurrence(DateTimeOffset.UtcNow, _easternStandardZonedClock.GetTimeZoneInfo()); + var utcNow = easternStandardZonedClock.GetCurrentInstant().ToDateTimeUtc(); + var nextUtc = _cron.GetNextOccurrence(DateTimeOffset.UtcNow, easternStandardZonedClock.GetTimeZoneInfo()); if (nextUtc is null) { - _logger.LogWarning("Next utc occurence is null"); + logger.LogWarning("Next utc occurence is null"); await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken); continue; } var next = nextUtc.Value - utcNow; - _logger.LogDebug("Waiting {Time} until next operation", next.Humanize(3)); + logger.LogDebug("Waiting {Time} until next operation", next.Humanize(3)); await Task.Delay(nextUtc.Value - utcNow, stoppingToken); } - _logger.LogInformation("Hosted service ended"); + logger.LogInformation("Hosted service ended"); } private async Task PostWeeklyScheduleAsync() { if (_discordOptions.Guild is null) { - _logger.LogWarning("Guild isn't configured"); + logger.LogWarning("Guild isn't configured"); return; } - var guildResult = await _guildService.GetAsync(_discordOptions.Guild); + var guildResult = await guildService.GetAsync(_discordOptions.Guild); var guild = guildResult.Value; if (guildResult.IsFailed || guild is null) { - _logger.LogWarning("Guild doc failed, or the guild is null for some reason {Errors}", guildResult.Errors); + logger.LogWarning("Guild doc failed, or the guild is null for some reason {Errors}", guildResult.Errors); return; } if (guild.WeeklyScheduleChannel is null) { - _logger.LogDebug("Guild doesn't have a configured weekly schedule channel"); + logger.LogDebug("Guild doesn't have a configured weekly schedule channel"); return; } - var eventsThisWeekResult = await _scheduledEventService.GetScheduledWeeklyEventsAsync(guild.Id, _easternStandardZonedClock.GetCurrentDate()); + var eventsThisWeekResult = await scheduledEventService.GetScheduledWeeklyEventsAsync(guild.Id, easternStandardZonedClock.GetCurrentDate()); var eventsThisWeek = eventsThisWeekResult.Value; if (eventsThisWeekResult.IsFailed || eventsThisWeek is null) { - _logger.LogWarning("Fetching this weeks events failed, or is null {Errors}", eventsThisWeekResult.Errors); + logger.LogWarning("Fetching this weeks events failed, or is null {Errors}", eventsThisWeekResult.Errors); return; } - var weeklyScheduleChannelResult = await _guildService.GetWeeklyScheduleChannel(guild.Id); + var weeklyScheduleChannelResult = await guildService.GetWeeklyScheduleChannel(guild.Id); var weeklyScheduleChannel = weeklyScheduleChannelResult.Value; if (weeklyScheduleChannelResult.IsFailed || weeklyScheduleChannel is null) { - _logger.LogWarning("Fetching the guilds weekly schedule channel failed, or is null {Errors}", weeklyScheduleChannelResult.Errors); + logger.LogWarning("Fetching the guilds weekly schedule channel failed, or is null {Errors}", weeklyScheduleChannelResult.Errors); return; } - var daysThisWeek = _easternStandardZonedClock.GetCurrentWeekAsDates(); + var daysThisWeek = easternStandardZonedClock.GetCurrentWeekAsDates(); var eventsByDay = new Dictionary>(); var eventsThisWeekList = eventsThisWeek.ToList(); @@ -136,13 +121,13 @@ private async Task PostWeeklyScheduleAsync() { eventsByDay.Add(dayOfWeek, new List()); - foreach (var guildScheduledEvent in eventsThisWeekList.Where(e => _easternStandardZonedClock.ToZonedDateTime(e.StartTime).Date.ToDateOnly() == dayOfWeek)) + foreach (var guildScheduledEvent in eventsThisWeekList.Where(e => easternStandardZonedClock.ToZonedDateTime(e.StartTime).Date.ToDateOnly() == dayOfWeek)) { eventsByDay[dayOfWeek].Add(guildScheduledEvent); } } - _logger.LogInformation("Updating weekly schedule"); + logger.LogInformation("Updating weekly schedule"); var postedHeader = false; var postedFooter = false; @@ -173,7 +158,7 @@ private async Task PostWeeklyScheduleAsync() { var deletedMessages = 0; - _logger.LogInformation("Wiping posted messages"); + logger.LogInformation("Wiping posted messages"); foreach (var message in messagesToDelete) { @@ -181,7 +166,7 @@ private async Task PostWeeklyScheduleAsync() deletedMessages++; } - _logger.LogInformation("Deleted {DeletedMessages} messages", deletedMessages); + logger.LogInformation("Deleted {DeletedMessages} messages", deletedMessages); // Update the messages list messages = (await weeklyScheduleChannel @@ -215,12 +200,12 @@ private async Task PostWeeklyScheduleAsync() var timeStamp = day .ToLocalDate() - .AtStartOfDayInZone(_easternStandardZonedClock.GetTzdbTimeZone()) + .AtStartOfDayInZone(easternStandardZonedClock.GetTzdbTimeZone()) .ToInstant() .ToDiscordTimestamp(TimestampTagStyles.ShortDate); // The day has passed - if (_easternStandardZonedClock.GetCurrentDate().ToDateOnly() > day) + if (easternStandardZonedClock.GetCurrentDate().ToDateOnly() > day) { description.AppendLine($"~~### {day.ToString("dddd")} - {timeStamp}~~"); } else @@ -283,7 +268,7 @@ private async Task PostWeeklyScheduleAsync() if (lastPostedMessage is null) { - _logger.LogInformation("Posting new message"); + logger.LogInformation("Posting new message"); await weeklyScheduleChannel.SendMessageAsync(embed: embed.Build()); } else @@ -295,7 +280,7 @@ await weeklyScheduleChannel.ModifyMessageAsync(lastPostedMessage.Id, props => } } - _logger.LogInformation("Finished updating weekly schedule"); + logger.LogInformation("Finished updating weekly schedule"); } [LoggerMessage(EventId = 1, Level = LogLevel.Error, Message = "Exception occurred")] diff --git a/src/Miha.Discord/Services/Hosted/InteractionHandler.cs b/src/Miha.Discord/Services/Hosted/InteractionHandler.cs index 880bdbc..951b7f7 100644 --- a/src/Miha.Discord/Services/Hosted/InteractionHandler.cs +++ b/src/Miha.Discord/Services/Hosted/InteractionHandler.cs @@ -9,25 +9,15 @@ namespace Miha.Discord.Services.Hosted; -public class InteractionHandler : DiscordClientService +public class InteractionHandler( + DiscordSocketClient client, + IServiceProvider provider, + InteractionService interactionService, + IOptions discordOptions, + ILogger logger) : DiscordClientService(client, logger) { - private readonly IServiceProvider _provider; - private readonly InteractionService _interactionService; - private readonly ILogger _logger; - private readonly DiscordOptions _discordOptions; - - public InteractionHandler( - DiscordSocketClient client, - IServiceProvider provider, - InteractionService interactionService, - IOptions discordOptions, - ILogger logger) : base(client, logger) - { - _provider = provider; - _interactionService = interactionService; - _logger = logger; - _discordOptions = discordOptions.Value; - } + private readonly ILogger _logger = logger; + private readonly DiscordOptions _discordOptions = discordOptions.Value; protected override async Task ExecuteAsync(CancellationToken stoppingToken) { @@ -38,11 +28,11 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) Client.InteractionCreated += HandleInteraction; - await _interactionService.AddModulesAsync(Assembly.GetExecutingAssembly(), _provider); + await interactionService.AddModulesAsync(Assembly.GetExecutingAssembly(), provider); await Client.WaitForReadyAsync(stoppingToken); - await _interactionService.RegisterCommandsToGuildAsync(_discordOptions.Guild.Value); + await interactionService.RegisterCommandsToGuildAsync(_discordOptions.Guild.Value); } private async Task HandleInteraction(SocketInteraction arg) @@ -51,7 +41,7 @@ private async Task HandleInteraction(SocketInteraction arg) { // Create an execution context that matches the generic type parameter of your InteractionModuleBase modules var ctx = new SocketInteractionContext(Client, arg); - await _interactionService.ExecuteCommandAsync(ctx, _provider); + await interactionService.ExecuteCommandAsync(ctx, provider); } catch (Exception ex) { diff --git a/src/Miha.Discord/Services/Hosted/SlimMessageBusService.cs b/src/Miha.Discord/Services/Hosted/SlimMessageBusService.cs index 0c73bee..9888ae8 100644 --- a/src/Miha.Discord/Services/Hosted/SlimMessageBusService.cs +++ b/src/Miha.Discord/Services/Hosted/SlimMessageBusService.cs @@ -9,25 +9,18 @@ namespace Miha.Discord.Services.Hosted; -public class SlimMessageBusService : DiscordClientService +public class SlimMessageBusService( + DiscordSocketClient client, + IPublishBus bus, + ILogger logger) : DiscordClientService(client, logger) { - private readonly IMessageBus _bus; - - public SlimMessageBusService( - DiscordSocketClient client, - IMessageBus bus, - ILogger logger) : base(client, logger) - { - _bus = bus; - } - protected override async Task ExecuteAsync(CancellationToken stoppingToken) { // Publish events to our Slim Message Bus consumers - Client.GuildScheduledEventCreated += @event => _bus.Publish(@event, Topics.GuildEvent.Created, cancellationToken: stoppingToken); - Client.GuildScheduledEventStarted += @event => _bus.Publish(@event, Topics.GuildEvent.Started, cancellationToken: stoppingToken); - Client.GuildScheduledEventCancelled += @event => _bus.Publish(@event, Topics.GuildEvent.Cancelled, cancellationToken: stoppingToken); - Client.GuildScheduledEventUpdated += (_, @event) => _bus.Publish(@event, Topics.GuildEvent.Updated, cancellationToken: stoppingToken); + Client.GuildScheduledEventCreated += @event => bus.Publish(@event, Topics.GuildEvent.Created, cancellationToken: stoppingToken); + Client.GuildScheduledEventStarted += @event => bus.Publish(@event, Topics.GuildEvent.Started, cancellationToken: stoppingToken); + Client.GuildScheduledEventCancelled += @event => bus.Publish(@event, Topics.GuildEvent.Cancelled, cancellationToken: stoppingToken); + Client.GuildScheduledEventUpdated += (_, @event) => bus.Publish(@event, Topics.GuildEvent.Updated, cancellationToken: stoppingToken); await Client.WaitForReadyAsync(stoppingToken); await Client.SetActivityAsync(new Game("on " + Versioning.GetVersion())); diff --git a/src/Miha.Logic/Miha.Logic.csproj b/src/Miha.Logic/Miha.Logic.csproj index 63d3ac3..adcee9c 100644 --- a/src/Miha.Logic/Miha.Logic.csproj +++ b/src/Miha.Logic/Miha.Logic.csproj @@ -1,9 +1,10 @@ - net7.0 + net8.0 enable enable + 12 diff --git a/src/Miha.Logic/Services/BirthdayJobService.cs b/src/Miha.Logic/Services/BirthdayJobService.cs index e82b19a..f27c78c 100644 --- a/src/Miha.Logic/Services/BirthdayJobService.cs +++ b/src/Miha.Logic/Services/BirthdayJobService.cs @@ -5,12 +5,6 @@ namespace Miha.Logic.Services; -public class BirthdayJobService : DocumentService, IBirthdayJobService -{ - public BirthdayJobService( - IBirthdayJobRepository repository, - ILogger logger) : base(repository, logger) - { - - } -} +public class BirthdayJobService( + IBirthdayJobRepository repository, + ILogger logger) : DocumentService(repository, logger), IBirthdayJobService; diff --git a/src/Miha.Logic/Services/GuildService.cs b/src/Miha.Logic/Services/GuildService.cs index 68ed3d2..512c1f5 100644 --- a/src/Miha.Logic/Services/GuildService.cs +++ b/src/Miha.Logic/Services/GuildService.cs @@ -8,20 +8,11 @@ namespace Miha.Logic.Services; -public partial class GuildService : DocumentService, IGuildService +public class GuildService( + DiscordSocketClient client, + IGuildRepository repository, + ILogger logger) : DocumentService(repository, logger), IGuildService { - private readonly DiscordSocketClient _client; - private readonly ILogger _logger; - - public GuildService( - DiscordSocketClient client, - IGuildRepository repository, - ILogger logger) : base(repository, logger) - { - _client = client; - _logger = logger; - } - public async Task> GetLoggingChannelAsync(ulong? guildId) { try @@ -34,23 +25,23 @@ public async Task> GetLoggingChannelAsync(ulong? guildId) var optionsResult = await GetAsync(guildId); if (optionsResult.IsFailed) { - _logger.LogWarning("Guild doesn't have any document when trying to get logging channel {GuildId}", guildId); + logger.LogWarning("Guild doesn't have any document when trying to get logging channel {GuildId}", guildId); return optionsResult.ToResult(); } var logChannel = optionsResult.Value?.LogChannel; if (!logChannel.HasValue) { - _logger.LogDebug("Guild doesn't have a logging channel set {GuildId}", guildId); + logger.LogDebug("Guild doesn't have a logging channel set {GuildId}", guildId); return Result.Fail("Logging channel not set"); } - if (await _client.GetChannelAsync(logChannel.Value) is ITextChannel loggingChannel) + if (await client.GetChannelAsync(logChannel.Value) is ITextChannel loggingChannel) { return Result.Ok(loggingChannel); } - _logger.LogWarning("Guild's logging channel wasn't found, or might not be a Text Channel {GuildId} {LoggingChannelId}", guildId, logChannel.Value); + logger.LogWarning("Guild's logging channel wasn't found, or might not be a Text Channel {GuildId} {LoggingChannelId}", guildId, logChannel.Value); return Result.Fail("Logging channel not found"); } catch (Exception e) @@ -72,23 +63,23 @@ public async Task> GetAnnouncementChannelAsync(ulong? guild var optionsResult = await GetAsync(guildId); if (optionsResult.IsFailed) { - _logger.LogWarning("Guild doesn't have any document when trying to get announcement channel {GuildId}", guildId); + logger.LogWarning("Guild doesn't have any document when trying to get announcement channel {GuildId}", guildId); return optionsResult.ToResult(); } var announcementChannel = optionsResult.Value?.AnnouncementChannel; if (!announcementChannel.HasValue) { - _logger.LogDebug("Guild doesn't have a announcement channel set {GuildId}", guildId); + logger.LogDebug("Guild doesn't have a announcement channel set {GuildId}", guildId); return Result.Fail("Announcement channel not set"); } - if (await _client.GetChannelAsync(announcementChannel.Value) is ITextChannel loggingChannel) + if (await client.GetChannelAsync(announcementChannel.Value) is ITextChannel loggingChannel) { return Result.Ok(loggingChannel); } - _logger.LogWarning("Guild's announcement channel wasn't found, or might not be a Text Channel {GuildId} {AnnouncementChannelId}", guildId, announcementChannel.Value); + logger.LogWarning("Guild's announcement channel wasn't found, or might not be a Text Channel {GuildId} {AnnouncementChannelId}", guildId, announcementChannel.Value); return Result.Fail("Announcement channel not found"); } catch (Exception e) @@ -110,23 +101,23 @@ public async Task> GetWeeklyScheduleChannel(ulong? guildId) var optionsResult = await GetAsync(guildId); if (optionsResult.IsFailed) { - _logger.LogWarning("Guild doesn't have any document when trying to get announcement channel {GuildId}", guildId); + logger.LogWarning("Guild doesn't have any document when trying to get announcement channel {GuildId}", guildId); return optionsResult.ToResult(); } var weeklyScheduleChannel = optionsResult.Value?.WeeklyScheduleChannel; if (!weeklyScheduleChannel.HasValue) { - _logger.LogDebug("Guild doesn't have a weekly schedule channel set {GuildId}", guildId); + logger.LogDebug("Guild doesn't have a weekly schedule channel set {GuildId}", guildId); return Result.Fail("Weekly schedule channel not set"); } - if (await _client.GetChannelAsync(weeklyScheduleChannel.Value) is ITextChannel channel) + if (await client.GetChannelAsync(weeklyScheduleChannel.Value) is ITextChannel channel) { return Result.Ok(channel); } - _logger.LogWarning("Guild's weekly schedule channel wasn't found, or might not be a Text Channel {GuildId} {WeeklyScheduleChannel}", guildId, weeklyScheduleChannel.Value); + logger.LogWarning("Guild's weekly schedule channel wasn't found, or might not be a Text Channel {GuildId} {WeeklyScheduleChannel}", guildId, weeklyScheduleChannel.Value); return Result.Fail("Weekly schedule channel not found"); } catch (Exception e) @@ -148,23 +139,23 @@ public async Task> GetAnnouncementRoleAsync(ulong? guildId) var optionsResult = await GetAsync(guildId); if (optionsResult.IsFailed) { - _logger.LogWarning("Guild doesn't have any document when trying to get announcement role {GuildId}", guildId); + logger.LogWarning("Guild doesn't have any document when trying to get announcement role {GuildId}", guildId); return optionsResult.ToResult(); } var announcementRoleId = optionsResult.Value?.AnnouncementRoleId; if (!announcementRoleId.HasValue) { - _logger.LogDebug("Guild doesn't have a announcement role set {GuildId}", guildId); + logger.LogDebug("Guild doesn't have a announcement role set {GuildId}", guildId); return Result.Fail("Announcement role not set"); } - if (_client.GetGuild(guildId.Value).GetRole(announcementRoleId.Value) is IRole announcementRole) + if (client.GetGuild(guildId.Value).GetRole(announcementRoleId.Value) is IRole announcementRole) { return Result.Ok(announcementRole); } - _logger.LogWarning("Guild's announcement role wasn't found {GuildId} {AnnouncementRoleId}", guildId, announcementRoleId); + logger.LogWarning("Guild's announcement role wasn't found {GuildId} {AnnouncementRoleId}", guildId, announcementRoleId); return Result.Fail("Announcement role not found"); } catch (Exception e) diff --git a/src/Miha.Logic/Services/UserService.cs b/src/Miha.Logic/Services/UserService.cs index 764ead2..72248ea 100644 --- a/src/Miha.Logic/Services/UserService.cs +++ b/src/Miha.Logic/Services/UserService.cs @@ -9,23 +9,14 @@ namespace Miha.Logic.Services; -public partial class UserService : DocumentService, IUserService +public partial class UserService( + IUserRepository repository, + ILogger logger) : DocumentService(repository, logger), IUserService { - private readonly IUserRepository _repository; - private readonly ILogger _logger; - - public UserService( - IUserRepository repository, - ILogger logger) : base(repository, logger) - { - _repository = repository; - _logger = logger; - } - public async Task>> GetAllUsersWithBirthdayForWeekAsync(LocalDate weekDate, bool includeAlreadyAnnounced) { var weekNumberInYear = WeekYearRules.Iso.GetWeekOfWeekYear(weekDate); - var usersWithBirthday = await _repository.GetAllUsersWithBirthdayEnabledAsync(); + var usersWithBirthday = await repository.GetAllUsersWithBirthdayEnabledAsync(); // Add a method to User document which will return the localDate or AnnualDate in EST of their birthday @@ -56,7 +47,7 @@ public async Task>> GetAllUsersWithBirthdayForW return Result.Fail("Couldn't find the usr_Id in the passed link"); } - return await _repository.UpsertAsync(userId, doc => doc.VrcUserId = usrId.Value); + return await repository.UpsertAsync(userId, doc => doc.VrcUserId = usrId.Value); } catch (Exception e) { diff --git a/src/Miha.Redis/Miha.Redis.csproj b/src/Miha.Redis/Miha.Redis.csproj index a2b75a1..8f23898 100644 --- a/src/Miha.Redis/Miha.Redis.csproj +++ b/src/Miha.Redis/Miha.Redis.csproj @@ -1,9 +1,10 @@ - net7.0 + net8.0 enable enable + 12 diff --git a/src/Miha.Redis/Repositories/BirthdayJobRepository.cs b/src/Miha.Redis/Repositories/BirthdayJobRepository.cs index 329db89..c3cc33e 100644 --- a/src/Miha.Redis/Repositories/BirthdayJobRepository.cs +++ b/src/Miha.Redis/Repositories/BirthdayJobRepository.cs @@ -4,10 +4,4 @@ namespace Miha.Redis.Repositories; -public class BirthdayJobRepository : DocumentRepository, IBirthdayJobRepository -{ - public BirthdayJobRepository(IRedisConnectionProvider provider) : base(provider) - { - - } -} +public class BirthdayJobRepository(IRedisConnectionProvider provider) : DocumentRepository(provider), IBirthdayJobRepository; diff --git a/src/Miha.Redis/Repositories/DocumentRepository.cs b/src/Miha.Redis/Repositories/DocumentRepository.cs index f96c6a8..b40aed2 100644 --- a/src/Miha.Redis/Repositories/DocumentRepository.cs +++ b/src/Miha.Redis/Repositories/DocumentRepository.cs @@ -5,18 +5,11 @@ namespace Miha.Redis.Repositories; -public class DocumentRepository : IDocumentRepository where T : Document, new() +public class DocumentRepository(IRedisConnectionProvider provider) : IDocumentRepository where T : Document, new() { - private readonly IRedisConnectionProvider _provider; - - public DocumentRepository(IRedisConnectionProvider provider) - { - _provider = provider; - } - public async Task> GetAllAsync() { - var collection = _provider.RedisCollection(); + var collection = provider.RedisCollection(); return await collection.ToListAsync(); } @@ -27,7 +20,7 @@ public async Task> GetAllAsync() id.Should().NotBeNullOrEmpty(); - var collection = _provider.RedisCollection(); + var collection = provider.RedisCollection(); return await collection.FindByIdAsync(id); } @@ -37,7 +30,7 @@ public async Task> GetAllAsync() var id = document.Id.ToString(); id.Should().NotBeNullOrEmpty(); - var collection = _provider.RedisCollection(); + var collection = provider.RedisCollection(); var doc = await collection.FindByIdAsync(id); var exists = doc is not null; @@ -60,7 +53,7 @@ public async Task> GetAllAsync() var id = documentId.ToString() ?? string.Empty; id.Should().NotBeNullOrEmpty(); - var collection = _provider.RedisCollection(); + var collection = provider.RedisCollection(); var document = await collection.FindByIdAsync(id); var exists = document is not null; @@ -84,7 +77,7 @@ public async Task DeleteAsync(ulong? documentId, bool successIfNotFound = false) { documentId.Should().NotBeNull(); - var collection = _provider.RedisCollection(); + var collection = provider.RedisCollection(); var document = await collection.FindByIdAsync(documentId.ToString()!); if (successIfNotFound && document is null) diff --git a/src/Miha.Redis/Repositories/GuildRepository.cs b/src/Miha.Redis/Repositories/GuildRepository.cs index 6fa6caa..3fe59ff 100644 --- a/src/Miha.Redis/Repositories/GuildRepository.cs +++ b/src/Miha.Redis/Repositories/GuildRepository.cs @@ -4,10 +4,4 @@ namespace Miha.Redis.Repositories; -public class GuildRepository : DocumentRepository, IGuildRepository -{ - public GuildRepository(IRedisConnectionProvider provider) : base(provider) - { - - } -} +public class GuildRepository(IRedisConnectionProvider provider) : DocumentRepository(provider), IGuildRepository; diff --git a/src/Miha.Redis/Repositories/UserRepository.cs b/src/Miha.Redis/Repositories/UserRepository.cs index ef0cf7b..c2940f0 100644 --- a/src/Miha.Redis/Repositories/UserRepository.cs +++ b/src/Miha.Redis/Repositories/UserRepository.cs @@ -6,18 +6,13 @@ namespace Miha.Redis.Repositories; -public partial class UserRepository : DocumentRepository, IUserRepository +public partial class UserRepository( + IRedisConnectionProvider provider, + ILogger logger) + : DocumentRepository(provider), IUserRepository { - private readonly IRedisConnectionProvider _provider; - private readonly ILogger _logger; - - public UserRepository( - IRedisConnectionProvider provider, - ILogger logger) : base(provider) - { - _provider = provider; - _logger = logger; - } + private readonly IRedisConnectionProvider _provider = provider; + private readonly ILogger _logger = logger; public async Task> GetAllUsersWithBirthdayEnabledAsync() { diff --git a/src/Miha.Redis/Services/RedisIndexCreationService.cs b/src/Miha.Redis/Services/RedisIndexCreationService.cs index 87fbc77..79fff96 100644 --- a/src/Miha.Redis/Services/RedisIndexCreationService.cs +++ b/src/Miha.Redis/Services/RedisIndexCreationService.cs @@ -7,18 +7,11 @@ namespace Miha.Redis.Services; -public partial class RedisIndexCreationService : IHostedService +public partial class RedisIndexCreationService( + IRedisConnectionProvider provider, + ILogger logger) : IHostedService { - private readonly IRedisConnectionProvider _provider; - private readonly ILogger _logger; - - public RedisIndexCreationService( - IRedisConnectionProvider provider, - ILogger logger) - { - _provider = provider; - _logger = logger; - } + private readonly ILogger _logger = logger; public async Task StartAsync(CancellationToken cancellationToken) { @@ -30,7 +23,7 @@ public async Task StartAsync(CancellationToken cancellationToken) { LogInfoIndexingType(model.Name); - await _provider.Connection.CreateIndexAsync(model); + await provider.Connection.CreateIndexAsync(model); } LogInfoIndexedModels(); diff --git a/src/Miha.Redis/Services/RedisSeedService.cs b/src/Miha.Redis/Services/RedisSeedService.cs index f9b7112..977d325 100644 --- a/src/Miha.Redis/Services/RedisSeedService.cs +++ b/src/Miha.Redis/Services/RedisSeedService.cs @@ -5,27 +5,18 @@ namespace Miha.Redis.Services; -public class RedisSeedService +public class RedisSeedService( + IOptions redisOptions, + IGuildRepository guildRepository, + ILogger logger) { - private readonly RedisSeedOptions _seedOptions; - private readonly IGuildRepository _guildRepository; - private readonly ILogger _logger; - - public RedisSeedService( - IOptions redisOptions, - IGuildRepository guildRepository, - ILogger logger) - { - _seedOptions = redisOptions.Value.SeedOptions; - _guildRepository = guildRepository; - _logger = logger; - } + private readonly RedisSeedOptions _seedOptions = redisOptions.Value.SeedOptions; public async Task SeedGuildAsync(ulong? guildId) { if (_seedOptions.GuildOptions is null) { - _logger.LogDebug("Seed options are null, skipping seeding"); + logger.LogDebug("Seed options are null, skipping seeding"); return; } @@ -34,15 +25,15 @@ public async Task SeedGuildAsync(ulong? guildId) throw new ArgumentNullException(nameof(guildId), "A guildId is required for guild document seeding"); } - var existingGuildDoc = await _guildRepository.GetAsync(guildId.Value); + var existingGuildDoc = await guildRepository.GetAsync(guildId.Value); if (existingGuildDoc is not null) { - _logger.LogInformation("Guild document already exists, no guild document seeding is required"); + logger.LogInformation("Guild document already exists, no guild document seeding is required"); return; } - _logger.LogInformation("Seeding guild document with configured seed guild options {@GuildOptions}", _seedOptions.GuildOptions); + logger.LogInformation("Seeding guild document with configured seed guild options {@GuildOptions}", _seedOptions.GuildOptions); var guildDoc = new GuildDocument { @@ -54,8 +45,8 @@ public async Task SeedGuildAsync(ulong? guildId) LogChannel = _seedOptions.GuildOptions.LogChannel }; - var newGuildDoc = await _guildRepository.UpsertAsync(guildDoc); + var newGuildDoc = await guildRepository.UpsertAsync(guildDoc); - _logger.LogInformation("Guild document seeded {@GuildDocument}", newGuildDoc); + logger.LogInformation("Guild document seeded {@GuildDocument}", newGuildDoc); } } diff --git a/src/Miha.Shared/Miha.Shared.csproj b/src/Miha.Shared/Miha.Shared.csproj index df0c19c..3a0e0c2 100644 --- a/src/Miha.Shared/Miha.Shared.csproj +++ b/src/Miha.Shared/Miha.Shared.csproj @@ -1,9 +1,10 @@ - net7.0 + net8.0 enable enable + 12 diff --git a/src/Miha.Shared/ZonedClocks/EasternStandardZonedClock.cs b/src/Miha.Shared/ZonedClocks/EasternStandardZonedClock.cs index 4ca4193..65db450 100644 --- a/src/Miha.Shared/ZonedClocks/EasternStandardZonedClock.cs +++ b/src/Miha.Shared/ZonedClocks/EasternStandardZonedClock.cs @@ -4,18 +4,11 @@ namespace Miha.Shared.ZonedClocks; -public class EasternStandardZonedClock : ZonedClock, IEasternStandardZonedClock +public class EasternStandardZonedClock(IClock clock) : ZonedClock(clock, DateTimeZoneProviders.Tzdb[Timezones.IanaEasternTime], CalendarSystem.Iso), IEasternStandardZonedClock { - private readonly DateTimeZone _timeZone; - private readonly BclDateTimeZone _bclDateTimeZone; - private readonly TimeZoneInfo _timeZoneInfo; - - public EasternStandardZonedClock(IClock clock) : base(clock, DateTimeZoneProviders.Tzdb[Timezones.IanaEasternTime], CalendarSystem.Iso) - { - _timeZone = DateTimeZoneProviders.Tzdb[Timezones.IanaEasternTime]; - _bclDateTimeZone = (BclDateTimeZone) DateTimeZoneProviders.Bcl[Timezones.IanaEasternTime]; - _timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(Timezones.WindowsEasternTime); - } + private readonly DateTimeZone _timeZone = DateTimeZoneProviders.Tzdb[Timezones.IanaEasternTime]; + private readonly BclDateTimeZone _bclDateTimeZone = (BclDateTimeZone) DateTimeZoneProviders.Bcl[Timezones.IanaEasternTime]; + private readonly TimeZoneInfo _timeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(Timezones.WindowsEasternTime); public DateTimeZone GetTzdbTimeZone() => _timeZone; public BclDateTimeZone GetBclTimeZone() => _bclDateTimeZone; diff --git a/src/Miha/Health/MihaHealthCheck.cs b/src/Miha/Health/MihaHealthCheck.cs index 48ee168..4968dbb 100644 --- a/src/Miha/Health/MihaHealthCheck.cs +++ b/src/Miha/Health/MihaHealthCheck.cs @@ -9,25 +9,14 @@ namespace Miha.Health; -public class MihaHealthCheck : IHealthCheck +public class MihaHealthCheck(DiscordSocketClient client, IRedisConnectionProvider provider) : IHealthCheck { - private readonly DiscordSocketClient _client; - private readonly IRedisConnectionProvider _provider; - - public MihaHealthCheck( - DiscordSocketClient client, - IRedisConnectionProvider provider) - { - _client = client; - _provider = provider; - } - public async Task ExecuteAsync(CancellationToken cancellationToken) { try { - var redisPing = await _provider.Connection.ExecuteAsync("PING"); - var discordState = _client.ConnectionState; + var redisPing = await provider.Connection.ExecuteAsync("PING"); + var discordState = client.ConnectionState; var discord = discordState.ToString(); var redis = redisPing.ToString(CultureInfo.InvariantCulture); diff --git a/src/Miha/Miha.csproj b/src/Miha/Miha.csproj index 9e15942..ce95a81 100644 --- a/src/Miha/Miha.csproj +++ b/src/Miha/Miha.csproj @@ -2,10 +2,11 @@ Exe - net7.0 + net8.0 enable enable Linux + 12 diff --git a/src/Miha/Services/BirthdayScannerService.cs b/src/Miha/Services/BirthdayScannerService.cs index c7f4520..3b858ef 100644 --- a/src/Miha/Services/BirthdayScannerService.cs +++ b/src/Miha/Services/BirthdayScannerService.cs @@ -10,30 +10,15 @@ namespace Miha.Services; /// /// Scans birthdays, and creates BirthdayJobDocuments /// -public class BirthdayScannerService : BackgroundService +public class BirthdayScannerService( + IEasternStandardZonedClock easternStandardZonedClock, + IUserService userService, + IBirthdayJobService birthdayJobService, + ILogger logger) : BackgroundService { private const string Schedule = "*/5 8-19 * * *"; // https://crontab.cronhub.io/ - private readonly IEasternStandardZonedClock _easternStandardZonedClock; - private readonly IUserService _userService; - private readonly IBirthdayJobService _birthdayJobService; - private readonly ILogger _logger; - - private readonly CronExpression _cron; - - public BirthdayScannerService( - IEasternStandardZonedClock easternStandardZonedClock, - IUserService userService, - IBirthdayJobService birthdayJobService, - ILogger logger) - { - _easternStandardZonedClock = easternStandardZonedClock; - _userService = userService; - _birthdayJobService = birthdayJobService; - _logger = logger; - - _cron = CronExpression.Parse(Schedule, CronFormat.Standard); - } + private readonly CronExpression _cron = CronExpression.Parse(Schedule, CronFormat.Standard); protected override async Task ExecuteAsync(CancellationToken stoppingToken) { @@ -41,45 +26,45 @@ protected override async Task ExecuteAsync(CancellationToken stoppingToken) { await ScanBirthdaysAsync(); - var utcNow = _easternStandardZonedClock.GetCurrentInstant().ToDateTimeUtc(); - var nextUtc = _cron.GetNextOccurrence(DateTimeOffset.UtcNow, _easternStandardZonedClock.GetTimeZoneInfo()); + var utcNow = easternStandardZonedClock.GetCurrentInstant().ToDateTimeUtc(); + var nextUtc = _cron.GetNextOccurrence(DateTimeOffset.UtcNow, easternStandardZonedClock.GetTimeZoneInfo()); if (nextUtc is null) { - _logger.LogWarning("Next utc occurence is null"); + logger.LogWarning("Next utc occurence is null"); await Task.Delay(TimeSpan.FromMinutes(1), stoppingToken); continue; } - _logger.LogDebug("Waiting {Time}", nextUtc.Value - utcNow); + logger.LogDebug("Waiting {Time}", nextUtc.Value - utcNow); await Task.Delay(nextUtc.Value - utcNow, stoppingToken); } } private async Task ScanBirthdaysAsync() { - _logger.LogInformation("Scanning for birthdays"); + logger.LogInformation("Scanning for birthdays"); - var today = _easternStandardZonedClock.GetCurrentDate(); - var unannouncedBirthdaysThisWeek = await _userService.GetAllUsersWithBirthdayForWeekAsync(today, false); + var today = easternStandardZonedClock.GetCurrentDate(); + var unannouncedBirthdaysThisWeek = await userService.GetAllUsersWithBirthdayForWeekAsync(today, false); if (unannouncedBirthdaysThisWeek.IsFailed) { - _logger.LogError("Failed getting un-announced birthdays"); + logger.LogError("Failed getting un-announced birthdays"); return; } if (!unannouncedBirthdaysThisWeek.Value.Any()) { - _logger.LogInformation("Found no un-announced birthdays this week"); + logger.LogInformation("Found no un-announced birthdays this week"); return; } - var birthdayJobs = await _birthdayJobService.GetAllAsync(); + var birthdayJobs = await birthdayJobService.GetAllAsync(); if (birthdayJobs.IsFailed) { - _logger.LogError("Failed getting birthday jobs"); + logger.LogError("Failed getting birthday jobs"); return; } @@ -87,12 +72,12 @@ private async Task ScanBirthdaysAsync() if (!unscheduledBirthdays.Any()) { - _logger.LogInformation("All birthdays for this week are already scheduled"); + logger.LogInformation("All birthdays for this week are already scheduled"); } foreach (var unscheduledBirthday in unscheduledBirthdays) { - var result = await _birthdayJobService.UpsertAsync(new BirthdayJobDocument + var result = await birthdayJobService.UpsertAsync(new BirthdayJobDocument { Id = unscheduledBirthday.Id, UserDocumentId = unscheduledBirthday.Id, @@ -101,7 +86,7 @@ private async Task ScanBirthdaysAsync() if (result.IsFailed) { - _logger.LogWarning("Birthday job creation failed for an unscheduled birthday {Id}", unscheduledBirthday.Id); + logger.LogWarning("Birthday job creation failed for an unscheduled birthday {Id}", unscheduledBirthday.Id); } } }