From 0f4c40b3449157dace240d55c2d838f30396ddda Mon Sep 17 00:00:00 2001 From: Ske Date: Tue, 7 Jul 2020 15:28:53 +0200 Subject: [PATCH] Add group add/remove commands --- PluralKit.Bot/Commands/CommandTree.cs | 6 ++++ PluralKit.Bot/Commands/Groups.cs | 38 ++++++++++++++++++++ PluralKit.Core/Models/Patch/ModelPatchExt.cs | 20 ++++++++++- 3 files changed, 63 insertions(+), 1 deletion(-) diff --git a/PluralKit.Bot/Commands/CommandTree.cs b/PluralKit.Bot/Commands/CommandTree.cs index 7947b390..dcc5904a 100644 --- a/PluralKit.Bot/Commands/CommandTree.cs +++ b/PluralKit.Bot/Commands/CommandTree.cs @@ -50,6 +50,8 @@ namespace PluralKit.Bot public static Command GroupList = new Command("group list", "group list", "Lists all groups in this system"); public static Command GroupRename = new Command("group rename", "group name ", "Renames a group"); public static Command GroupDesc = new Command("group description", "group description [description]", "Changes a group's description"); + public static Command GroupAdd = new Command("group add", "group add [member 2] [member 3...]", "Adds one or more members to a group"); + public static Command GroupRemove = new Command("group remove", "group remove [member 2] [member 3...]", "Removes one or more members from a group"); public static Command Switch = new Command("switch", "switch [member 2] [member 3...]", "Registers a switch"); public static Command SwitchOut = new Command("switch out", "switch out", "Registers a switch with no members"); public static Command SwitchMove = new Command("switch move", "switch move ", "Moves the latest switch in time"); @@ -333,6 +335,10 @@ namespace PluralKit.Bot await ctx.Execute(GroupRename, g => g.RenameGroup(ctx, target)); else if (ctx.Match("description", "info", "bio", "text", "desc")) await ctx.Execute(GroupDesc, g => g.GroupDescription(ctx, target)); + else if (ctx.Match("add", "a")) + await ctx.Execute(GroupAdd,g => g.AddRemoveMembers(ctx, target, Groups.AddRemoveOperation.Add)); + else if (ctx.Match("remove", "rem", "r")) + await ctx.Execute(GroupRemove, g => g.AddRemoveMembers(ctx, target, Groups.AddRemoveOperation.Remove)); else if (!ctx.HasNext()) await ctx.Execute(GroupInfo, g => g.ShowGroupCard(ctx, target)); else diff --git a/PluralKit.Bot/Commands/Groups.cs b/PluralKit.Bot/Commands/Groups.cs index 14af6b6a..a0e32ded 100644 --- a/PluralKit.Bot/Commands/Groups.cs +++ b/PluralKit.Bot/Commands/Groups.cs @@ -144,6 +144,44 @@ namespace PluralKit.Bot await ctx.Reply(embed: eb.Build()); } + public async Task AddRemoveMembers(Context ctx, PKGroup target, AddRemoveOperation op) + { + ctx.CheckOwnGroup(target); + + // Parse all arguments + var members = new List(); + while (ctx.HasNext()) + { + var member = await ctx.MatchMember(); + if (member == null) + throw new PKSyntaxError(ctx.CreateMemberNotFoundError(ctx.PopArgument()));; + if (member.System != target.System) + throw new PKError($"Member **{member.Name}** (`{member.Hid}`) is not in your own system, so you can't add it to a group."); + members.Add(member); + } + + if (members.Count == 0) + throw new PKSyntaxError("You must pass one or more members."); + + await using var conn = await _db.Obtain(); + if (op == AddRemoveOperation.Add) + { + await conn.AddMembersToGroup(target.Id, members.Select(m => m.Id)); + await ctx.Reply($"{Emojis.Success} Members added to group."); + } + else if (op == AddRemoveOperation.Remove) + { + await conn.RemoveMembersFromGroup(target.Id, members.Select(m => m.Id)); + await ctx.Reply($"{Emojis.Success} Members removed from group."); + } + } + + public enum AddRemoveOperation + { + Add, + Remove + } + private static async Task GetGroupSystem(Context ctx, PKGroup target, IPKConnection conn) { var system = ctx.System; diff --git a/PluralKit.Core/Models/Patch/ModelPatchExt.cs b/PluralKit.Core/Models/Patch/ModelPatchExt.cs index f98fa94c..b7074d92 100644 --- a/PluralKit.Core/Models/Patch/ModelPatchExt.cs +++ b/PluralKit.Core/Models/Patch/ModelPatchExt.cs @@ -1,4 +1,6 @@ -using System.Threading.Tasks; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; using Dapper; @@ -73,5 +75,21 @@ namespace PluralKit.Core .Build("returning *"); return conn.QueryFirstAsync(query, pms); } + + public static async Task AddMembersToGroup(this IPKConnection conn, GroupId group, IEnumerable members) + { + await using var w = conn.BeginBinaryImport("copy group_members (group_id, member_id) from stdin (format binary)"); + foreach (var member in members) + { + await w.StartRowAsync(); + await w.WriteAsync(group.Value); + await w.WriteAsync(member.Value); + } + await w.CompleteAsync(); + } + + public static Task RemoveMembersFromGroup(this IPKConnection conn, GroupId group, IEnumerable members) => + conn.ExecuteAsync("delete from group_members where group_id = @Group and member_id = any(@Members)", + new {Group = group, Members = members.ToArray() }); } } \ No newline at end of file