Add group delete command

This commit is contained in:
Ske 2020-08-08 14:56:34 +02:00
parent f504e16543
commit cedb050b8a
3 changed files with 40 additions and 15 deletions

View File

@ -54,6 +54,7 @@ namespace PluralKit.Bot
public static Command GroupAdd = new Command("group add", "group <group> add <member> [member 2] [member 3...]", "Adds one or more members to a group"); public static Command GroupAdd = new Command("group add", "group <group> add <member> [member 2] [member 3...]", "Adds one or more members to a group");
public static Command GroupRemove = new Command("group remove", "group <group> remove <member> [member 2] [member 3...]", "Removes one or more members from a group"); public static Command GroupRemove = new Command("group remove", "group <group> remove <member> [member 2] [member 3...]", "Removes one or more members from a group");
public static Command GroupPrivacy = new Command("group privacy", "group <group> privacy <description|icon|visibility|all> <public|private>", "Changes a group's privacy settings"); public static Command GroupPrivacy = new Command("group privacy", "group <group> privacy <description|icon|visibility|all> <public|private>", "Changes a group's privacy settings");
public static Command GroupDelete = new Command("group delete", "group <group> delete", "Deletes a group");
public static Command Switch = new Command("switch", "switch <member> [member 2] [member 3...]", "Registers a switch"); public static Command Switch = new Command("switch", "switch <member> [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 SwitchOut = new Command("switch out", "switch out", "Registers a switch with no members");
public static Command SwitchMove = new Command("switch move", "switch move <date/time>", "Moves the latest switch in time"); public static Command SwitchMove = new Command("switch move", "switch move <date/time>", "Moves the latest switch in time");
@ -349,6 +350,8 @@ namespace PluralKit.Bot
await ctx.Execute<Groups>(GroupPrivacy, g => g.GroupPrivacy(ctx, target, PrivacyLevel.Public)); await ctx.Execute<Groups>(GroupPrivacy, g => g.GroupPrivacy(ctx, target, PrivacyLevel.Public));
else if (ctx.Match("private", "priv")) else if (ctx.Match("private", "priv"))
await ctx.Execute<Groups>(GroupPrivacy, g => g.GroupPrivacy(ctx, target, PrivacyLevel.Private)); await ctx.Execute<Groups>(GroupPrivacy, g => g.GroupPrivacy(ctx, target, PrivacyLevel.Private));
else if (ctx.Match("delete", "remove", "destroy", "erase", "yeet"))
await ctx.Execute<Groups>(GroupDelete, g => g.DeleteGroup(ctx, target));
else if (!ctx.HasNext()) else if (!ctx.HasNext())
await ctx.Execute<Groups>(GroupInfo, g => g.ShowGroupCard(ctx, target)); await ctx.Execute<Groups>(GroupInfo, g => g.ShowGroupCard(ctx, target));
else else

View File

@ -2,14 +2,13 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dapper; using Dapper;
using DSharpPlus.Entities; using DSharpPlus.Entities;
using NodaTime;
using PluralKit.Core; using PluralKit.Core;
namespace PluralKit.Bot namespace PluralKit.Bot
@ -29,7 +28,7 @@ namespace PluralKit.Bot
var groupName = ctx.RemainderOrNull() ?? throw new PKSyntaxError("You must pass a group name."); var groupName = ctx.RemainderOrNull() ?? throw new PKSyntaxError("You must pass a group name.");
if (groupName.Length > Limits.MaxGroupNameLength) if (groupName.Length > Limits.MaxGroupNameLength)
throw new PKError($"Group name too long ({groupName.Length}/{Limits.MaxMemberNameLength} characters)."); throw new PKError($"Group name too long ({groupName.Length}/{Limits.MaxGroupNameLength} characters).");
await using var conn = await _db.Obtain(); await using var conn = await _db.Obtain();
@ -41,10 +40,10 @@ namespace PluralKit.Bot
var eb = new DiscordEmbedBuilder() var eb = new DiscordEmbedBuilder()
.WithDescription($"Your new group, **{groupName}**, has been created, with the group ID **`{newGroup.Hid}`**.\nBelow are a couple of useful commands:") .WithDescription($"Your new group, **{groupName}**, has been created, with the group ID **`{newGroup.Hid}`**.\nBelow are a couple of useful commands:")
.AddField("View the group card", $"> pk;group **{newGroup.Hid}**") .AddField("View the group card", $"> pk;group **{GroupReference(newGroup)}**")
.AddField("Add members to the group", $"> pk;group **{newGroup.Hid}** add **MemberName**\n> pk;group **{newGroup.Hid}** add **Member1** **Member2** **Member3** (and so on...)") .AddField("Add members to the group", $"> pk;group **{GroupReference(newGroup)}** add **MemberName**\n> pk;group **{GroupReference(newGroup)}** add **Member1** **Member2** **Member3** (and so on...)")
.AddField("Set the description", $"> pk;group **{newGroup.Hid}** description **This is my new group, and here is the description!**") .AddField("Set the description", $"> pk;group **{GroupReference(newGroup)}** description **This is my new group, and here is the description!**")
.AddField("Set the group icon", $"> pk;group **{newGroup.Hid}** icon\n*(with an image attached)*"); .AddField("Set the group icon", $"> pk;group **{GroupReference(newGroup)}** icon\n*(with an image attached)*");
await ctx.Reply($"{Emojis.Success} Group created!", eb.Build()); await ctx.Reply($"{Emojis.Success} Group created!", eb.Build());
} }
@ -76,7 +75,7 @@ namespace PluralKit.Bot
{ {
if (target.Description == null) if (target.Description == null)
if (ctx.System?.Id == target.System) if (ctx.System?.Id == target.System)
await ctx.Reply($"This group does not have a description set. To set one, type `pk;group {target.Hid} description <description>`."); await ctx.Reply($"This group does not have a description set. To set one, type `pk;group {GroupReference(target)} description <description>`.");
else else
await ctx.Reply("This group does not have a description set."); await ctx.Reply("This group does not have a description set.");
else if (ctx.MatchFlag("r", "raw")) else if (ctx.MatchFlag("r", "raw"))
@ -85,8 +84,8 @@ namespace PluralKit.Bot
await ctx.Reply(embed: new DiscordEmbedBuilder() await ctx.Reply(embed: new DiscordEmbedBuilder()
.WithTitle("Group description") .WithTitle("Group description")
.WithDescription(target.Description) .WithDescription(target.Description)
.AddField("\u200B", $"To print the description with formatting, type `pk;group {target.Hid} description -raw`." .AddField("\u200B", $"To print the description with formatting, type `pk;group {GroupReference(target)} description -raw`."
+ (ctx.System?.Id == target.System ? $" To clear it, type `pk;group {target.Hid} description -clear`." : "")) + (ctx.System?.Id == target.System ? $" To clear it, type `pk;group {GroupReference(target)} description -clear`." : ""))
.Build()); .Build());
} }
else else
@ -163,9 +162,9 @@ namespace PluralKit.Bot
.WithFooter($"System ID: {system.Hid} | Group ID: {target.Hid} | Created on {target.Created.FormatZoned(system)}"); .WithFooter($"System ID: {system.Hid} | Group ID: {target.Hid} | Created on {target.Created.FormatZoned(system)}");
if (memberCount == 0) if (memberCount == 0)
eb.AddField("Members (0)", $"Add one with `pk;group {target.Hid} add <member>`!", true); eb.AddField("Members (0)", $"Add one with `pk;group {GroupReference(target)} add <member>`!", true);
else else
eb.AddField($"Members ({memberCount})", $"(see `pk;group {target.Hid} list`)", true); eb.AddField($"Members ({memberCount})", $"(see `pk;group {GroupReference(target)} list`)", true);
if (target.DescriptionFor(pctx) is {} desc) if (target.DescriptionFor(pctx) is {} desc)
eb.AddField("Description", desc); eb.AddField("Description", desc);
@ -252,7 +251,7 @@ namespace PluralKit.Bot
.AddField("Description", target.DescriptionPrivacy.Explanation()) .AddField("Description", target.DescriptionPrivacy.Explanation())
.AddField("Icon", target.IconPrivacy.Explanation()) .AddField("Icon", target.IconPrivacy.Explanation())
.AddField("Visibility", target.Visibility.Explanation()) .AddField("Visibility", target.Visibility.Explanation())
.WithDescription("To edit privacy settings, use the command:\n`pk;group <group> privacy <subject> <level>`\n\n- `subject` is one of `description`, `icon`, `visibility`, or `all`\n- `level` is either `public` or `private`.") .WithDescription($"To edit privacy settings, use the command:\n`pk;group **{GroupReference(target)}** privacy <subject> <level>`\n\n- `subject` is one of `description`, `icon`, `visibility`, or `all`\n- `level` is either `public` or `private`.")
.Build()); .Build());
return; return;
} }
@ -262,9 +261,9 @@ namespace PluralKit.Bot
await _db.Execute(c => c.UpdateGroup(target.Id, new GroupPatch().WithAllPrivacy(level))); await _db.Execute(c => c.UpdateGroup(target.Id, new GroupPatch().WithAllPrivacy(level)));
if (level == PrivacyLevel.Private) if (level == PrivacyLevel.Private)
await ctx.Reply($"{Emojis.Success} All {target.Name}'s privacy settings have been set to **{level.LevelName()}**. Other accounts will now see nothing on the member card."); await ctx.Reply($"{Emojis.Success} All {target.Name}'s privacy settings have been set to **{level.LevelName()}**. Other accounts will now see nothing on the group card.");
else else
await ctx.Reply($"{Emojis.Success} All {target.Name}'s privacy settings have been set to **{level.LevelName()}**. Other accounts will now see everything on the member card."); await ctx.Reply($"{Emojis.Success} All {target.Name}'s privacy settings have been set to **{level.LevelName()}**. Other accounts will now see everything on the group card.");
} }
async Task SetLevel(GroupPrivacySubject subject, PrivacyLevel level) async Task SetLevel(GroupPrivacySubject subject, PrivacyLevel level)
@ -301,6 +300,19 @@ namespace PluralKit.Bot
await SetLevel(ctx.PopGroupPrivacySubject(), ctx.PopPrivacyLevel()); await SetLevel(ctx.PopGroupPrivacySubject(), ctx.PopPrivacyLevel());
} }
public async Task DeleteGroup(Context ctx, PKGroup target)
{
ctx.CheckOwnGroup(target);
await ctx.Reply($"{Emojis.Warn} Are you sure you want to delete this group? If so, reply to this message with the group's ID (`{target.Hid}`).\n**Note: this action is permanent.**");
if (!await ctx.ConfirmWithReply(target.Hid))
throw new PKError($"Group deletion cancelled. Note that you must reply with your group ID (`{target.Hid}`) *verbatim*.");
await _db.Execute(conn => conn.DeleteGroup(target.Id));
await ctx.Reply($"{Emojis.Success} Group deleted.");
}
private static async Task<PKSystem> GetGroupSystem(Context ctx, PKGroup target, IPKConnection conn) private static async Task<PKSystem> GetGroupSystem(Context ctx, PKGroup target, IPKConnection conn)
{ {
var system = ctx.System; var system = ctx.System;
@ -308,5 +320,12 @@ namespace PluralKit.Bot
return system; return system;
return await conn.QuerySystem(target.System)!; return await conn.QuerySystem(target.System)!;
} }
private static string GroupReference(PKGroup group)
{
if (Regex.IsMatch(group.Name, "[A-Za-z0-9\\-_]+"))
return group.Name;
return group.Hid;
}
} }
} }

View File

@ -76,6 +76,9 @@ namespace PluralKit.Core
return conn.QueryFirstAsync<PKGroup>(query, pms); return conn.QueryFirstAsync<PKGroup>(query, pms);
} }
public static Task DeleteGroup(this IPKConnection conn, GroupId group) =>
conn.ExecuteAsync("delete from groups where id = @Id", new {Id = group });
public static async Task AddMembersToGroup(this IPKConnection conn, GroupId group, IEnumerable<MemberId> members) public static async Task AddMembersToGroup(this IPKConnection conn, GroupId group, IEnumerable<MemberId> members)
{ {
await using var w = conn.BeginBinaryImport("copy group_members (group_id, member_id) from stdin (format binary)"); await using var w = conn.BeginBinaryImport("copy group_members (group_id, member_id) from stdin (format binary)");