diff --git a/PluralKit.Bot/Commands/CommandTree.cs b/PluralKit.Bot/Commands/CommandTree.cs index 5561fe99..e4d12d03 100644 --- a/PluralKit.Bot/Commands/CommandTree.cs +++ b/PluralKit.Bot/Commands/CommandTree.cs @@ -43,7 +43,7 @@ namespace PluralKit.Bot public static Command MemberDisplayName = new Command("member displayname", "member displayname [display name]", "Changes a member's display name"); public static Command MemberServerName = new Command("member servername", "member servername [server name]", "Changes a member's display name in the current server"); public static Command MemberKeepProxy = new Command("member keepproxy", "member keepproxy [on|off]", "Sets whether to include a member's proxy tags when proxying"); - public static Command MemberRandom = new Command("random", "random", "Looks up a random member from your system"); + public static Command MemberRandom = new Command("random", "random", "Shows the info card of a randomly selected member in your system."); public static Command MemberPrivacy = new Command("member privacy", "member privacy ", "Changes a members's privacy settings"); public static Command GroupInfo = new Command("group", "group ", "Looks up information about a group"); public static Command GroupNew = new Command("group new", "group new ", "Creates a new group"); @@ -57,6 +57,8 @@ namespace PluralKit.Bot public static Command GroupPrivacy = new Command("group privacy", "group privacy ", "Changes a group's privacy settings"); public static Command GroupIcon = new Command("group icon", "group icon [url|@mention]", "Changes a group's icon"); public static Command GroupDelete = new Command("group delete", "group delete", "Deletes a group"); + public static Command GroupMemberRandom = new Command("group random", "group random", "Shows the info card of a randomly selected member in a group."); + public static Command GroupRandom = new Command("random", "random group", "Shows the info card of a randomly selected group in your system."); 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"); @@ -102,7 +104,7 @@ namespace PluralKit.Bot public static Command[] GroupCommandsTargeted = { GroupInfo, GroupAdd, GroupRemove, GroupMemberList, GroupRename, GroupDesc, GroupIcon, GroupPrivacy, - GroupDelete + GroupDelete, GroupMemberRandom }; public static Command[] SwitchCommands = {Switch, SwitchOut, SwitchMove, SwitchDelete, SwitchDeleteAll}; @@ -193,7 +195,10 @@ namespace PluralKit.Bot if (ctx.Match("permcheck")) return ctx.Execute(PermCheck, m => m.PermCheckGuild(ctx)); if (ctx.Match("random", "r")) - return ctx.Execute(MemberRandom, m => m.MemberRandom(ctx)); + if (ctx.Match("group", "g") || ctx.MatchFlag("group", "g")) + return ctx.Execute(GroupRandom, r => r.Group(ctx)); + else + return ctx.Execute(MemberRandom, m => m.Member(ctx)); // remove compiler warning return ctx.Reply( @@ -372,6 +377,8 @@ namespace PluralKit.Bot await ctx.Execute(GroupRemove, g => g.AddRemoveMembers(ctx, target, Groups.AddRemoveOperation.Remove)); else if (ctx.Match("members", "list", "ms", "l")) await ctx.Execute(GroupMemberList, g => g.ListGroupMembers(ctx, target)); + else if (ctx.Match("random")) + await ctx.Execute(GroupMemberRandom, r => r.GroupMember(ctx, target)); else if (ctx.Match("privacy")) await ctx.Execute(GroupPrivacy, g => g.GroupPrivacy(ctx, target, null)); else if (ctx.Match("public", "pub")) diff --git a/PluralKit.Bot/Commands/Member.cs b/PluralKit.Bot/Commands/Member.cs index 93bf1687..9998e1f5 100644 --- a/PluralKit.Bot/Commands/Member.cs +++ b/PluralKit.Bot/Commands/Member.cs @@ -61,29 +61,6 @@ namespace PluralKit.Bot await ctx.Reply($"{Emojis.Warn} You are approaching the per-system member limit ({memberCount} / {memberLimit} members). Please review your member list for unused or duplicate members."); } - public async Task MemberRandom(Context ctx) - { - ctx.CheckSystem(); - - var randGen = new global::System.Random(); - //Maybe move this somewhere else in the file structure since it doesn't need to get created at every command - - // TODO: don't buffer these, find something else to do ig - - var members = await _db.Execute(c => - { - if (ctx.MatchFlag("all", "a")) - return _repo.GetSystemMembers(c, ctx.System.Id); - return _repo.GetSystemMembers(c, ctx.System.Id) - .Where(m => m.MemberVisibility == PrivacyLevel.Public); - }).ToListAsync(); - - if (members == null || !members.Any()) - throw Errors.NoMembersError; - var randInt = randGen.Next(members.Count); - await ctx.Reply(embed: await _embeds.CreateMemberEmbed(ctx.System, members[randInt], ctx.Guild, ctx.LookupContextFor(ctx.System))); - } - public async Task ViewMember(Context ctx, PKMember target) { var system = await _db.Execute(c => _repo.GetSystem(c, target.System)); diff --git a/PluralKit.Bot/Commands/Random.cs b/PluralKit.Bot/Commands/Random.cs new file mode 100644 index 00000000..6c154cbc --- /dev/null +++ b/PluralKit.Bot/Commands/Random.cs @@ -0,0 +1,79 @@ +using System.Linq; +using System.Threading.Tasks; + +using PluralKit.Core; + +namespace PluralKit.Bot +{ + public class Random + { + private readonly IDatabase _db; + private readonly ModelRepository _repo; + private readonly EmbedService _embeds; + + private readonly global::System.Random randGen = new global::System.Random(); + + public Random(EmbedService embeds, IDatabase db, ModelRepository repo) + { + _embeds = embeds; + _db = db; + _repo = repo; + } + + // todo: get postgresql to return one random member/group instead of querying all members/groups + + public async Task Member(Context ctx) + { + ctx.CheckSystem(); + + var members = await _db.Execute(c => + { + if (ctx.MatchFlag("all", "a")) + return _repo.GetSystemMembers(c, ctx.System.Id); + return _repo.GetSystemMembers(c, ctx.System.Id) + .Where(m => m.MemberVisibility == PrivacyLevel.Public); + }).ToListAsync(); + + if (members == null || !members.Any()) + throw new PKError("Your system has no members! Please create at least one member before using this command."); + + var randInt = randGen.Next(members.Count); + await ctx.Reply(embed: await _embeds.CreateMemberEmbed(ctx.System, members[randInt], ctx.Guild, ctx.LookupContextFor(ctx.System))); + } + + public async Task Group(Context ctx) + { + ctx.CheckSystem(); + + var groups = await _db.Execute(c => c.QueryGroupList(ctx.System.Id)); + if (!ctx.MatchFlag("all", "a")) + groups = groups.Where(g => g.Visibility == PrivacyLevel.Public); + + if (groups == null || !groups.Any()) + throw new PKError("Your system has no groups! Please create at least one group before using this command."); + + var randInt = randGen.Next(groups.Count()); + await ctx.Reply(embed: await _embeds.CreateGroupEmbed(ctx, ctx.System, groups.ToArray()[randInt])); + } + + public async Task GroupMember(Context ctx, PKGroup group) + { + var opts = ctx.ParseMemberListOptions(ctx.LookupContextFor(group.System)); + opts.GroupFilter = group.Id; + + await using var conn = await _db.Obtain(); + var members = await conn.QueryMemberList(ctx.System.Id, opts.ToQueryOptions()); + + if (members == null || !members.Any()) + throw new PKError("This group has no members! Please add at least one member to this group before using this command."); + + if (!ctx.MatchFlag("all", "a")) + members = members.Where(g => g.MemberVisibility == PrivacyLevel.Public); + + var ms = members.ToList(); + + var randInt = randGen.Next(ms.Count); + await ctx.Reply(embed: await _embeds.CreateMemberEmbed(ctx.System, ms[randInt], ctx.Guild, ctx.LookupContextFor(ctx.System))); + } + } +} \ No newline at end of file diff --git a/PluralKit.Bot/Errors.cs b/PluralKit.Bot/Errors.cs index 79600f68..4ad5a2d0 100644 --- a/PluralKit.Bot/Errors.cs +++ b/PluralKit.Bot/Errors.cs @@ -45,7 +45,6 @@ namespace PluralKit.Bot { public static PKError MemberNameTooLongError(int length) => new PKError($"Member name too long ({length}/{Limits.MaxMemberNameLength} characters)."); public static PKError MemberPronounsTooLongError(int length) => new PKError($"Member pronouns too long ({length}/{Limits.MaxMemberNameLength} characters)."); public static PKError MemberLimitReachedError(int limit) => new PKError($"System has reached the maximum number of members ({limit}). Please delete unused members first in order to create new ones."); - public static PKError NoMembersError => new PKError("Your system has no members! Please create at least one member before using this command."); public static PKError InvalidColorError(string color) => new PKError($"\"{color}\" is not a valid color. Color must be in 6-digit RGB hex format (eg. #ff0000)."); public static PKError BirthdayParseError(string birthday) => new PKError($"\"{birthday}\" could not be parsed as a valid date. Try a format like \"2016-12-24\" or \"May 3 1996\"."); diff --git a/PluralKit.Bot/Modules.cs b/PluralKit.Bot/Modules.cs index 5841149f..1dfb74c1 100644 --- a/PluralKit.Bot/Modules.cs +++ b/PluralKit.Bot/Modules.cs @@ -42,6 +42,7 @@ namespace PluralKit.Bot builder.RegisterType().AsSelf(); builder.RegisterType().AsSelf(); builder.RegisterType().AsSelf(); + builder.RegisterType().AsSelf(); builder.RegisterType().AsSelf(); builder.RegisterType().AsSelf(); builder.RegisterType().AsSelf(); diff --git a/docs/content/command-list.md b/docs/content/command-list.md index 0eed6ac8..8858afc6 100644 --- a/docs/content/command-list.md +++ b/docs/content/command-list.md @@ -54,7 +54,6 @@ Words in **\** or **[square brackets]** mean fill-in-the-blank. - `pk;member color [color]` - Changes the color of a member. - `pk;member birthdate [birthdate]` - Changes the birthday of a member. - `pk;member delete` - Deletes a member. -- `pk;random` - Shows the member card of a randomly selected member in your system. ## Group commands *Replace `` with a group's name, 5-character ID or display name. For most commands, adding `-clear` will clear/delete the field.* @@ -62,6 +61,7 @@ Words in **\** or **[square brackets]** mean fill-in-the-blank. - `pk;group new ` - Creates a new group. - `pk;group list` - Lists all groups in your system. - `pk;group list` - Lists all members in a group. +- `pk;group random` - Shows the info card of a randomly selected member in a group. - `pk;group rename ` - Renames a group. - `pk;group displayname [display name]` - Shows or changes a group's display name. - `pk;group description [description]` - Shows or changes a group's description. @@ -89,6 +89,7 @@ Words in **\** or **[square brackets]** mean fill-in-the-blank. - `pk;blacklist remove <#channel> [#channel...]` - Removes the given channel(s) from the proxy blacklist. ## Utility +- `pk;random [-group]` - Shows the info card of a randomly selected member [or group] in your system. - `pk;message ` - Looks up information about a proxied message by its message ID or link. - `pk;invite` - Sends the bot invite link for PluralKit. - `pk;import` - Imports a data file from PluralKit or Tupperbox.