diff --git a/PluralKit.Bot/Commands/Admin.cs b/PluralKit.Bot/Commands/Admin.cs index 15a2c4d2..3a0d3823 100644 --- a/PluralKit.Bot/Commands/Admin.cs +++ b/PluralKit.Bot/Commands/Admin.cs @@ -7,12 +7,10 @@ namespace PluralKit.Bot; public class Admin { private readonly BotConfig _botConfig; - private readonly ModelRepository _repo; - public Admin(BotConfig botConfig, ModelRepository repo) + public Admin(BotConfig botConfig) { _botConfig = botConfig; - _repo = repo; } public async Task UpdateSystemId(Context ctx) @@ -27,14 +25,14 @@ public class Admin if (!Regex.IsMatch(newHid, "^[a-z]{5}$")) throw new PKError($"Invalid new system ID `{newHid}`."); - var existingSystem = await _repo.GetSystemByHid(newHid); + var existingSystem = await ctx.Repository.GetSystemByHid(newHid); if (existingSystem != null) throw new PKError($"Another system already exists with ID `{newHid}`."); if (!await ctx.PromptYesNo($"Change system ID of `{target.Hid}` to `{newHid}`?", "Change")) throw new PKError("ID change cancelled."); - await _repo.UpdateSystem(target.Id, new SystemPatch { Hid = newHid }); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Hid = newHid }); await ctx.Reply($"{Emojis.Success} System ID updated (`{target.Hid}` -> `{newHid}`)."); } @@ -50,7 +48,7 @@ public class Admin if (!Regex.IsMatch(newHid, "^[a-z]{5}$")) throw new PKError($"Invalid new member ID `{newHid}`."); - var existingMember = await _repo.GetMemberByHid(newHid); + var existingMember = await ctx.Repository.GetMemberByHid(newHid); if (existingMember != null) throw new PKError($"Another member already exists with ID `{newHid}`."); @@ -60,7 +58,7 @@ public class Admin )) throw new PKError("ID change cancelled."); - await _repo.UpdateMember(target.Id, new MemberPatch { Hid = newHid }); + await ctx.Repository.UpdateMember(target.Id, new MemberPatch { Hid = newHid }); await ctx.Reply($"{Emojis.Success} Member ID updated (`{target.Hid}` -> `{newHid}`)."); } @@ -76,7 +74,7 @@ public class Admin if (!Regex.IsMatch(newHid, "^[a-z]{5}$")) throw new PKError($"Invalid new group ID `{newHid}`."); - var existingGroup = await _repo.GetGroupByHid(newHid); + var existingGroup = await ctx.Repository.GetGroupByHid(newHid); if (existingGroup != null) throw new PKError($"Another group already exists with ID `{newHid}`."); @@ -85,7 +83,7 @@ public class Admin )) throw new PKError("ID change cancelled."); - await _repo.UpdateGroup(target.Id, new GroupPatch { Hid = newHid }); + await ctx.Repository.UpdateGroup(target.Id, new GroupPatch { Hid = newHid }); await ctx.Reply($"{Emojis.Success} Group ID updated (`{target.Hid}` -> `{newHid}`)."); } @@ -97,7 +95,7 @@ public class Admin if (target == null) throw new PKError("Unknown system."); - var config = await _repo.GetSystemConfig(target.Id); + var config = await ctx.Repository.GetSystemConfig(target.Id); var currentLimit = config.MemberLimitOverride ?? Limits.MaxMemberCount; if (!ctx.HasNext()) @@ -113,7 +111,7 @@ public class Admin if (!await ctx.PromptYesNo($"Update member limit from **{currentLimit}** to **{newLimit}**?", "Update")) throw new PKError("Member limit change cancelled."); - await _repo.UpdateSystemConfig(target.Id, new SystemConfigPatch { MemberLimitOverride = newLimit }); + await ctx.Repository.UpdateSystemConfig(target.Id, new SystemConfigPatch { MemberLimitOverride = newLimit }); await ctx.Reply($"{Emojis.Success} Member limit updated."); } @@ -125,7 +123,7 @@ public class Admin if (target == null) throw new PKError("Unknown system."); - var config = await _repo.GetSystemConfig(target.Id); + var config = await ctx.Repository.GetSystemConfig(target.Id); var currentLimit = config.GroupLimitOverride ?? Limits.MaxGroupCount; if (!ctx.HasNext()) @@ -141,7 +139,7 @@ public class Admin if (!await ctx.PromptYesNo($"Update group limit from **{currentLimit}** to **{newLimit}**?", "Update")) throw new PKError("Group limit change cancelled."); - await _repo.UpdateSystemConfig(target.Id, new SystemConfigPatch { GroupLimitOverride = newLimit }); + await ctx.Repository.UpdateSystemConfig(target.Id, new SystemConfigPatch { GroupLimitOverride = newLimit }); await ctx.Reply($"{Emojis.Success} Group limit updated."); } } \ No newline at end of file diff --git a/PluralKit.Bot/Commands/Api.cs b/PluralKit.Bot/Commands/Api.cs index 6911c0f4..2396a347 100644 --- a/PluralKit.Bot/Commands/Api.cs +++ b/PluralKit.Bot/Commands/Api.cs @@ -16,13 +16,11 @@ public class Api private readonly BotConfig _botConfig; private readonly DispatchService _dispatch; - private readonly ModelRepository _repo; private readonly PrivateChannelService _dmCache; - public Api(BotConfig botConfig, ModelRepository repo, DispatchService dispatch, PrivateChannelService dmCache) + public Api(BotConfig botConfig, DispatchService dispatch, PrivateChannelService dmCache) { _botConfig = botConfig; - _repo = repo; _dispatch = dispatch; _dmCache = dmCache; } @@ -32,7 +30,7 @@ public class Api ctx.CheckSystem(); // Get or make a token - var token = ctx.System.Token ?? await MakeAndSetNewToken(ctx.System); + var token = ctx.System.Token ?? await MakeAndSetNewToken(ctx, ctx.System); try { @@ -65,9 +63,9 @@ public class Api } } - private async Task MakeAndSetNewToken(PKSystem system) + private async Task MakeAndSetNewToken(Context ctx, PKSystem system) { - system = await _repo.UpdateSystem(system.Id, new SystemPatch { Token = StringUtils.GenerateToken() }); + system = await ctx.Repository.UpdateSystem(system.Id, new SystemPatch { Token = StringUtils.GenerateToken() }); return system.Token; } @@ -95,7 +93,7 @@ public class Api // Make the new token after sending the first DM; this ensures if we can't DM, we also don't end up // breaking their existing token as a side effect :) - var token = await MakeAndSetNewToken(ctx.System); + var token = await MakeAndSetNewToken(ctx, ctx.System); await ctx.Rest.CreateMessage(dm, new MessageRequest { Content = token }); if (_botConfig.IsBetaBot) @@ -132,7 +130,7 @@ public class Api if (await ctx.MatchClear("your system's webhook URL")) { - await _repo.UpdateSystem(ctx.System.Id, new SystemPatch { WebhookUrl = null, WebhookToken = null }); + await ctx.Repository.UpdateSystem(ctx.System.Id, new SystemPatch { WebhookUrl = null, WebhookToken = null }); await ctx.Reply($"{Emojis.Success} System webhook URL removed."); return; @@ -156,7 +154,7 @@ public class Api var newToken = StringUtils.GenerateToken(); - await _repo.UpdateSystem(ctx.System.Id, new SystemPatch { WebhookUrl = newUrl, WebhookToken = newToken }); + await ctx.Repository.UpdateSystem(ctx.System.Id, new SystemPatch { WebhookUrl = newUrl, WebhookToken = newToken }); await ctx.Reply($"{Emojis.Success} Successfully the new webhook URL for your system." + $"\n\n{Emojis.Warn} The following token is used to authenticate requests from PluralKit to you." diff --git a/PluralKit.Bot/Commands/Autoproxy.cs b/PluralKit.Bot/Commands/Autoproxy.cs index 07efabfd..b5ebf2c8 100644 --- a/PluralKit.Bot/Commands/Autoproxy.cs +++ b/PluralKit.Bot/Commands/Autoproxy.cs @@ -11,15 +11,6 @@ namespace PluralKit.Bot; public class Autoproxy { - private readonly IDatabase _db; - private readonly ModelRepository _repo; - - public Autoproxy(IDatabase db, ModelRepository repo) - { - _db = db; - _repo = repo; - } - public async Task SetAutoproxyMode(Context ctx) { // no need to check account here, it's already done at CommandTree @@ -99,8 +90,8 @@ public class Autoproxy var fronters = ctx.MessageContext.LastSwitchMembers; var relevantMember = ctx.MessageContext.AutoproxyMode switch { - AutoproxyMode.Front => fronters.Length > 0 ? await _repo.GetMember(fronters[0]) : null, - AutoproxyMode.Member => await _repo.GetMember(ctx.MessageContext.AutoproxyMember.Value), + AutoproxyMode.Front => fronters.Length > 0 ? await ctx.Repository.GetMember(fronters[0]) : null, + AutoproxyMode.Member => await ctx.Repository.GetMember(ctx.MessageContext.AutoproxyMember.Value), _ => null }; @@ -145,9 +136,9 @@ public class Autoproxy private async Task UpdateAutoproxy(Context ctx, AutoproxyMode autoproxyMode, MemberId? autoproxyMember) { - await _repo.GetSystemGuild(ctx.Guild.Id, ctx.System.Id); + await ctx.Repository.GetSystemGuild(ctx.Guild.Id, ctx.System.Id); var patch = new SystemGuildPatch { AutoproxyMode = autoproxyMode, AutoproxyMember = autoproxyMember }; - await _repo.UpdateSystemGuild(ctx.System.Id, ctx.Guild.Id, patch); + await ctx.Repository.UpdateSystemGuild(ctx.System.Id, ctx.Guild.Id, patch); } } \ No newline at end of file diff --git a/PluralKit.Bot/Commands/Checks.cs b/PluralKit.Bot/Commands/Checks.cs index c410ab01..701ace1a 100644 --- a/PluralKit.Bot/Commands/Checks.cs +++ b/PluralKit.Bot/Commands/Checks.cs @@ -15,10 +15,8 @@ public class Checks { private readonly BotConfig _botConfig; private readonly IDiscordCache _cache; - private readonly IDatabase _db; private readonly ProxyMatcher _matcher; private readonly ProxyService _proxy; - private readonly ModelRepository _repo; private readonly DiscordApiClient _rest; private readonly PermissionSet[] requiredPermissions = @@ -28,13 +26,10 @@ public class Checks PermissionSet.ManageWebhooks, PermissionSet.ReadMessageHistory }; - public Checks(DiscordApiClient rest, IDiscordCache cache, IDatabase db, ModelRepository repo, - BotConfig botConfig, ProxyService proxy, ProxyMatcher matcher) + public Checks(DiscordApiClient rest, IDiscordCache cache, BotConfig botConfig, ProxyService proxy, ProxyMatcher matcher) { _rest = rest; _cache = cache; - _db = db; - _repo = repo; _botConfig = botConfig; _proxy = proxy; _matcher = matcher; @@ -216,7 +211,7 @@ public class Checks if (messageId == null || channelId == null) throw new PKError(failedToGetMessage); - var proxiedMsg = await _db.Execute(conn => _repo.GetMessage(conn, messageId.Value)); + var proxiedMsg = await ctx.Database.Execute(conn => ctx.Repository.GetMessage(conn, messageId.Value)); if (proxiedMsg != null) { await ctx.Reply($"{Emojis.Success} This message was proxied successfully."); @@ -250,8 +245,8 @@ public class Checks throw new PKError("Unable to get the channel associated with this message."); // using channel.GuildId here since _rest.GetMessage() doesn't return the GuildId - var context = await _repo.GetMessageContext(msg.Author.Id, channel.GuildId.Value, msg.ChannelId); - var members = (await _repo.GetProxyMembers(msg.Author.Id, channel.GuildId.Value)).ToList(); + var context = await ctx.Repository.GetMessageContext(msg.Author.Id, channel.GuildId.Value, msg.ChannelId); + var members = (await ctx.Repository.GetProxyMembers(msg.Author.Id, channel.GuildId.Value)).ToList(); // Run everything through the checks, catch the ProxyCheckFailedException, and reply with the error message. try diff --git a/PluralKit.Bot/Commands/Config.cs b/PluralKit.Bot/Commands/Config.cs index 9061cf80..50637dad 100644 --- a/PluralKit.Bot/Commands/Config.cs +++ b/PluralKit.Bot/Commands/Config.cs @@ -11,13 +11,6 @@ using PluralKit.Core; namespace PluralKit.Bot; public class Config { - private readonly ModelRepository _repo; - - public Config(ModelRepository repo) - { - _repo = repo; - } - private record PaginatedConfigItem(string Key, string Description, string? CurrentValue, string DefaultValue); public async Task ShowConfig(Context ctx) @@ -141,7 +134,7 @@ public class Config return; } var patch = new AccountPatch { AllowAutoproxy = allow }; - await _repo.UpdateAccount(ctx.Author.Id, patch); + await ctx.Repository.UpdateAccount(ctx.Author.Id, patch); await ctx.Reply($"{Emojis.Success} Autoproxy {statusString} for account <@{ctx.Author.Id}>."); } @@ -181,7 +174,7 @@ public class Config else newTimeout = timeoutPeriod; } - await _repo.UpdateSystemConfig(ctx.System.Id, new() { LatchTimeout = (int?)newTimeout?.TotalSeconds }); + await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { LatchTimeout = (int?)newTimeout?.TotalSeconds }); if (newTimeout == null) await ctx.Reply($"{Emojis.Success} Latch timeout reset to default ({ProxyMatcher.DefaultLatchExpiryTime.ToTimeSpan().Humanize(4)})."); @@ -199,7 +192,7 @@ public class Config if (await ctx.MatchClear()) { - await _repo.UpdateSystemConfig(ctx.System.Id, new() { UiTz = "UTC" }); + await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { UiTz = "UTC" }); await ctx.Reply($"{Emojis.Success} System time zone cleared (set to UTC)."); return; @@ -220,7 +213,7 @@ public class Config var msg = $"This will change the system time zone to **{zone.Id}**. The current time is **{currentTime.FormatZoned()}**. Is this correct?"; if (!await ctx.PromptYesNo(msg, "Change Timezone")) throw Errors.TimezoneChangeCancelled; - await _repo.UpdateSystemConfig(ctx.System.Id, new() { UiTz = zone.Id }); + await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { UiTz = zone.Id }); await ctx.Reply($"System time zone changed to **{zone.Id}**."); } @@ -308,7 +301,7 @@ public class Config await ctx.Reply(Response(true, ctx.Config.PingsEnabled)); else { - await _repo.UpdateSystemConfig(ctx.System.Id, new() { PingsEnabled = value }); + await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { PingsEnabled = value }); await ctx.Reply($"Reaction pings have now been {EnabledDisabled(value)}."); } } @@ -324,13 +317,13 @@ public class Config { if (ctx.MatchToggle()) { - await _repo.UpdateSystemConfig(ctx.System.Id, new() { MemberDefaultPrivate = true }); + await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { MemberDefaultPrivate = true }); await ctx.Reply("Newly created members will now have their privacy settings set to private."); } else { - await _repo.UpdateSystemConfig(ctx.System.Id, new() { MemberDefaultPrivate = false }); + await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { MemberDefaultPrivate = false }); await ctx.Reply("Newly created members will now have their privacy settings set to public."); } @@ -348,13 +341,13 @@ public class Config { if (ctx.MatchToggle()) { - await _repo.UpdateSystemConfig(ctx.System.Id, new() { GroupDefaultPrivate = true }); + await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { GroupDefaultPrivate = true }); await ctx.Reply("Newly created groups will now have their privacy settings set to private."); } else { - await _repo.UpdateSystemConfig(ctx.System.Id, new() { GroupDefaultPrivate = false }); + await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { GroupDefaultPrivate = false }); await ctx.Reply("Newly created groups will now have their privacy settings set to public."); } @@ -372,13 +365,13 @@ public class Config if (ctx.MatchToggle()) { - await _repo.UpdateSystemConfig(ctx.System.Id, new() { ShowPrivateInfo = true }); + await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { ShowPrivateInfo = true }); await ctx.Reply("Private information will now be **shown** when looking up your own info. Use the `-public` flag to hide it."); } else { - await _repo.UpdateSystemConfig(ctx.System.Id, new() { ShowPrivateInfo = false }); + await ctx.Repository.UpdateSystemConfig(ctx.System.Id, new() { ShowPrivateInfo = false }); await ctx.Reply("Private information will now be **hidden** when looking up your own info. Use the `-private` flag to show it."); } diff --git a/PluralKit.Bot/Commands/GroupMember.cs b/PluralKit.Bot/Commands/GroupMember.cs index 090cc0ca..02a6f8b5 100644 --- a/PluralKit.Bot/Commands/GroupMember.cs +++ b/PluralKit.Bot/Commands/GroupMember.cs @@ -8,15 +8,6 @@ namespace PluralKit.Bot; public class GroupMember { - private readonly IDatabase _db; - private readonly ModelRepository _repo; - - public GroupMember(IDatabase db, ModelRepository repo) - { - _db = db; - _repo = repo; - } - public async Task AddRemoveGroups(Context ctx, PKMember target, Groups.AddRemoveOperation op) { ctx.CheckSystem().CheckOwnMember(target); @@ -26,7 +17,7 @@ public class GroupMember .Distinct() .ToList(); - var existingGroups = (await _repo.GetMemberGroups(target.Id).ToListAsync()) + var existingGroups = (await ctx.Repository.GetMemberGroups(target.Id).ToListAsync()) .Select(g => g.Id) .Distinct() .ToList(); @@ -39,7 +30,7 @@ public class GroupMember .Where(group => !existingGroups.Contains(group)) .ToList(); - await _repo.AddGroupsToMember(target.Id, toAction); + await ctx.Repository.AddGroupsToMember(target.Id, toAction); } else if (op == Groups.AddRemoveOperation.Remove) { @@ -47,7 +38,7 @@ public class GroupMember .Where(group => existingGroups.Contains(group)) .ToList(); - await _repo.RemoveGroupsFromMember(target.Id, toAction); + await ctx.Repository.RemoveGroupsFromMember(target.Id, toAction); } else { @@ -62,7 +53,7 @@ public class GroupMember { var pctx = ctx.DirectLookupContextFor(target.System); - var groups = await _repo.GetMemberGroups(target.Id) + var groups = await ctx.Repository.GetMemberGroups(target.Id) .Where(g => g.Visibility.CanAccess(pctx)) .OrderBy(g => (g.DisplayName ?? g.Name), StringComparer.InvariantCultureIgnoreCase) .ToListAsync(); @@ -96,7 +87,7 @@ public class GroupMember .Distinct() .ToList(); - var existingMembersInGroup = (await _db.Execute(conn => conn.QueryMemberList(target.System, + var existingMembersInGroup = (await ctx.Database.Execute(conn => conn.QueryMemberList(target.System, new DatabaseViewsExt.ListQueryOptions { GroupFilter = target.Id }))) .Select(m => m.Id.Value) .Distinct() @@ -109,14 +100,14 @@ public class GroupMember toAction = members .Where(m => !existingMembersInGroup.Contains(m.Value)) .ToList(); - await _repo.AddMembersToGroup(target.Id, toAction); + await ctx.Repository.AddMembersToGroup(target.Id, toAction); } else if (op == Groups.AddRemoveOperation.Remove) { toAction = members .Where(m => existingMembersInGroup.Contains(m.Value)) .ToList(); - await _repo.RemoveMembersFromGroup(target.Id, toAction); + await ctx.Repository.RemoveMembersFromGroup(target.Id, toAction); } else { @@ -154,6 +145,6 @@ public class GroupMember var system = ctx.System; if (system?.Id == target.System) return system; - return await _repo.GetSystem(target.System)!; + return await ctx.Repository.GetSystem(target.System)!; } } \ No newline at end of file diff --git a/PluralKit.Bot/Commands/Groups.cs b/PluralKit.Bot/Commands/Groups.cs index a4851210..c2dbb493 100644 --- a/PluralKit.Bot/Commands/Groups.cs +++ b/PluralKit.Bot/Commands/Groups.cs @@ -23,16 +23,12 @@ public class Groups } private readonly HttpClient _client; - private readonly IDatabase _db; private readonly DispatchService _dispatch; private readonly EmbedService _embeds; - private readonly ModelRepository _repo; - public Groups(IDatabase db, ModelRepository repo, EmbedService embeds, HttpClient client, + public Groups(EmbedService embeds, HttpClient client, DispatchService dispatch) { - _db = db; - _repo = repo; _embeds = embeds; _client = client; _dispatch = dispatch; @@ -48,14 +44,14 @@ public class Groups throw new PKError($"Group name too long ({groupName.Length}/{Limits.MaxGroupNameLength} characters)."); // Check group cap - var existingGroupCount = await _repo.GetSystemGroupCount(ctx.System.Id); + var existingGroupCount = await ctx.Repository.GetSystemGroupCount(ctx.System.Id); var groupLimit = ctx.Config.GroupLimitOverride ?? Limits.MaxGroupCount; if (existingGroupCount >= groupLimit) throw new PKError( $"System has reached the maximum number of groups ({groupLimit}). Please delete unused groups first in order to create new ones."); // Warn if there's already a group by this name - var existingGroup = await _repo.GetGroupByName(ctx.System.Id, groupName); + var existingGroup = await ctx.Repository.GetGroupByName(ctx.System.Id, groupName); if (existingGroup != null) { var msg = @@ -64,8 +60,10 @@ public class Groups throw new PKError("Group creation cancelled."); } - using var conn = await _db.Obtain(); - var newGroup = await _repo.CreateGroup(ctx.System.Id, groupName); + // todo: this is supposed to be a transaction, but it's not used in any useful way + // consider removing it? + using var conn = await ctx.Database.Obtain(); + var newGroup = await ctx.Repository.CreateGroup(ctx.System.Id, groupName); var dispatchData = new JObject(); dispatchData.Add("name", groupName); @@ -73,7 +71,7 @@ public class Groups if (ctx.Config.GroupDefaultPrivate) { var patch = new GroupPatch().WithAllPrivacy(PrivacyLevel.Private); - await _repo.UpdateGroup(newGroup.Id, patch, conn); + await ctx.Repository.UpdateGroup(newGroup.Id, patch, conn); dispatchData.Merge(patch.ToJson()); } @@ -111,7 +109,7 @@ public class Groups $"New group name too long ({newName.Length}/{Limits.MaxMemberNameLength} characters)."); // Warn if there's already a group by this name - var existingGroup = await _repo.GetGroupByName(ctx.System.Id, newName); + var existingGroup = await ctx.Repository.GetGroupByName(ctx.System.Id, newName); if (existingGroup != null && existingGroup.Id != target.Id) { var msg = @@ -120,7 +118,7 @@ public class Groups throw new PKError("Group rename cancelled."); } - await _repo.UpdateGroup(target.Id, new GroupPatch { Name = newName }); + await ctx.Repository.UpdateGroup(target.Id, new GroupPatch { Name = newName }); await ctx.Reply($"{Emojis.Success} Group name changed from **{target.Name}** to **{newName}**."); } @@ -172,7 +170,7 @@ public class Groups if (await ctx.MatchClear("this group's display name")) { var patch = new GroupPatch { DisplayName = Partial.Null() }; - await _repo.UpdateGroup(target.Id, patch); + await ctx.Repository.UpdateGroup(target.Id, patch); await ctx.Reply($"{Emojis.Success} Group display name cleared."); if (target.NamePrivacy == PrivacyLevel.Private) @@ -183,7 +181,7 @@ public class Groups var newDisplayName = ctx.RemainderOrNull(false).NormalizeLineEndSpacing(); var patch = new GroupPatch { DisplayName = Partial.Present(newDisplayName) }; - await _repo.UpdateGroup(target.Id, patch); + await ctx.Repository.UpdateGroup(target.Id, patch); await ctx.Reply($"{Emojis.Success} Group display name changed."); } @@ -229,7 +227,7 @@ public class Groups if (await ctx.MatchClear("this group's description")) { var patch = new GroupPatch { Description = Partial.Null() }; - await _repo.UpdateGroup(target.Id, patch); + await ctx.Repository.UpdateGroup(target.Id, patch); await ctx.Reply($"{Emojis.Success} Group description cleared."); } else @@ -239,7 +237,7 @@ public class Groups throw Errors.StringTooLongError("Description", description.Length, Limits.MaxDescriptionLength); var patch = new GroupPatch { Description = Partial.Present(description) }; - await _repo.UpdateGroup(target.Id, patch); + await ctx.Repository.UpdateGroup(target.Id, patch); await ctx.Reply($"{Emojis.Success} Group description changed."); } @@ -251,7 +249,7 @@ public class Groups { ctx.CheckOwnGroup(target); - await _repo.UpdateGroup(target.Id, new GroupPatch { Icon = null }); + await ctx.Repository.UpdateGroup(target.Id, new GroupPatch { Icon = null }); await ctx.Reply($"{Emojis.Success} Group icon cleared."); } @@ -261,7 +259,7 @@ public class Groups await AvatarUtils.VerifyAvatarOrThrow(_client, img.Url); - await _repo.UpdateGroup(target.Id, new GroupPatch { Icon = img.Url }); + await ctx.Repository.UpdateGroup(target.Id, new GroupPatch { Icon = img.Url }); var msg = img.Source switch { @@ -316,7 +314,7 @@ public class Groups { ctx.CheckOwnGroup(target); - await _repo.UpdateGroup(target.Id, new GroupPatch { BannerImage = null }); + await ctx.Repository.UpdateGroup(target.Id, new GroupPatch { BannerImage = null }); await ctx.Reply($"{Emojis.Success} Group banner image cleared."); } @@ -326,7 +324,7 @@ public class Groups await AvatarUtils.VerifyAvatarOrThrow(_client, img.Url, true); - await _repo.UpdateGroup(target.Id, new GroupPatch { BannerImage = img.Url }); + await ctx.Repository.UpdateGroup(target.Id, new GroupPatch { BannerImage = img.Url }); var msg = img.Source switch { @@ -382,7 +380,7 @@ public class Groups ctx.CheckOwnGroup(target); var patch = new GroupPatch { Color = Partial.Null() }; - await _repo.UpdateGroup(target.Id, patch); + await ctx.Repository.UpdateGroup(target.Id, patch); await ctx.Reply($"{Emojis.Success} Group color cleared."); } @@ -413,7 +411,7 @@ public class Groups if (!Regex.IsMatch(color, "^[0-9a-fA-F]{6}$")) throw Errors.InvalidColorError(color); var patch = new GroupPatch { Color = Partial.Present(color.ToLowerInvariant()) }; - await _repo.UpdateGroup(target.Id, patch); + await ctx.Repository.UpdateGroup(target.Id, patch); await ctx.Reply(embed: new EmbedBuilder() .Title($"{Emojis.Success} Group color changed.") @@ -490,7 +488,7 @@ public class Groups async Task SetAll(PrivacyLevel level) { - await _repo.UpdateGroup(target.Id, new GroupPatch().WithAllPrivacy(level)); + await ctx.Repository.UpdateGroup(target.Id, new GroupPatch().WithAllPrivacy(level)); if (level == PrivacyLevel.Private) await ctx.Reply( @@ -502,7 +500,7 @@ public class Groups async Task SetLevel(GroupPrivacySubject subject, PrivacyLevel level) { - await _repo.UpdateGroup(target.Id, new GroupPatch().WithPrivacy(subject, level)); + await ctx.Repository.UpdateGroup(target.Id, new GroupPatch().WithPrivacy(subject, level)); var subjectName = subject switch { @@ -570,7 +568,7 @@ public class Groups throw new PKError( $"Group deletion cancelled. Note that you must reply with your group ID (`{target.Hid}`) *verbatim*."); - await _repo.DeleteGroup(target.Id); + await ctx.Repository.DeleteGroup(target.Id); await ctx.Reply($"{Emojis.Success} Group deleted."); } @@ -580,6 +578,6 @@ public class Groups var system = ctx.System; if (system?.Id == target.System) return system; - return await _repo.GetSystem(target.System)!; + return await ctx.Repository.GetSystem(target.System)!; } } \ No newline at end of file diff --git a/PluralKit.Bot/Commands/Member.cs b/PluralKit.Bot/Commands/Member.cs index 883deb76..c06fc24a 100644 --- a/PluralKit.Bot/Commands/Member.cs +++ b/PluralKit.Bot/Commands/Member.cs @@ -14,17 +14,13 @@ namespace PluralKit.Bot; public class Member { private readonly HttpClient _client; - private readonly IDatabase _db; private readonly DispatchService _dispatch; private readonly EmbedService _embeds; - private readonly ModelRepository _repo; - public Member(EmbedService embeds, IDatabase db, ModelRepository repo, HttpClient client, + public Member(EmbedService embeds, HttpClient client, DispatchService dispatch) { _embeds = embeds; - _db = db; - _repo = repo; _client = client; _dispatch = dispatch; } @@ -39,23 +35,23 @@ public class Member throw Errors.StringTooLongError("Member name", memberName.Length, Limits.MaxMemberNameLength); // Warn if there's already a member by this name - var existingMember = await _repo.GetMemberByName(ctx.System.Id, memberName); + var existingMember = await ctx.Repository.GetMemberByName(ctx.System.Id, memberName); if (existingMember != null) { var msg = $"{Emojis.Warn} You already have a member in your system with the name \"{existingMember.NameFor(ctx)}\" (with ID `{existingMember.Hid}`). Do you want to create another member with the same name?"; if (!await ctx.PromptYesNo(msg, "Create")) throw new PKError("Member creation cancelled."); } - await using var conn = await _db.Obtain(); + await using var conn = await ctx.Database.Obtain(); // Enforce per-system member limit - var memberCount = await _repo.GetSystemMemberCount(ctx.System.Id); + var memberCount = await ctx.Repository.GetSystemMemberCount(ctx.System.Id); var memberLimit = ctx.Config.MemberLimitOverride ?? Limits.MaxMemberCount; if (memberCount >= memberLimit) throw Errors.MemberLimitReachedError(memberLimit); // Create the member - var member = await _repo.CreateMember(ctx.System.Id, memberName, conn); + var member = await ctx.Repository.CreateMember(ctx.System.Id, memberName, conn); memberCount++; JObject dispatchData = new JObject(); @@ -64,7 +60,7 @@ public class Member if (ctx.Config.MemberDefaultPrivate) { var patch = new MemberPatch().WithAllPrivacy(PrivacyLevel.Private); - await _repo.UpdateMember(member.Id, patch, conn); + await ctx.Repository.UpdateMember(member.Id, patch, conn); dispatchData.Merge(patch.ToJson()); } @@ -75,8 +71,7 @@ public class Member try { await AvatarUtils.VerifyAvatarOrThrow(_client, avatarArg.Url); - await _db.Execute(conn => - _repo.UpdateMember(member.Id, new MemberPatch { AvatarUrl = avatarArg.Url }, conn)); + await ctx.Repository.UpdateMember(member.Id, new MemberPatch { AvatarUrl = avatarArg.Url }, conn); dispatchData.Add("avatar_url", avatarArg.Url); } @@ -95,7 +90,7 @@ public class Member await ctx.Reply( $"{Emojis.Success} Member \"{memberName}\" (`{member.Hid}`) registered! Check out the getting started page for how to get a member up and running: https://pluralkit.me/start#create-a-member"); // todo: move this to ModelRepository - if (await _db.Execute(conn => conn.QuerySingleAsync("select has_private_members(@System)", + if (await ctx.Database.Execute(conn => conn.QuerySingleAsync("select has_private_members(@System)", new { System = ctx.System.Id })) && !ctx.Config.MemberDefaultPrivate) //if has private members await ctx.Reply( $"{Emojis.Warn} This member is currently **public**. To change this, use `pk;member {member.Hid} private`."); @@ -118,7 +113,7 @@ public class Member public async Task ViewMember(Context ctx, PKMember target) { - var system = await _repo.GetSystem(target.System); + var system = await ctx.Repository.GetSystem(target.System); await ctx.Reply( embed: await _embeds.CreateMemberEmbed(system, target, ctx.Guild, ctx.LookupContextFor(system.Id), ctx.Zone)); } diff --git a/PluralKit.Bot/Commands/MemberAvatar.cs b/PluralKit.Bot/Commands/MemberAvatar.cs index 4b3ceebd..c79de009 100644 --- a/PluralKit.Bot/Commands/MemberAvatar.cs +++ b/PluralKit.Bot/Commands/MemberAvatar.cs @@ -9,11 +9,9 @@ namespace PluralKit.Bot; public class MemberAvatar { private readonly HttpClient _client; - private readonly ModelRepository _repo; - public MemberAvatar(ModelRepository repo, HttpClient client) + public MemberAvatar(HttpClient client) { - _repo = repo; _client = client; } @@ -76,14 +74,14 @@ public class MemberAvatar public async Task ServerAvatar(Context ctx, PKMember target) { ctx.CheckGuildContext(); - var guildData = await _repo.GetMemberGuild(ctx.Guild.Id, target.Id); + var guildData = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id); await AvatarCommandTree(AvatarLocation.Server, ctx, target, guildData); } public async Task Avatar(Context ctx, PKMember target) { var guildData = ctx.Guild != null - ? await _repo.GetMemberGuild(ctx.Guild.Id, target.Id) + ? await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id) : null; await AvatarCommandTree(AvatarLocation.Member, ctx, target, guildData); @@ -159,9 +157,9 @@ public class MemberAvatar switch (location) { case AvatarLocation.Server: - return _repo.UpdateMemberGuild(target.Id, ctx.Guild.Id, new MemberGuildPatch { AvatarUrl = url }); + return ctx.Repository.UpdateMemberGuild(target.Id, ctx.Guild.Id, new MemberGuildPatch { AvatarUrl = url }); case AvatarLocation.Member: - return _repo.UpdateMember(target.Id, new MemberPatch { AvatarUrl = url }); + return ctx.Repository.UpdateMember(target.Id, new MemberPatch { AvatarUrl = url }); default: throw new ArgumentOutOfRangeException($"Unknown avatar location {location}"); } diff --git a/PluralKit.Bot/Commands/MemberEdit.cs b/PluralKit.Bot/Commands/MemberEdit.cs index f3f7a966..417419b8 100644 --- a/PluralKit.Bot/Commands/MemberEdit.cs +++ b/PluralKit.Bot/Commands/MemberEdit.cs @@ -13,11 +13,9 @@ namespace PluralKit.Bot; public class MemberEdit { private readonly HttpClient _client; - private readonly ModelRepository _repo; - public MemberEdit(ModelRepository repo, HttpClient client) + public MemberEdit(HttpClient client) { - _repo = repo; _client = client; } @@ -32,7 +30,7 @@ public class MemberEdit throw Errors.StringTooLongError("Member name", newName.Length, Limits.MaxMemberNameLength); // Warn if there's already a member by this name - var existingMember = await _repo.GetMemberByName(ctx.System.Id, newName); + var existingMember = await ctx.Repository.GetMemberByName(ctx.System.Id, newName); if (existingMember != null && existingMember.Id != target.Id) { var msg = @@ -42,7 +40,7 @@ public class MemberEdit // Rename the member var patch = new MemberPatch { Name = Partial.Present(newName) }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Member renamed."); if (newName.Contains(" ")) @@ -54,7 +52,7 @@ public class MemberEdit if (ctx.Guild != null) { - var memberGuildConfig = await _repo.GetMemberGuild(ctx.Guild.Id, target.Id); + var memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id); if (memberGuildConfig.DisplayName != null) await ctx.Reply( $"{Emojis.Note} Note that this member has a server name set ({memberGuildConfig.DisplayName}) in this server ({ctx.Guild.Name}), and will be proxied using that name here."); @@ -101,7 +99,7 @@ public class MemberEdit if (await ctx.MatchClear("this member's description")) { var patch = new MemberPatch { Description = Partial.Null() }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Member description cleared."); } else @@ -111,7 +109,7 @@ public class MemberEdit throw Errors.StringTooLongError("Description", description.Length, Limits.MaxDescriptionLength); var patch = new MemberPatch { Description = Partial.Present(description) }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Member description changed."); } @@ -152,7 +150,7 @@ public class MemberEdit if (await ctx.MatchClear("this member's pronouns")) { var patch = new MemberPatch { Pronouns = Partial.Null() }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Member pronouns cleared."); } else @@ -162,7 +160,7 @@ public class MemberEdit throw Errors.StringTooLongError("Pronouns", pronouns.Length, Limits.MaxPronounsLength); var patch = new MemberPatch { Pronouns = Partial.Present(pronouns) }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Member pronouns changed."); } @@ -174,7 +172,7 @@ public class MemberEdit async Task ClearBannerImage() { - await _repo.UpdateMember(target.Id, new MemberPatch { BannerImage = null }); + await ctx.Repository.UpdateMember(target.Id, new MemberPatch { BannerImage = null }); await ctx.Reply($"{Emojis.Success} Member banner image cleared."); } @@ -182,7 +180,7 @@ public class MemberEdit { await AvatarUtils.VerifyAvatarOrThrow(_client, img.Url, true); - await _repo.UpdateMember(target.Id, new MemberPatch { BannerImage = img.Url }); + await ctx.Repository.UpdateMember(target.Id, new MemberPatch { BannerImage = img.Url }); var msg = img.Source switch { @@ -233,7 +231,7 @@ public class MemberEdit ctx.CheckOwnMember(target); var patch = new MemberPatch { Color = Partial.Null() }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Member color cleared."); } @@ -267,7 +265,7 @@ public class MemberEdit if (!Regex.IsMatch(color, "^[0-9a-fA-F]{6}$")) throw Errors.InvalidColorError(color); var patch = new MemberPatch { Color = Partial.Present(color.ToLowerInvariant()) }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply(embed: new EmbedBuilder() .Title($"{Emojis.Success} Member color changed.") @@ -284,7 +282,7 @@ public class MemberEdit ctx.CheckOwnMember(target); var patch = new MemberPatch { Birthday = Partial.Null() }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Member birthdate cleared."); } @@ -318,7 +316,7 @@ public class MemberEdit if (birthday == null) throw Errors.BirthdayParseError(birthdayStr); var patch = new MemberPatch { Birthday = Partial.Present(birthday) }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Member birthdate changed."); } @@ -330,7 +328,7 @@ public class MemberEdit MemberGuildSettings memberGuildConfig = null; if (ctx.Guild != null) - memberGuildConfig = await _repo.GetMemberGuild(ctx.Guild.Id, target.Id); + memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id); var eb = new EmbedBuilder() .Title("Member names") @@ -370,7 +368,7 @@ public class MemberEdit var successStr = text; if (ctx.Guild != null) { - var memberGuildConfig = await _repo.GetMemberGuild(ctx.Guild.Id, target.Id); + var memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id); if (memberGuildConfig.DisplayName != null) successStr += $" However, this member has a server name set in this server ({ctx.Guild.Name}), and will be proxied using that name, \"{memberGuildConfig.DisplayName}\", here."; @@ -412,7 +410,7 @@ public class MemberEdit if (await ctx.MatchClear("this member's display name")) { var patch = new MemberPatch { DisplayName = Partial.Null() }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await PrintSuccess( $"{Emojis.Success} Member display name cleared. This member will now be proxied using their member name \"{target.Name}\"."); @@ -425,7 +423,7 @@ public class MemberEdit var newDisplayName = ctx.RemainderOrNull(false).NormalizeLineEndSpacing(); var patch = new MemberPatch { DisplayName = Partial.Present(newDisplayName) }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await PrintSuccess( $"{Emojis.Success} Member display name changed. This member will now be proxied using the name \"{newDisplayName}\"."); @@ -442,7 +440,7 @@ public class MemberEdit $" To set one, type `pk;member {target.Reference()} servername `."; // No perms check, display name isn't covered by member privacy - var memberGuildConfig = await _repo.GetMemberGuild(ctx.Guild.Id, target.Id); + var memberGuildConfig = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id); if (ctx.MatchRaw()) { @@ -467,7 +465,7 @@ public class MemberEdit if (await ctx.MatchClear("this member's server name")) { - await _repo.UpdateMemberGuild(target.Id, ctx.Guild.Id, new MemberGuildPatch { DisplayName = null }); + await ctx.Repository.UpdateMemberGuild(target.Id, ctx.Guild.Id, new MemberGuildPatch { DisplayName = null }); if (target.DisplayName != null) await ctx.Reply( @@ -480,7 +478,7 @@ public class MemberEdit { var newServerName = ctx.RemainderOrNull(false).NormalizeLineEndSpacing(); - await _repo.UpdateMemberGuild(target.Id, ctx.Guild.Id, + await ctx.Repository.UpdateMemberGuild(target.Id, ctx.Guild.Id, new MemberGuildPatch { DisplayName = newServerName }); await ctx.Reply( @@ -519,7 +517,7 @@ public class MemberEdit ; var patch = new MemberPatch { KeepProxy = Partial.Present(newValue) }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); if (newValue) await ctx.Reply( @@ -548,7 +546,7 @@ public class MemberEdit var newValue = ctx.MatchToggle(); var patch = new MemberPatch { AllowAutoproxy = Partial.Present(newValue) }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); if (newValue) await ctx.Reply($"{Emojis.Success} Latch / front autoproxy have been **enabled** for this member."); @@ -583,11 +581,11 @@ public class MemberEdit // Get guild settings (mostly for warnings and such) MemberGuildSettings guildSettings = null; if (ctx.Guild != null) - guildSettings = await _repo.GetMemberGuild(ctx.Guild.Id, target.Id); + guildSettings = await ctx.Repository.GetMemberGuild(ctx.Guild.Id, target.Id); async Task SetAll(PrivacyLevel level) { - await _repo.UpdateMember(target.Id, new MemberPatch().WithAllPrivacy(level)); + await ctx.Repository.UpdateMember(target.Id, new MemberPatch().WithAllPrivacy(level)); if (level == PrivacyLevel.Private) await ctx.Reply( @@ -599,7 +597,7 @@ public class MemberEdit async Task SetLevel(MemberPrivacySubject subject, PrivacyLevel level) { - await _repo.UpdateMember(target.Id, new MemberPatch().WithPrivacy(subject, level)); + await ctx.Repository.UpdateMember(target.Id, new MemberPatch().WithPrivacy(subject, level)); var subjectName = subject switch { @@ -677,7 +675,7 @@ public class MemberEdit $"{Emojis.Warn} Are you sure you want to delete \"{target.NameFor(ctx)}\"? If so, reply to this message with the member's ID (`{target.Hid}`). __***This cannot be undone!***__"); if (!await ctx.ConfirmWithReply(target.Hid)) throw Errors.MemberDeleteCancelled; - await _repo.DeleteMember(target.Id); + await ctx.Repository.DeleteMember(target.Id); await ctx.Reply($"{Emojis.Success} Member deleted."); } diff --git a/PluralKit.Bot/Commands/MemberProxy.cs b/PluralKit.Bot/Commands/MemberProxy.cs index 1ed5c58b..1e1edb9e 100644 --- a/PluralKit.Bot/Commands/MemberProxy.cs +++ b/PluralKit.Bot/Commands/MemberProxy.cs @@ -6,15 +6,6 @@ namespace PluralKit.Bot; public class MemberProxy { - private readonly IDatabase _db; - private readonly ModelRepository _repo; - - public MemberProxy(IDatabase db, ModelRepository repo) - { - _db = db; - _repo = repo; - } - public async Task Proxy(Context ctx, PKMember target) { ctx.CheckSystem().CheckOwnMember(target); @@ -32,7 +23,7 @@ public class MemberProxy async Task WarnOnConflict(ProxyTag newTag) { var query = "select * from (select *, (unnest(proxy_tags)).prefix as prefix, (unnest(proxy_tags)).suffix as suffix from members where system = @System) as _ where prefix is not distinct from @Prefix and suffix is not distinct from @Suffix and id != @Existing"; - var conflicts = (await _db.Execute(conn => conn.QueryAsync(query, + var conflicts = (await ctx.Database.Execute(conn => conn.QueryAsync(query, new { newTag.Prefix, newTag.Suffix, Existing = target.Id, system = target.System }))).ToList(); if (conflicts.Count <= 0) return true; @@ -54,7 +45,7 @@ public class MemberProxy } var patch = new MemberPatch { ProxyTags = Partial.Present(new ProxyTag[0]) }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Proxy tags cleared."); } @@ -86,7 +77,7 @@ public class MemberProxy var newTags = target.ProxyTags.ToList(); newTags.Add(tagToAdd); var patch = new MemberPatch { ProxyTags = Partial.Present(newTags.ToArray()) }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Added proxy tags {tagToAdd.ProxyString.AsCode()}."); } @@ -104,7 +95,7 @@ public class MemberProxy var newTags = target.ProxyTags.ToList(); newTags.Remove(tagToRemove); var patch = new MemberPatch { ProxyTags = Partial.Present(newTags.ToArray()) }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Removed proxy tags {tagToRemove.ProxyString.AsCode()}."); } @@ -128,7 +119,7 @@ public class MemberProxy var newTags = new[] { requestedTag }; var patch = new MemberPatch { ProxyTags = Partial.Present(newTags) }; - await _repo.UpdateMember(target.Id, patch); + await ctx.Repository.UpdateMember(target.Id, patch); await ctx.Reply($"{Emojis.Success} Member proxy tags set to {requestedTag.ProxyString.AsCode()}."); } diff --git a/PluralKit.Bot/Commands/Message.cs b/PluralKit.Bot/Commands/Message.cs index 8b91b3f9..f809b487 100644 --- a/PluralKit.Bot/Commands/Message.cs +++ b/PluralKit.Bot/Commands/Message.cs @@ -23,19 +23,15 @@ public class ProxiedMessage private readonly IDiscordCache _cache; private readonly IClock _clock; - private readonly IDatabase _db; private readonly EmbedService _embeds; private readonly LogChannelService _logChannel; - private readonly ModelRepository _repo; private readonly DiscordApiClient _rest; private readonly WebhookExecutorService _webhookExecutor; - public ProxiedMessage(IDatabase db, ModelRepository repo, EmbedService embeds, IClock clock, + public ProxiedMessage(EmbedService embeds, IClock clock, DiscordApiClient rest, WebhookExecutorService webhookExecutor, LogChannelService logChannel, IDiscordCache cache) { - _db = db; - _repo = repo; _embeds = embeds; _clock = clock; _rest = rest; @@ -85,13 +81,14 @@ public class ProxiedMessage private async Task GetMessageToEdit(Context ctx) { - await using var conn = await _db.Obtain(); + // todo: is it correct to get a connection here? + await using var conn = await ctx.Database.Obtain(); FullMessage? msg = null; var (referencedMessage, _) = ctx.MatchMessage(false); if (referencedMessage != null) { - msg = await _repo.GetMessage(conn, referencedMessage.Value); + msg = await ctx.Repository.GetMessage(conn, referencedMessage.Value); if (msg == null) throw new PKError("This is not a message proxied by PluralKit."); } @@ -105,7 +102,7 @@ public class ProxiedMessage if (recent == null) throw new PKSyntaxError("Could not find a recent message to edit."); - msg = await _repo.GetMessage(conn, recent.Mid); + msg = await ctx.Repository.GetMessage(conn, recent.Mid); if (msg == null) throw new PKSyntaxError("Could not find a recent message to edit."); } @@ -130,7 +127,7 @@ public class ProxiedMessage private async Task FindRecentMessage(Context ctx) { - var lastMessage = await _repo.GetLastMessage(ctx.Guild.Id, ctx.Channel.Id, ctx.Author.Id); + var lastMessage = await ctx.Repository.GetLastMessage(ctx.Guild.Id, ctx.Channel.Id, ctx.Author.Id); if (lastMessage == null) return null; @@ -153,7 +150,7 @@ public class ProxiedMessage var isDelete = ctx.Match("delete") || ctx.MatchFlag("delete"); - var message = await _db.Execute(c => _repo.GetMessage(c, messageId.Value)); + var message = await ctx.Database.Execute(c => ctx.Repository.GetMessage(c, messageId.Value)); if (message == null) { if (isDelete) @@ -245,7 +242,7 @@ public class ProxiedMessage private async Task DeleteCommandMessage(Context ctx, ulong messageId) { - var message = await _repo.GetCommandMessage(messageId); + var message = await ctx.Repository.GetCommandMessage(messageId); if (message == null) throw Errors.MessageNotFound(messageId); diff --git a/PluralKit.Bot/Commands/Random.cs b/PluralKit.Bot/Commands/Random.cs index ab26602f..b7ea811d 100644 --- a/PluralKit.Bot/Commands/Random.cs +++ b/PluralKit.Bot/Commands/Random.cs @@ -4,17 +4,13 @@ namespace PluralKit.Bot; public class Random { - private readonly IDatabase _db; private readonly EmbedService _embeds; - private readonly ModelRepository _repo; private readonly global::System.Random randGen = new(); - public Random(EmbedService embeds, IDatabase db, ModelRepository repo) + public Random(EmbedService embeds) { _embeds = embeds; - _db = db; - _repo = repo; } // todo: get postgresql to return one random member/group instead of querying all members/groups @@ -23,7 +19,7 @@ public class Random { ctx.CheckSystem(); - var members = await _repo.GetSystemMembers(ctx.System.Id).ToListAsync(); + var members = await ctx.Repository.GetSystemMembers(ctx.System.Id).ToListAsync(); if (!ctx.MatchFlag("all", "a")) members = members.Where(m => m.MemberVisibility == PrivacyLevel.Public).ToList(); @@ -41,7 +37,7 @@ public class Random { ctx.CheckSystem(); - var groups = await _repo.GetSystemGroups(ctx.System.Id).ToListAsync(); + var groups = await ctx.Repository.GetSystemGroups(ctx.System.Id).ToListAsync(); if (!ctx.MatchFlag("all", "a")) groups = groups.Where(g => g.Visibility == PrivacyLevel.Public).ToList(); @@ -60,8 +56,7 @@ public class Random var opts = ctx.ParseListOptions(ctx.DirectLookupContextFor(group.System)); opts.GroupFilter = group.Id; - await using var conn = await _db.Obtain(); - var members = await conn.QueryMemberList(ctx.System.Id, opts.ToQueryOptions()); + var members = await ctx.Database.Execute(conn => conn.QueryMemberList(ctx.System.Id, opts.ToQueryOptions())); if (members == null || !members.Any()) throw new PKError( diff --git a/PluralKit.Bot/Commands/ServerConfig.cs b/PluralKit.Bot/Commands/ServerConfig.cs index 0e4f3cac..5cf8bb46 100644 --- a/PluralKit.Bot/Commands/ServerConfig.cs +++ b/PluralKit.Bot/Commands/ServerConfig.cs @@ -12,24 +12,20 @@ namespace PluralKit.Bot; public class ServerConfig { private readonly IDiscordCache _cache; - private readonly LoggerCleanService _cleanService; - private readonly ModelRepository _repo; - public ServerConfig(LoggerCleanService cleanService, ModelRepository repo, IDiscordCache cache) + public ServerConfig(IDiscordCache cache) { - _cleanService = cleanService; - _repo = repo; _cache = cache; } public async Task SetLogChannel(Context ctx) { await ctx.CheckGuildContext().CheckAuthorPermission(PermissionSet.ManageGuild, "Manage Server"); - var settings = await _repo.GetGuild(ctx.Guild.Id); + var settings = await ctx.Repository.GetGuild(ctx.Guild.Id); if (await ctx.MatchClear("the server log channel")) { - await _repo.UpdateGuild(ctx.Guild.Id, new GuildPatch { LogChannel = null }); + await ctx.Repository.UpdateGuild(ctx.Guild.Id, new GuildPatch { LogChannel = null }); await ctx.Reply($"{Emojis.Success} Proxy logging channel cleared."); return; } @@ -59,7 +55,7 @@ public class ServerConfig if (!perms.HasFlag(PermissionSet.EmbedLinks)) throw new PKError("PluralKit is missing **Embed Links** permissions in the new log channel."); - await _repo.UpdateGuild(ctx.Guild.Id, new GuildPatch { LogChannel = channel.Id }); + await ctx.Repository.UpdateGuild(ctx.Guild.Id, new GuildPatch { LogChannel = channel.Id }); await ctx.Reply($"{Emojis.Success} Proxy logging channel set to <#{channel.Id}>."); } @@ -82,7 +78,7 @@ public class ServerConfig } ulong? logChannel = null; - var config = await _repo.GetGuild(ctx.Guild.Id); + var config = await ctx.Repository.GetGuild(ctx.Guild.Id); logChannel = config.LogChannel; var blacklist = config.LogBlacklist.ToHashSet(); @@ -91,7 +87,7 @@ public class ServerConfig else blacklist.UnionWith(affectedChannels.Select(c => c.Id)); - await _repo.UpdateGuild(ctx.Guild.Id, new GuildPatch { LogBlacklist = blacklist.ToArray() }); + await ctx.Repository.UpdateGuild(ctx.Guild.Id, new GuildPatch { LogBlacklist = blacklist.ToArray() }); await ctx.Reply( $"{Emojis.Success} Message logging for the given channels {(enable ? "enabled" : "disabled")}." + @@ -104,7 +100,7 @@ public class ServerConfig { await ctx.CheckGuildContext().CheckAuthorPermission(PermissionSet.ManageGuild, "Manage Server"); - var blacklist = await _repo.GetGuild(ctx.Guild.Id); + var blacklist = await ctx.Repository.GetGuild(ctx.Guild.Id); // Resolve all channels from the cache and order by position var channels = (await Task.WhenAll(blacklist.Blacklist @@ -168,7 +164,7 @@ public class ServerConfig affectedChannels.Add(channel); } - var guild = await _repo.GetGuild(ctx.Guild.Id); + var guild = await ctx.Repository.GetGuild(ctx.Guild.Id); var blacklist = guild.Blacklist.ToHashSet(); if (shouldAdd) @@ -176,7 +172,7 @@ public class ServerConfig else blacklist.ExceptWith(affectedChannels.Select(c => c.Id)); - await _repo.UpdateGuild(ctx.Guild.Id, new GuildPatch { Blacklist = blacklist.ToArray() }); + await ctx.Repository.UpdateGuild(ctx.Guild.Id, new GuildPatch { Blacklist = blacklist.ToArray() }); await ctx.Reply( $"{Emojis.Success} Channels {(shouldAdd ? "added to" : "removed from")} the proxy blacklist."); @@ -186,9 +182,9 @@ public class ServerConfig { await ctx.CheckGuildContext().CheckAuthorPermission(PermissionSet.ManageGuild, "Manage Server"); - var botList = string.Join(", ", _cleanService.Bots.Select(b => b.Name).OrderBy(x => x.ToLowerInvariant())); + var botList = string.Join(", ", LoggerCleanService.Bots.Select(b => b.Name).OrderBy(x => x.ToLowerInvariant())); - var guild = await _repo.GetGuild(ctx.Guild.Id); + var guild = await ctx.Repository.GetGuild(ctx.Guild.Id); bool newValue; if (ctx.Match("enable", "on", "yes")) @@ -205,7 +201,7 @@ public class ServerConfig .Title("Log cleanup settings") .Field(new Embed.Field("Supported bots", botList)); - var guildCfg = await _repo.GetGuild(ctx.Guild.Id); + var guildCfg = await ctx.Repository.GetGuild(ctx.Guild.Id); if (guildCfg.LogCleanupEnabled) eb.Description( "Log cleanup is currently **on** for this server. To disable it, type `pk;logclean off`."); @@ -216,7 +212,7 @@ public class ServerConfig return; } - await _repo.UpdateGuild(ctx.Guild.Id, new GuildPatch { LogCleanupEnabled = newValue }); + await ctx.Repository.UpdateGuild(ctx.Guild.Id, new GuildPatch { LogCleanupEnabled = newValue }); if (newValue) await ctx.Reply( diff --git a/PluralKit.Bot/Commands/Switch.cs b/PluralKit.Bot/Commands/Switch.cs index 3c341466..751cf0a2 100644 --- a/PluralKit.Bot/Commands/Switch.cs +++ b/PluralKit.Bot/Commands/Switch.cs @@ -7,15 +7,6 @@ namespace PluralKit.Bot; public class Switch { - private readonly IDatabase _db; - private readonly ModelRepository _repo; - - public Switch(IDatabase db, ModelRepository repo) - { - _db = db; - _repo = repo; - } - public async Task SwitchDo(Context ctx) { ctx.CheckSystem(); @@ -42,18 +33,18 @@ public class Switch $"Switch contains too many members ({members.Count} > {Limits.MaxSwitchMemberCount} members)."); // Find the last switch and its members if applicable - await using var conn = await _db.Obtain(); - var lastSwitch = await _repo.GetLatestSwitch(ctx.System.Id); + await using var conn = await ctx.Database.Obtain(); + var lastSwitch = await ctx.Repository.GetLatestSwitch(ctx.System.Id); if (lastSwitch != null) { - var lastSwitchMembers = _repo.GetSwitchMembers(conn, lastSwitch.Id); + var lastSwitchMembers = ctx.Repository.GetSwitchMembers(conn, lastSwitch.Id); // Make sure the requested switch isn't identical to the last one if (await lastSwitchMembers.Select(m => m.Id) .SequenceEqualAsync(members.Select(m => m.Id).ToAsyncEnumerable())) throw Errors.SameSwitch(members, ctx.LookupContextFor(ctx.System.Id)); } - await _repo.AddSwitch(conn, ctx.System.Id, members.Select(m => m.Id).ToList()); + await ctx.Repository.AddSwitch(conn, ctx.System.Id, members.Select(m => m.Id).ToList()); if (members.Count == 0) await ctx.Reply($"{Emojis.Success} Switch-out registered."); @@ -78,7 +69,7 @@ public class Switch if (time.ToInstant() > SystemClock.Instance.GetCurrentInstant()) throw Errors.SwitchTimeInFuture; // Fetch the last two switches for the system to do bounds checking on - var lastTwoSwitches = await _repo.GetSwitches(ctx.System.Id).Take(2).ToListAsync(); + var lastTwoSwitches = await ctx.Repository.GetSwitches(ctx.System.Id).Take(2).ToListAsync(); // If we don't have a switch to move, don't bother if (lastTwoSwitches.Count == 0) throw Errors.NoRegisteredSwitches; @@ -90,7 +81,7 @@ public class Switch // Now we can actually do the move, yay! // But, we do a prompt to confirm. - var lastSwitchMembers = _db.Execute(conn => _repo.GetSwitchMembers(conn, lastTwoSwitches[0].Id)); + var lastSwitchMembers = ctx.Database.Execute(conn => ctx.Repository.GetSwitchMembers(conn, lastTwoSwitches[0].Id)); var lastSwitchMemberStr = string.Join(", ", await lastSwitchMembers.Select(m => m.NameFor(ctx)).ToListAsync()); var lastSwitchTime = lastTwoSwitches[0].Timestamp.ToUnixTimeSeconds(); // .FormatZoned(ctx.System) @@ -105,7 +96,7 @@ public class Switch if (!await ctx.PromptYesNo(msg, "Move Switch")) throw Errors.SwitchMoveCancelled; // aaaand *now* we do the move - await _repo.MoveSwitch(lastTwoSwitches[0].Id, time.ToInstant()); + await ctx.Repository.MoveSwitch(lastTwoSwitches[0].Id, time.ToInstant()); await ctx.Reply($"{Emojis.Success} Switch moved to ({newSwitchDeltaStr} ago)."); } @@ -130,11 +121,11 @@ public class Switch if (members.Select(m => m.Id).Distinct().Count() != members.Count) throw Errors.DuplicateSwitchMembers; // Find the switch to edit - await using var conn = await _db.Obtain(); - var lastSwitch = await _repo.GetLatestSwitch(ctx.System.Id); + await using var conn = await ctx.Database.Obtain(); + var lastSwitch = await ctx.Repository.GetLatestSwitch(ctx.System.Id); // Make sure there's at least one switch if (lastSwitch == null) throw Errors.NoRegisteredSwitches; - var lastSwitchMembers = _repo.GetSwitchMembers(conn, lastSwitch.Id); + var lastSwitchMembers = ctx.Repository.GetSwitchMembers(conn, lastSwitch.Id); // Make sure switch isn't being edited to have the members it already does if (await lastSwitchMembers.Select(m => m.Id) .SequenceEqualAsync(members.Select(m => m.Id).ToAsyncEnumerable())) @@ -154,7 +145,7 @@ public class Switch if (!await ctx.PromptYesNo(msg, "Edit")) throw Errors.SwitchEditCancelled; // Actually edit the switch - await _repo.EditSwitch(conn, lastSwitch.Id, members.Select(m => m.Id).ToList()); + await ctx.Repository.EditSwitch(conn, lastSwitch.Id, members.Select(m => m.Id).ToList()); // Tell the user the edit suceeded if (members.Count == 0) @@ -174,16 +165,16 @@ public class Switch $"{Emojis.Warn} This will delete *all registered switches* in your system. Are you sure you want to proceed?"; if (!await ctx.PromptYesNo(purgeMsg, "Clear Switches")) throw Errors.GenericCancelled(); - await _repo.DeleteAllSwitches(ctx.System.Id); + await ctx.Repository.DeleteAllSwitches(ctx.System.Id); await ctx.Reply($"{Emojis.Success} Cleared system switches!"); return; } // Fetch the last two switches for the system to do bounds checking on - var lastTwoSwitches = await _repo.GetSwitches(ctx.System.Id).Take(2).ToListAsync(); + var lastTwoSwitches = await ctx.Repository.GetSwitches(ctx.System.Id).Take(2).ToListAsync(); if (lastTwoSwitches.Count == 0) throw Errors.NoRegisteredSwitches; - var lastSwitchMembers = _db.Execute(conn => _repo.GetSwitchMembers(conn, lastTwoSwitches[0].Id)); + var lastSwitchMembers = ctx.Database.Execute(conn => ctx.Repository.GetSwitchMembers(conn, lastTwoSwitches[0].Id)); var lastSwitchMemberStr = string.Join(", ", await lastSwitchMembers.Select(m => m.NameFor(ctx)).ToListAsync()); var lastSwitchDeltaStr = @@ -196,7 +187,7 @@ public class Switch } else { - var secondSwitchMembers = _db.Execute(conn => _repo.GetSwitchMembers(conn, lastTwoSwitches[1].Id)); + var secondSwitchMembers = ctx.Database.Execute(conn => ctx.Repository.GetSwitchMembers(conn, lastTwoSwitches[1].Id)); var secondSwitchMemberStr = string.Join(", ", await secondSwitchMembers.Select(m => m.NameFor(ctx)).ToListAsync()); var secondSwitchDeltaStr = (SystemClock.Instance.GetCurrentInstant() - lastTwoSwitches[1].Timestamp) @@ -205,7 +196,7 @@ public class Switch } if (!await ctx.PromptYesNo(msg, "Delete Switch")) throw Errors.SwitchDeleteCancelled; - await _repo.DeleteSwitch(lastTwoSwitches[0].Id); + await ctx.Repository.DeleteSwitch(lastTwoSwitches[0].Id); await ctx.Reply($"{Emojis.Success} Switch deleted."); } diff --git a/PluralKit.Bot/Commands/System.cs b/PluralKit.Bot/Commands/System.cs index 703c1654..4046220d 100644 --- a/PluralKit.Bot/Commands/System.cs +++ b/PluralKit.Bot/Commands/System.cs @@ -5,12 +5,10 @@ namespace PluralKit.Bot; public class System { private readonly EmbedService _embeds; - private readonly ModelRepository _repo; public System(EmbedService embeds, ModelRepository repo) { _embeds = embeds; - _repo = repo; } public async Task Query(Context ctx, PKSystem system) @@ -28,8 +26,8 @@ public class System if (systemName != null && systemName.Length > Limits.MaxSystemNameLength) throw Errors.StringTooLongError("System name", systemName.Length, Limits.MaxSystemNameLength); - var system = await _repo.CreateSystem(systemName); - await _repo.AddAccount(system.Id, ctx.Author.Id); + var system = await ctx.Repository.CreateSystem(systemName); + await ctx.Repository.AddAccount(system.Id, ctx.Author.Id); // TODO: better message, perhaps embed like in groups? await ctx.Reply( diff --git a/PluralKit.Bot/Commands/SystemEdit.cs b/PluralKit.Bot/Commands/SystemEdit.cs index b5f1b675..85a848d8 100644 --- a/PluralKit.Bot/Commands/SystemEdit.cs +++ b/PluralKit.Bot/Commands/SystemEdit.cs @@ -14,11 +14,9 @@ namespace PluralKit.Bot; public class SystemEdit { private readonly HttpClient _client; - private readonly ModelRepository _repo; - public SystemEdit(ModelRepository repo, HttpClient client) + public SystemEdit(HttpClient client) { - _repo = repo; _client = client; } @@ -54,7 +52,7 @@ public class SystemEdit if (await ctx.MatchClear("your system's name")) { - await _repo.UpdateSystem(target.Id, new SystemPatch { Name = null }); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Name = null }); await ctx.Reply($"{Emojis.Success} System name cleared."); } @@ -65,7 +63,7 @@ public class SystemEdit if (newSystemName.Length > Limits.MaxSystemNameLength) throw Errors.StringTooLongError("System name", newSystemName.Length, Limits.MaxSystemNameLength); - await _repo.UpdateSystem(target.Id, new SystemPatch { Name = newSystemName }); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Name = newSystemName }); await ctx.Reply($"{Emojis.Success} System name changed."); } @@ -109,7 +107,7 @@ public class SystemEdit if (await ctx.MatchClear("your system's description")) { - await _repo.UpdateSystem(target.Id, new SystemPatch { Description = null }); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Description = null }); await ctx.Reply($"{Emojis.Success} System description cleared."); } @@ -119,7 +117,7 @@ public class SystemEdit if (newDescription.Length > Limits.MaxDescriptionLength) throw Errors.StringTooLongError("Description", newDescription.Length, Limits.MaxDescriptionLength); - await _repo.UpdateSystem(target.Id, new SystemPatch { Description = newDescription }); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Description = newDescription }); await ctx.Reply($"{Emojis.Success} System description changed."); } @@ -149,7 +147,7 @@ public class SystemEdit if (await ctx.MatchClear()) { - await _repo.UpdateSystem(target.Id, new SystemPatch { Color = Partial.Null() }); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Color = Partial.Null() }); await ctx.Reply($"{Emojis.Success} System color cleared."); } @@ -160,7 +158,7 @@ public class SystemEdit if (color.StartsWith("#")) color = color.Substring(1); if (!Regex.IsMatch(color, "^[0-9a-fA-F]{6}$")) throw Errors.InvalidColorError(color); - await _repo.UpdateSystem(target.Id, + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Color = Partial.Present(color.ToLowerInvariant()) }); await ctx.Reply(embed: new EmbedBuilder() @@ -202,7 +200,7 @@ public class SystemEdit if (await ctx.MatchClear("your system's tag")) { - await _repo.UpdateSystem(target.Id, new SystemPatch { Tag = null }); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Tag = null }); await ctx.Reply($"{Emojis.Success} System tag cleared."); } @@ -213,7 +211,7 @@ public class SystemEdit if (newTag.Length > Limits.MaxSystemTagLength) throw Errors.StringTooLongError("System tag", newTag.Length, Limits.MaxSystemTagLength); - await _repo.UpdateSystem(target.Id, new SystemPatch { Tag = newTag }); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { Tag = newTag }); await ctx.Reply( $"{Emojis.Success} System tag changed. Member names will now end with {newTag.AsCode()} when proxied."); @@ -227,7 +225,7 @@ public class SystemEdit var setDisabledWarning = $"{Emojis.Warn} Your system tag is currently **disabled** in this server. No tag will be applied when proxying.\nTo re-enable the system tag in the current server, type `pk;s servertag -enable`."; - var settings = await _repo.GetSystemGuild(ctx.Guild.Id, target.Id); + var settings = await ctx.Repository.GetSystemGuild(ctx.Guild.Id, target.Id); async Task Show(bool raw = false) { @@ -264,7 +262,7 @@ public class SystemEdit if (newTag != null && newTag.Length > Limits.MaxSystemTagLength) throw Errors.StringTooLongError("System server tag", newTag.Length, Limits.MaxSystemTagLength); - await _repo.UpdateSystemGuild(target.Id, ctx.Guild.Id, new SystemGuildPatch { Tag = newTag }); + await ctx.Repository.UpdateSystemGuild(target.Id, ctx.Guild.Id, new SystemGuildPatch { Tag = newTag }); await ctx.Reply( $"{Emojis.Success} System server tag changed. Member names will now end with {newTag.AsCode()} when proxied in the current server '{ctx.Guild.Name}'."); @@ -275,7 +273,7 @@ public class SystemEdit async Task Clear() { - await _repo.UpdateSystemGuild(target.Id, ctx.Guild.Id, new SystemGuildPatch { Tag = null }); + await ctx.Repository.UpdateSystemGuild(target.Id, ctx.Guild.Id, new SystemGuildPatch { Tag = null }); await ctx.Reply( $"{Emojis.Success} System server tag cleared. Member names will now end with the global system tag, if there is one set."); @@ -286,7 +284,7 @@ public class SystemEdit async Task EnableDisable(bool newValue) { - await _repo.UpdateSystemGuild(target.Id, ctx.Guild.Id, + await ctx.Repository.UpdateSystemGuild(target.Id, ctx.Guild.Id, new SystemGuildPatch { TagEnabled = newValue }); await ctx.Reply(PrintEnableDisableResult(newValue, newValue != ctx.MessageContext.TagEnabled)); @@ -347,7 +345,7 @@ public class SystemEdit { ctx.CheckOwnSystem(target); - await _repo.UpdateSystem(target.Id, new SystemPatch { AvatarUrl = null }); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { AvatarUrl = null }); await ctx.Reply($"{Emojis.Success} System icon cleared."); } @@ -357,7 +355,7 @@ public class SystemEdit await AvatarUtils.VerifyAvatarOrThrow(_client, img.Url); - await _repo.UpdateSystem(target.Id, new SystemPatch { AvatarUrl = img.Url }); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { AvatarUrl = img.Url }); var msg = img.Source switch { @@ -439,7 +437,7 @@ public class SystemEdit if (await ctx.MatchClear("your system's banner image")) { - await _repo.UpdateSystem(target.Id, new SystemPatch { BannerImage = null }); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { BannerImage = null }); await ctx.Reply($"{Emojis.Success} System banner image cleared."); } @@ -447,7 +445,7 @@ public class SystemEdit { await AvatarUtils.VerifyAvatarOrThrow(_client, img.Url, true); - await _repo.UpdateSystem(target.Id, new SystemPatch { BannerImage = img.Url }); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch { BannerImage = img.Url }); var msg = img.Source switch { @@ -477,7 +475,7 @@ public class SystemEdit throw new PKError( $"System deletion cancelled. Note that you must reply with your system ID (`{target.Hid}`) *verbatim*."); - await _repo.DeleteSystem(target.Id); + await ctx.Repository.DeleteSystem(target.Id); await ctx.Reply($"{Emojis.Success} System deleted."); } @@ -489,7 +487,7 @@ public class SystemEdit var guild = await ctx.MatchGuild() ?? ctx.Guild ?? throw new PKError("You must run this command in a server or pass a server ID."); - var gs = await _repo.GetSystemGuild(guild.Id, ctx.System.Id); + var gs = await ctx.Repository.GetSystemGuild(guild.Id, ctx.System.Id); string serverText; if (guild.Id == ctx.Guild?.Id) @@ -510,7 +508,7 @@ public class SystemEdit var newValue = ctx.MatchToggle(); - await _repo.UpdateSystemGuild(ctx.System.Id, guild.Id, new SystemGuildPatch { ProxyEnabled = newValue }); + await ctx.Repository.UpdateSystemGuild(ctx.System.Id, guild.Id, new SystemGuildPatch { ProxyEnabled = newValue }); if (newValue) await ctx.Reply($"Message proxying in {serverText} is now **enabled** for your system."); @@ -538,7 +536,7 @@ public class SystemEdit async Task SetLevel(SystemPrivacySubject subject, PrivacyLevel level) { - await _repo.UpdateSystem(target.Id, new SystemPatch().WithPrivacy(subject, level)); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch().WithPrivacy(subject, level)); var levelExplanation = level switch { @@ -564,7 +562,7 @@ public class SystemEdit async Task SetAll(PrivacyLevel level) { - await _repo.UpdateSystem(target.Id, new SystemPatch().WithAllPrivacy(level)); + await ctx.Repository.UpdateSystem(target.Id, new SystemPatch().WithAllPrivacy(level)); var msg = level switch { diff --git a/PluralKit.Bot/Commands/SystemFront.cs b/PluralKit.Bot/Commands/SystemFront.cs index a599172a..2ed9a841 100644 --- a/PluralKit.Bot/Commands/SystemFront.cs +++ b/PluralKit.Bot/Commands/SystemFront.cs @@ -8,15 +8,11 @@ namespace PluralKit.Bot; public class SystemFront { - private readonly IDatabase _db; private readonly EmbedService _embeds; - private readonly ModelRepository _repo; - public SystemFront(EmbedService embeds, IDatabase db, ModelRepository repo) + public SystemFront(EmbedService embeds) { _embeds = embeds; - _db = db; - _repo = repo; } public async Task SystemFronter(Context ctx, PKSystem system) @@ -24,7 +20,7 @@ public class SystemFront if (system == null) throw Errors.NoSystemError; ctx.CheckSystemPrivacy(system.Id, system.FrontPrivacy); - var sw = await _repo.GetLatestSwitch(system.Id); + var sw = await ctx.Repository.GetLatestSwitch(system.Id); if (sw == null) throw Errors.NoRegisteredSwitches; await ctx.Reply(embed: await _embeds.CreateFronterEmbed(sw, ctx.Zone, ctx.LookupContextFor(system.Id))); @@ -35,10 +31,10 @@ public class SystemFront if (system == null) throw Errors.NoSystemError; ctx.CheckSystemPrivacy(system.Id, system.FrontHistoryPrivacy); - var totalSwitches = await _repo.GetSwitchCount(system.Id); + var totalSwitches = await ctx.Repository.GetSwitchCount(system.Id); if (totalSwitches == 0) throw Errors.NoRegisteredSwitches; - var sws = _repo.GetSwitches(system.Id) + var sws = ctx.Repository.GetSwitches(system.Id) .Scan(new FrontHistoryEntry(null, null), (lastEntry, newSwitch) => new FrontHistoryEntry(lastEntry.ThisSwitch?.Timestamp, newSwitch)); @@ -63,7 +59,7 @@ public class SystemFront // Fetch member list and format - var members = await _db.Execute(c => _repo.GetSwitchMembers(c, sw.Id)).ToListAsync(); + var members = await ctx.Database.Execute(c => ctx.Repository.GetSwitchMembers(c, sw.Id)).ToListAsync(); var membersStr = members.Any() ? string.Join(", ", members.Select(m => m.NameFor(ctx))) : "no fronter"; @@ -102,7 +98,7 @@ public class SystemFront ctx.CheckSystemPrivacy(system.Id, system.FrontHistoryPrivacy); - var totalSwitches = await _repo.GetSwitchCount(system.Id); + var totalSwitches = await ctx.Repository.GetSwitchCount(system.Id); if (totalSwitches == 0) throw Errors.NoRegisteredSwitches; var ignoreNoFronters = ctx.MatchFlag("fo", "fronters-only"); @@ -130,7 +126,7 @@ public class SystemFront else title.Append($"`{system.Hid}`"); - var frontpercent = await _db.Execute(c => _repo.GetFrontBreakdown(c, system.Id, group?.Id, rangeStart.Value.ToInstant(), now)); + var frontpercent = await ctx.Database.Execute(c => ctx.Repository.GetFrontBreakdown(c, system.Id, group?.Id, rangeStart.Value.ToInstant(), now)); await ctx.Reply(embed: await _embeds.CreateFrontPercentEmbed(frontpercent, system, group, ctx.Zone, ctx.LookupContextFor(system.Id), title.ToString(), ignoreNoFronters, showFlat)); } @@ -140,7 +136,7 @@ public class SystemFront var system = ctx.System; if (system?.Id == target.System) return system; - return await _repo.GetSystem(target.System)!; + return await ctx.Repository.GetSystem(target.System)!; } private struct FrontHistoryEntry diff --git a/PluralKit.Bot/Commands/SystemLink.cs b/PluralKit.Bot/Commands/SystemLink.cs index 6bcc766b..4fe256d0 100644 --- a/PluralKit.Bot/Commands/SystemLink.cs +++ b/PluralKit.Bot/Commands/SystemLink.cs @@ -6,30 +6,23 @@ namespace PluralKit.Bot; public class SystemLink { - private readonly ModelRepository _repo; - - public SystemLink(ModelRepository repo) - { - _repo = repo; - } - public async Task LinkSystem(Context ctx) { ctx.CheckSystem(); var account = await ctx.MatchUser() ?? throw new PKSyntaxError("You must pass an account to link with (either ID or @mention)."); - var accountIds = await _repo.GetSystemAccounts(ctx.System.Id); + var accountIds = await ctx.Repository.GetSystemAccounts(ctx.System.Id); if (accountIds.Contains(account.Id)) throw Errors.AccountAlreadyLinked; - var existingAccount = await _repo.GetSystemByAccount(account.Id); + var existingAccount = await ctx.Repository.GetSystemByAccount(account.Id); if (existingAccount != null) throw Errors.AccountInOtherSystem(existingAccount); var msg = $"{account.Mention()}, please confirm the link."; if (!await ctx.PromptYesNo(msg, "Confirm", account, false)) throw Errors.MemberLinkCancelled; - await _repo.AddAccount(ctx.System.Id, account.Id); + await ctx.Repository.AddAccount(ctx.System.Id, account.Id); await ctx.Reply($"{Emojis.Success} Account linked to system."); } @@ -41,14 +34,14 @@ public class SystemLink if (!ctx.MatchUserRaw(out id)) throw new PKSyntaxError("You must pass an account to link with (either ID or @mention)."); - var accountIds = (await _repo.GetSystemAccounts(ctx.System.Id)).ToList(); + var accountIds = (await ctx.Repository.GetSystemAccounts(ctx.System.Id)).ToList(); if (!accountIds.Contains(id)) throw Errors.AccountNotLinked; if (accountIds.Count == 1) throw Errors.UnlinkingLastAccount; var msg = $"Are you sure you want to unlink <@{id}> from your system?"; if (!await ctx.PromptYesNo(msg, "Unlink")) throw Errors.MemberUnlinkCancelled; - await _repo.RemoveAccount(ctx.System.Id, id); + await ctx.Repository.RemoveAccount(ctx.System.Id, id); await ctx.Reply($"{Emojis.Success} Account unlinked."); } } \ No newline at end of file diff --git a/PluralKit.Bot/Services/LoggerCleanService.cs b/PluralKit.Bot/Services/LoggerCleanService.cs index bc6caee8..cfe1a0c4 100644 --- a/PluralKit.Bot/Services/LoggerCleanService.cs +++ b/PluralKit.Bot/Services/LoggerCleanService.cs @@ -80,7 +80,7 @@ public class LoggerCleanService _logger = logger.ForContext(); } - public ICollection Bots => _bots.Values; + public static ICollection Bots => _bots.Values; public async ValueTask HandleLoggerBotCleanup(Message msg) {