Clean up member privacy command

This commit is contained in:
Ske 2020-06-17 23:06:49 +02:00
parent dd2690c3f4
commit 761270f0c3
3 changed files with 172 additions and 110 deletions

View File

@ -360,13 +360,7 @@ namespace PluralKit.Bot
await ctx.Reply($"{Emojis.Success} Member proxy tags will now not be included in the resulting message when proxying."); await ctx.Reply($"{Emojis.Success} Member proxy tags will now not be included in the resulting message when proxying.");
} }
public async Task Privacy(Context ctx, PKMember target, PrivacyLevel? newValueFromCommand) private DiscordEmbed CreatePrivacyEmbed(PKMember member)
{
if (ctx.System == null) throw Errors.NoSystemError;
if (target.System != ctx.System.Id) throw Errors.NotOwnMemberError;
// Display privacy settings
if (!ctx.HasNext() && newValueFromCommand == null)
{ {
string PrivacyLevelString(PrivacyLevel level) => level switch string PrivacyLevelString(PrivacyLevel level) => level switch
{ {
@ -376,126 +370,98 @@ namespace PluralKit.Bot
}; };
var eb = new DiscordEmbedBuilder() var eb = new DiscordEmbedBuilder()
.WithTitle($"Current privacy settings for {target.Name}") .WithTitle($"Current privacy settings for {member.Name}")
.AddField("Name (replaces name with display name if member has one)",PrivacyLevelString(target.NamePrivacy)) .AddField("Name (replaces name with display name if member has one)",PrivacyLevelString(member.NamePrivacy))
.AddField("Description", PrivacyLevelString(target.DescriptionPrivacy)) .AddField("Description", PrivacyLevelString(member.DescriptionPrivacy))
.AddField("Birthday", PrivacyLevelString(target.BirthdayPrivacy)) .AddField("Birthday", PrivacyLevelString(member.BirthdayPrivacy))
.AddField("Pronouns", PrivacyLevelString(target.PronounPrivacy)) .AddField("Pronouns", PrivacyLevelString(member.PronounPrivacy))
// .AddField("Color", PrivacyLevelString(target.ColorPrivacy)) // .AddField("Color", PrivacyLevelString(target.ColorPrivacy))
.AddField("Meta (message count, last front, last message)", PrivacyLevelString(target.MetadataPrivacy)) .AddField("Meta (message count, last front, last message)", PrivacyLevelString(member.MetadataPrivacy))
.AddField("Visibility", PrivacyLevelString(target.MemberVisibility)) .AddField("Visibility", PrivacyLevelString(member.MemberVisibility))
.WithDescription("To edit privacy settings, use the command:\n`pk;member <member> privacy <subject> <level>`\n\n- `subject` is one of `name`, `description`, `birthday`, `pronouns`, `created`, `messages`, `visibility`, or `all`\n- `level` is either `public` or `private`."); .WithDescription("To edit privacy settings, use the command:\n`pk;member <member> privacy <subject> <level>`\n\n- `subject` is one of `name`, `description`, `birthday`, `pronouns`, `created`, `messages`, `visibility`, or `all`\n- `level` is either `public` or `private`.");
await ctx.Reply(embed: eb.Build()); return eb.Build();
}
public async Task Privacy(Context ctx, PKMember target, PrivacyLevel? newValueFromCommand)
{
if (ctx.System == null) throw Errors.NoSystemError;
if (target.System != ctx.System.Id) throw Errors.NotOwnMemberError;
// Display privacy settings
if (!ctx.HasNext() && newValueFromCommand == null)
{
await ctx.Reply(embed: CreatePrivacyEmbed(target));
return; return;
} }
// Set Privacy Settings // Set Privacy Settings
PrivacyLevel PopPrivacyLevel(string subject, out string levelStr, out string levelExplanation) PrivacyLevel PopPrivacyLevel(string subjectName)
{ {
if (ctx.Match("public", "show", "shown", "visible")) if (ctx.Match("public", "show", "shown", "visible"))
{
levelStr = "public";
levelExplanation = "be shown on the member card";
return PrivacyLevel.Public; return PrivacyLevel.Public;
}
if (ctx.Match("private", "hide", "hidden")) if (ctx.Match("private", "hide", "hidden"))
{
levelStr = "private";
levelExplanation = "*not* be shown on the member card";
if(subject == "name") levelExplanation += " unless no display name is set";
return PrivacyLevel.Private; return PrivacyLevel.Private;
}
if (!ctx.HasNext()) if (!ctx.HasNext())
throw new PKSyntaxError($"You must pass a privacy level for `{subject}` (`public` or `private`)"); throw new PKSyntaxError($"You must pass a privacy level for `{subjectName}` (`public` or `private`)");
throw new PKSyntaxError($"Invalid privacy level `{ctx.PopArgument().SanitizeMentions()}` (must be `public` or `private`)."); throw new PKSyntaxError($"Invalid privacy level `{ctx.PopArgument().SanitizeMentions()}` (must be `public` or `private`).");
} }
string levelStr, levelExplanation, subjectStr; // See if we have a subject given
var subjectList = "`name`, `description`, `birthday`, `pronouns`, `metadata`, `visibility`, or `all`"; PrivacyLevel newLevel;
if(ctx.Match("name")) if (PrivacyUtils.TryParseMemberPrivacy(ctx.PeekArgument(), out var subject))
{ {
subjectStr = "name"; // We peeked before, pop it now
target.NamePrivacy = PopPrivacyLevel("name", out levelStr, out levelExplanation); ctx.PopArgument();
}
else if(ctx.Match("description", "desc", "text", "info"))
{
subjectStr = "description";
target.DescriptionPrivacy = PopPrivacyLevel("description", out levelStr, out levelExplanation);
}
else if(ctx.Match("birthday", "birth", "bday"))
{
subjectStr = "birthday";
target.BirthdayPrivacy = PopPrivacyLevel("birthday", out levelStr, out levelExplanation);
}
else if(ctx.Match("pronouns", "pronoun"))
{
subjectStr = "pronouns";
target.PronounPrivacy = PopPrivacyLevel("pronouns", out levelStr, out levelExplanation);
}
/*else if(ctx.Match("color","colour"))
{
subjectStr = "color";
target.ColorPrivacy = PopPrivacyLevel("color", out levelStr, out levelExplanation);
}*/
else if(ctx.Match("meta","metadata"))
{
subjectStr = "metadata (date created, message count, last fronted, and last message)";
target.MetadataPrivacy = PopPrivacyLevel("metadata", out levelStr, out levelExplanation);
}
else if(ctx.Match("visibility","hidden","shown","visible"))
{
subjectStr = "visibility";
target.MemberVisibility = PopPrivacyLevel("visibility", out levelStr, out levelExplanation);
}
else if(ctx.Match("all") || newValueFromCommand != null){
subjectStr = "all";
PrivacyLevel level;
if(newValueFromCommand != null)
{
if(newValueFromCommand == PrivacyLevel.Public)
{
level = PrivacyLevel.Public;
levelStr = "public";
levelExplanation = "be shown on the member card";
}
else
{
level = PrivacyLevel.Private;
levelStr = "private";
levelExplanation = "*not* be shown on the member card";
}
}
else
level = PopPrivacyLevel("all", out levelStr, out levelExplanation);
target.MemberVisibility = level;
target.NamePrivacy = level;
target.DescriptionPrivacy = level;
target.BirthdayPrivacy = level;
target.PronounPrivacy = level;
// target.ColorPrivacy = level;
target.MetadataPrivacy = level;
}
else
throw new PKSyntaxError($"Invalid privacy subject `{ctx.PopArgument().SanitizeMentions()}` (must be {subjectList}).");
// Read the privacy level from args
newLevel = PopPrivacyLevel(subject.Name());
// Set the level on the given subject
target.SetPrivacy(subject, newLevel);
await _data.SaveMember(target); await _data.SaveMember(target);
//Handle "all" subject
if(subjectStr == "all"){ // Print response
if(levelStr == "private") var explanation = (subject, newLevel) switch
await ctx.Reply($"All {target.Name.SanitizeMentions()}'s privacy settings have been set to **{levelStr}**. Other accounts will now see nothing on the member card."); {
else (MemberPrivacySubject.Name, PrivacyLevel.Private) => "This member's name is now hidden from other systems, and will be replaced by the member's display name.",
await ctx.Reply($"All {target.Name.SanitizeMentions()}'s privacy settings have been set to **{levelStr}**. Other accounts will now see everything on the member card."); (MemberPrivacySubject.Description, PrivacyLevel.Private) => "This member's description is now hidden from other systems.",
(MemberPrivacySubject.Birthday, PrivacyLevel.Private) => "This member's birthday is now hidden from other systems.",
(MemberPrivacySubject.Pronouns, PrivacyLevel.Private) => "This member's pronouns are now hidden from other systems.",
(MemberPrivacySubject.Metadata, PrivacyLevel.Private) => "This member's metadata (eg. created timestamp, message count, etc) is now hidden from other systems.",
(MemberPrivacySubject.Visibility, PrivacyLevel.Private) => "This member is now hidden from member lists.",
(MemberPrivacySubject.Name, PrivacyLevel.Public) => "This member's name is no longer hidden from other systems.",
(MemberPrivacySubject.Description, PrivacyLevel.Public) => "This member's description is no longer hidden from other systems.",
(MemberPrivacySubject.Birthday, PrivacyLevel.Public) => "This member's birthday is no longer hidden from other systems.",
(MemberPrivacySubject.Pronouns, PrivacyLevel.Public) => "This member's pronouns are no longer hidden other systems.",
(MemberPrivacySubject.Metadata, PrivacyLevel.Public) => "This member's metadata (eg. created timestamp, message count, etc) is no longer hidden from other systems.",
(MemberPrivacySubject.Visibility, PrivacyLevel.Public) => "This member is no longer hidden from member lists.",
};
await ctx.Reply($"{Emojis.Success} {target.Name.SanitizeMentions()}'s {subject.Name()} has been set to **{newLevel.Name()}**. {explanation}");
} }
//Handle other subjects else if (ctx.Match("all") || newValueFromCommand != null)
{
newLevel = newValueFromCommand ?? PopPrivacyLevel("all");
target.SetAllPrivacy(newLevel);
await _data.SaveMember(target);
if(newLevel == PrivacyLevel.Private)
await ctx.Reply($"All {target.Name.SanitizeMentions()}'s privacy settings have been set to **{newLevel.Name()}**. Other accounts will now see nothing on the member card.");
else else
await ctx.Reply($"{target.Name.SanitizeMentions()}'s {subjectStr} has been set to **{levelStr}**. Other accounts will now {levelExplanation}."); await ctx.Reply($"All {target.Name.SanitizeMentions()}'s privacy settings have been set to **{newLevel.Name()}**. Other accounts will now see everything on the member card.");
}
else
{
var subjectList = "`name`, `description`, `birthday`, `pronouns`, `metadata`, `visibility`, or `all`";
throw new PKSyntaxError($"Invalid privacy subject `{ctx.PopArgument().SanitizeMentions()}` (must be {subjectList}).");
}
// Name privacy only works given a display name
if (subject == MemberPrivacySubject.Name && newLevel == PrivacyLevel.Private && target.DisplayName == null)
await ctx.Reply($"{Emojis.Warn} This member does not have a display name set, and name privacy **will not take effect**.");
} }
public async Task Delete(Context ctx, PKMember target) public async Task Delete(Context ctx, PKMember target)

View File

@ -10,6 +10,9 @@
{ {
public static bool CanAccess(this PrivacyLevel level, LookupContext ctx) => public static bool CanAccess(this PrivacyLevel level, LookupContext ctx) =>
level == PrivacyLevel.Public || ctx == LookupContext.ByOwner; level == PrivacyLevel.Public || ctx == LookupContext.ByOwner;
public static string Name(this PrivacyLevel level) =>
level == PrivacyLevel.Public ? "public" : "private";
} }
public enum LookupContext public enum LookupContext

View File

@ -0,0 +1,93 @@
using System;
namespace PluralKit.Core
{
public enum MemberPrivacySubject {
Visibility,
Name,
Description,
Birthday,
Pronouns,
Metadata
}
public static class PrivacyUtils
{
public static string Name(this MemberPrivacySubject subject) => subject switch
{
MemberPrivacySubject.Name => "name",
MemberPrivacySubject.Description => "description",
MemberPrivacySubject.Pronouns => "pronouns",
MemberPrivacySubject.Birthday => "birthday",
MemberPrivacySubject.Metadata => "metadata",
MemberPrivacySubject.Visibility => "visibility",
_ => throw new ArgumentOutOfRangeException($"Unknown privacy subject {subject}")
};
public static void SetPrivacy(this PKMember member, MemberPrivacySubject subject, PrivacyLevel level)
{
// what do you mean switch expressions can't be statements >.>
_ = subject switch
{
MemberPrivacySubject.Name => member.NamePrivacy = level,
MemberPrivacySubject.Description => member.DescriptionPrivacy = level,
MemberPrivacySubject.Pronouns => member.PronounPrivacy = level,
MemberPrivacySubject.Birthday => member.BirthdayPrivacy= level,
MemberPrivacySubject.Metadata => member.MetadataPrivacy = level,
MemberPrivacySubject.Visibility => member.MemberVisibility = level,
_ => throw new ArgumentOutOfRangeException($"Unknown privacy subject {subject}")
};
}
public static void SetAllPrivacy(this PKMember member, PrivacyLevel level)
{
member.NamePrivacy = level;
member.DescriptionPrivacy = level;
member.PronounPrivacy = level;
member.BirthdayPrivacy = level;
member.MetadataPrivacy = level;
member.MemberVisibility = level;
}
public static bool TryParseMemberPrivacy(string input, out MemberPrivacySubject subject)
{
switch (input.ToLowerInvariant())
{
case "name":
subject = MemberPrivacySubject.Name;
break;
case "description":
case "desc":
case "text":
case "info":
subject = MemberPrivacySubject.Description;
break;
case "birthday":
case "birth":
case "bday":
subject = MemberPrivacySubject.Birthday;
break;
case "pronouns":
case "pronoun":
subject = MemberPrivacySubject.Pronouns;
break;
case "meta":
case "metadata":
case "created":
subject = MemberPrivacySubject.Metadata;
break;
case "visibility":
case "hidden":
case "shown":
case "visible":
case "list":
subject = MemberPrivacySubject.Visibility;
break;
default:
subject = MemberPrivacySubject.Name;
return false;
}
return true;
}
}
}