Refactor system/member privacy commands

This commit is contained in:
Ske 2020-07-08 00:46:58 +02:00
parent 1449234a84
commit 9f523b3c5f
8 changed files with 249 additions and 196 deletions

View File

@ -372,29 +372,6 @@ 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.");
} }
private DiscordEmbed CreatePrivacyEmbed(Context ctx, PKMember member)
{
string PrivacyLevelString(PrivacyLevel level) => level switch
{
PrivacyLevel.Private => "**Private** (visible only when queried by you)",
PrivacyLevel.Public => "**Public** (visible to everyone)",
_ => throw new ArgumentOutOfRangeException(nameof(level), level, null)
};
var eb = new DiscordEmbedBuilder()
.WithTitle($"Current privacy settings for {member.NameFor(ctx)}")
.AddField("Name (replaces name with display name if member has one)",PrivacyLevelString(member.NamePrivacy))
.AddField("Description", PrivacyLevelString(member.DescriptionPrivacy))
.AddField("Avatar", PrivacyLevelString(member.AvatarPrivacy))
.AddField("Birthday", PrivacyLevelString(member.BirthdayPrivacy))
.AddField("Pronouns", PrivacyLevelString(member.PronounPrivacy))
// .AddField("Color", PrivacyLevelString(target.ColorPrivacy))
.AddField("Meta (message count, last front, last message)", PrivacyLevelString(member.MetadataPrivacy))
.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`, `avatar`, `birthday`, `pronouns`, `created`, `messages`, `visibility`, or `all`\n- `level` is either `public` or `private`.");
return eb.Build();
}
public async Task Privacy(Context ctx, PKMember target, PrivacyLevel? newValueFromCommand) public async Task Privacy(Context ctx, PKMember target, PrivacyLevel? newValueFromCommand)
{ {
if (ctx.System == null) throw Errors.NoSystemError; if (ctx.System == null) throw Errors.NoSystemError;
@ -403,7 +380,17 @@ namespace PluralKit.Bot
// Display privacy settings // Display privacy settings
if (!ctx.HasNext() && newValueFromCommand == null) if (!ctx.HasNext() && newValueFromCommand == null)
{ {
await ctx.Reply(embed: CreatePrivacyEmbed(ctx, target)); await ctx.Reply(embed: new DiscordEmbedBuilder()
.WithTitle($"Current privacy settings for {target.NameFor(ctx)}")
.AddField("Name (replaces name with display name if member has one)",target.NamePrivacy.Explanation())
.AddField("Description", target.DescriptionPrivacy.Explanation())
.AddField("Avatar", target.AvatarPrivacy.Explanation())
.AddField("Birthday", target.BirthdayPrivacy.Explanation())
.AddField("Pronouns", target.PronounPrivacy.Explanation())
.AddField("Meta (message count, last front, last message)",target.MetadataPrivacy.Explanation())
.AddField("Visibility", target.MemberVisibility.Explanation())
.WithDescription("To edit privacy settings, use the command:\n`pk;member <member> privacy <subject> <level>`\n\n- `subject` is one of `name`, `description`, `avatar`, `birthday`, `pronouns`, `created`, `messages`, `visibility`, or `all`\n- `level` is either `public` or `private`.")
.Build());
return; return;
} }
@ -412,37 +399,33 @@ namespace PluralKit.Bot
if (ctx.Guild != null) if (ctx.Guild != null)
guildSettings = await _db.Execute(c => c.QueryOrInsertMemberGuildConfig(ctx.Guild.Id, target.Id)); guildSettings = await _db.Execute(c => c.QueryOrInsertMemberGuildConfig(ctx.Guild.Id, target.Id));
// Set Privacy Settings async Task SetAll(PrivacyLevel level)
PrivacyLevel PopPrivacyLevel(string subjectName)
{ {
if (ctx.Match("public", "show", "shown", "visible")) await _db.Execute(c => c.UpdateMember(target.Id, new MemberPatch().WithAllPrivacy(level)));
return PrivacyLevel.Public;
if (level == PrivacyLevel.Private)
if (ctx.Match("private", "hide", "hidden")) await ctx.Reply($"{Emojis.Success} All {target.NameFor(ctx)}'s privacy settings have been set to **{level.LevelName()}**. Other accounts will now see nothing on the member card.");
return PrivacyLevel.Private; else
await ctx.Reply($"{Emojis.Success} All {target.NameFor(ctx)}'s privacy settings have been set to **{level.LevelName()}**. Other accounts will now see everything on the member card.");
if (!ctx.HasNext())
throw new PKSyntaxError($"You must pass a privacy level for `{subjectName}` (`public` or `private`)");
throw new PKSyntaxError($"Invalid privacy level `{ctx.PopArgument()}` (must be `public` or `private`).");
} }
// See if we have a subject given
PrivacyLevel newLevel;
if (PrivacyUtils.TryParseMemberPrivacy(ctx.PeekArgument(), out var subject))
{
// We peeked before, pop it now
ctx.PopArgument();
// Read the privacy level from args
newLevel = PopPrivacyLevel(subject.Name());
// Set the level on the given subject
var patch = new MemberPatch();
patch.SetPrivacy(subject, newLevel);
await _db.Execute(conn => conn.UpdateMember(target.Id, patch));
// Print response async Task SetLevel(MemberPrivacySubject subject, PrivacyLevel level)
var explanation = (subject, newLevel) switch {
await _db.Execute(c => c.UpdateMember(target.Id, new MemberPatch().WithPrivacy(subject, level)));
var subjectName = subject switch
{
MemberPrivacySubject.Name => "name privacy",
MemberPrivacySubject.Description => "description privacy",
MemberPrivacySubject.Avatar => "avatar privacy",
MemberPrivacySubject.Pronouns => "pronoun privacy",
MemberPrivacySubject.Birthday => "birthday privacy",
MemberPrivacySubject.Metadata => "metadata privacy",
MemberPrivacySubject.Visibility => "visibility",
_ => throw new ArgumentOutOfRangeException($"Unknown privacy subject {subject}")
};
var explanation = (subject, level) switch
{ {
(MemberPrivacySubject.Name, PrivacyLevel.Private) => "This member's name is now hidden from other systems, and will be replaced by the member's display name.", (MemberPrivacySubject.Name, PrivacyLevel.Private) => "This member's name is now hidden from other systems, and will be replaced by the member's display name.",
(MemberPrivacySubject.Description, PrivacyLevel.Private) => "This member's description is now hidden from other systems.", (MemberPrivacySubject.Description, PrivacyLevel.Private) => "This member's description is now hidden from other systems.",
@ -460,37 +443,24 @@ namespace PluralKit.Bot
(MemberPrivacySubject.Metadata, PrivacyLevel.Public) => "This member's metadata (eg. created timestamp, message count, etc) is no longer hidden from 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.", (MemberPrivacySubject.Visibility, PrivacyLevel.Public) => "This member is no longer hidden from member lists.",
_ => throw new InvalidOperationException($"Invalid subject/level tuple ({subject}, {newLevel})") _ => throw new InvalidOperationException($"Invalid subject/level tuple ({subject}, {level})")
}; };
await ctx.Reply($"{Emojis.Success} {target.NameFor(ctx)}'s {subject.Name()} has been set to **{newLevel.LevelName()}**. {explanation}"); await ctx.Reply($"{Emojis.Success} {target.NameFor(ctx)}'s **{subjectName}** has been set to **{level.LevelName()}**. {explanation}");
}
else if (ctx.Match("all") || newValueFromCommand != null)
{
newLevel = newValueFromCommand ?? PopPrivacyLevel("all");
var patch = new MemberPatch(); // Name privacy only works given a display name
patch.SetAllPrivacy(newLevel); if (subject == MemberPrivacySubject.Name && level == PrivacyLevel.Private && target.DisplayName == null)
await _db.Execute(conn => conn.UpdateMember(target.Id, patch)); await ctx.Reply($"{Emojis.Warn} This member does not have a display name set, and name privacy **will not take effect**.");
if(newLevel == PrivacyLevel.Private) // Avatar privacy doesn't apply when proxying if no server avatar is set
await ctx.Reply($"All {target.NameFor(ctx)}'s privacy settings have been set to **{newLevel.LevelName()}**. Other accounts will now see nothing on the member card."); if (subject == MemberPrivacySubject.Avatar && level == PrivacyLevel.Private && guildSettings?.AvatarUrl == null)
else await ctx.Reply($"{Emojis.Warn} This member does not have a server avatar set, so *proxying* will **still show the member avatar**. If you want to hide your avatar when proxying here, set a server avatar: `pk;member {target.Hid} serveravatar`");
await ctx.Reply($"All {target.NameFor(ctx)}'s privacy settings have been set to **{newLevel.LevelName()}**. Other accounts will now see everything on the member card.");
} }
if (ctx.Match("all") || newValueFromCommand != null)
await SetAll(newValueFromCommand ?? ctx.PopPrivacyLevel());
else else
{ await SetLevel(ctx.PopMemberPrivacySubject(), ctx.PopPrivacyLevel());
var subjectList = "`name`, `description`, `avatar`, `birthday`, `pronouns`, `metadata`, `visibility`, or `all`";
throw new PKSyntaxError($"Invalid privacy subject `{ctx.PopArgument()}` (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**.");
// Avatar privacy doesn't apply when proxying if no server avatar is set
if (subject == MemberPrivacySubject.Avatar && newLevel == PrivacyLevel.Private &&
guildSettings?.AvatarUrl == null)
await ctx.Reply($"{Emojis.Warn} This member does not have a server avatar set, so *proxying* will **still show the member avatar**. If you want to hide your avatar when proxying here, set a server avatar: `pk;member {target.Hid} serveravatar`");
} }
public async Task Delete(Context ctx, PKMember target) public async Task Delete(Context ctx, PKMember target)

View File

@ -0,0 +1,39 @@
using PluralKit.Core;
namespace PluralKit.Bot
{
public static class ContextPrivacyExt
{
public static PrivacyLevel PopPrivacyLevel(this Context ctx)
{
if (ctx.Match("public", "show", "shown", "visible"))
return PrivacyLevel.Public;
if (ctx.Match("private", "hide", "hidden"))
return PrivacyLevel.Private;
if (!ctx.HasNext())
throw new PKSyntaxError("You must pass a privacy level (`public` or `private`)");
throw new PKSyntaxError($"Invalid privacy level `{ctx.PopArgument()}` (must be `public` or `private`).");
}
public static SystemPrivacySubject PopSystemPrivacySubject(this Context ctx)
{
if (!SystemPrivacyUtils.TryParseSystemPrivacy(ctx.PeekArgument(), out var subject))
throw new PKSyntaxError($"Invalid privacy subject `{ctx.PopArgument()}` (must be `description`, `members`, `front`, `fronthistory`, or `all`).");
ctx.PopArgument();
return subject;
}
public static MemberPrivacySubject PopMemberPrivacySubject(this Context ctx)
{
if (!MemberPrivacyUtils.TryParseMemberPrivacy(ctx.PeekArgument(), out var subject))
throw new PKSyntaxError($"Invalid privacy subject `{ctx.PopArgument()}` (must be `name`, `description`, `avatar`, `birthday`, `pronouns`, `metadata`, `visibility`, or `all).");
ctx.PopArgument();
return subject;
}
}
}

View File

@ -13,6 +13,8 @@ using NodaTime.TimeZones;
using PluralKit.Core; using PluralKit.Core;
using Sentry.Protocol;
namespace PluralKit.Bot namespace PluralKit.Bot
{ {
public class SystemEdit public class SystemEdit
@ -261,93 +263,62 @@ namespace PluralKit.Bot
{ {
ctx.CheckSystem(); ctx.CheckSystem();
if (!ctx.HasNext()) Task PrintEmbed()
{ {
string PrivacyLevelString(PrivacyLevel level) => level switch
{
PrivacyLevel.Private => "**Private** (visible only when queried by you)",
PrivacyLevel.Public => "**Public** (visible to everyone)",
_ => throw new ArgumentOutOfRangeException(nameof(level), level, null)
};
var eb = new DiscordEmbedBuilder() var eb = new DiscordEmbedBuilder()
.WithTitle("Current privacy settings for your system") .WithTitle("Current privacy settings for your system")
.AddField("Description", PrivacyLevelString(ctx.System.DescriptionPrivacy)) .AddField("Description", ctx.System.DescriptionPrivacy.Explanation())
.AddField("Member list", PrivacyLevelString(ctx.System.MemberListPrivacy)) .AddField("Member list", ctx.System.MemberListPrivacy.Explanation())
.AddField("Current fronter(s)", PrivacyLevelString(ctx.System.FrontPrivacy)) .AddField("Current fronter(s)", ctx.System.FrontPrivacy.Explanation())
.AddField("Front/switch history", PrivacyLevelString(ctx.System.FrontHistoryPrivacy)) .AddField("Front/switch history", ctx.System.FrontHistoryPrivacy.Explanation())
.WithDescription("To edit privacy settings, use the command:\n`pk;system privacy <subject> <level>`\n\n- `subject` is one of `description`, `list`, `front`, `fronthistory`, or `all` \n- `level` is either `public` or `private`."); .WithDescription("To edit privacy settings, use the command:\n`pk;system privacy <subject> <level>`\n\n- `subject` is one of `description`, `list`, `front`, `fronthistory`, or `all` \n- `level` is either `public` or `private`.");
await ctx.Reply(embed: eb.Build()); return ctx.Reply(embed: eb.Build());
return;
} }
PrivacyLevel PopPrivacyLevel(string subject, out string levelStr, out string levelExplanation) async Task SetLevel(SystemPrivacySubject subject, PrivacyLevel level)
{ {
if (ctx.Match("public", "show", "shown", "visible")) await _db.Execute(conn => conn.UpdateSystem(ctx.System.Id, new SystemPatch().WithPrivacy(subject, level)));
var levelExplanation = level switch
{ {
levelStr = "public"; PrivacyLevel.Public => "be able to query",
levelExplanation = "be able to query"; PrivacyLevel.Private => "*not* be able to query",
return PrivacyLevel.Public; _ => ""
} };
if (ctx.Match("private", "hide", "hidden")) var subjectStr = subject switch
{ {
levelStr = "private"; SystemPrivacySubject.Description => "description",
levelExplanation = "*not* be able to query"; SystemPrivacySubject.Front => "front",
return PrivacyLevel.Private; SystemPrivacySubject.FrontHistory => "front history",
} SystemPrivacySubject.MemberList => "member list",
_ => ""
};
if (!ctx.HasNext()) var msg = $"System {subjectStr} privacy has been set to **{level.LevelName()}**. Other accounts will now {levelExplanation} your system {subjectStr}.";
throw new PKSyntaxError($"You must pass a privacy level for `{subject}` (`public` or `private`)"); await ctx.Reply($"{Emojis.Success} {msg}");
throw new PKSyntaxError($"Invalid privacy level `{ctx.PopArgument()}` (must be `public` or `private`).");
} }
string levelStr, levelExplanation, subjectStr; async Task SetAll(PrivacyLevel level)
var subjectList = "`description`, `members`, `front`, `fronthistory`, or `all`";
SystemPatch patch = new SystemPatch();
if (ctx.Match("description", "desc", "text", "info"))
{ {
subjectStr = "description"; await _db.Execute(conn => conn.UpdateSystem(ctx.System.Id, new SystemPatch().WithAllPrivacy(level)));
patch.DescriptionPrivacy = PopPrivacyLevel("description", out levelStr, out levelExplanation);
}
else if (ctx.Match("members", "memberlist", "list", "mlist"))
{
subjectStr = "member list";
patch.MemberListPrivacy = PopPrivacyLevel("members", out levelStr, out levelExplanation);
}
else if (ctx.Match("front", "fronter"))
{
subjectStr = "fronter(s)";
patch.FrontPrivacy = PopPrivacyLevel("front", out levelStr, out levelExplanation);
}
else if (ctx.Match("switch", "switches", "fronthistory", "fh"))
{
subjectStr = "front history";
patch.FrontHistoryPrivacy = PopPrivacyLevel("fronthistory", out levelStr, out levelExplanation);
}
else if (ctx.Match("all")){
subjectStr = "all";
PrivacyLevel level = PopPrivacyLevel("all", out levelStr, out levelExplanation);
patch.DescriptionPrivacy = level;
patch.MemberListPrivacy = level;
patch.FrontPrivacy = level;
patch.FrontHistoryPrivacy = level;
var msg = level switch
{
PrivacyLevel.Private => $"All system privacy settings have been set to **{level.LevelName()}**. Other accounts will now not be able to view your member list, front history, or system description.",
PrivacyLevel.Public => $"All system privacy settings have been set to **{level.LevelName()}**. Other accounts will now be able to view everything.",
_ => ""
};
await ctx.Reply($"{Emojis.Success} {msg}");
} }
if (!ctx.HasNext())
await PrintEmbed();
else if (ctx.Match("all"))
await SetAll(ctx.PopPrivacyLevel());
else else
throw new PKSyntaxError($"Invalid privacy subject `{ctx.PopArgument()}` (must be {subjectList})."); await SetLevel(ctx.PopSystemPrivacySubject(), ctx.PopPrivacyLevel());
await _db.Execute(conn => conn.UpdateSystem(ctx.System.Id, patch));
if(subjectStr == "all"){
if(levelStr == "private")
await ctx.Reply($"All of your systems privacy settings have been set to **{levelStr}**. Other accounts will now see nothing on the member card.");
else
await ctx.Reply($"All of your systems privacy have been set to **{levelStr}**. Other accounts will now see everything on the member card.");
}
//Handle other subjects
else
await ctx.Reply($"System {subjectStr} privacy has been set to **{levelStr}**. Other accounts will now {levelExplanation} your system {subjectStr}.");
} }
public async Task SystemPing(Context ctx) public async Task SystemPing(Context ctx)

View File

@ -0,0 +1,9 @@
namespace PluralKit.Core
{
public enum LookupContext
{
ByOwner,
ByNonOwner,
API
}
}

View File

@ -2,7 +2,8 @@
namespace PluralKit.Core namespace PluralKit.Core
{ {
public enum MemberPrivacySubject { public enum MemberPrivacySubject
{
Visibility, Visibility,
Name, Name,
Description, Description,
@ -11,48 +12,34 @@ namespace PluralKit.Core
Pronouns, Pronouns,
Metadata Metadata
} }
public static class PrivacyUtils
{
public static string Name(this MemberPrivacySubject subject) => subject switch
{
MemberPrivacySubject.Name => "name",
MemberPrivacySubject.Description => "description",
MemberPrivacySubject.Avatar => "avatar",
MemberPrivacySubject.Pronouns => "pronouns",
MemberPrivacySubject.Birthday => "birthday",
MemberPrivacySubject.Metadata => "metadata",
MemberPrivacySubject.Visibility => "visibility",
_ => throw new ArgumentOutOfRangeException($"Unknown privacy subject {subject}")
};
public static void SetPrivacy(this MemberPatch member, MemberPrivacySubject subject, PrivacyLevel level) public static class MemberPrivacyUtils
{
public static MemberPatch WithPrivacy(this MemberPatch member, MemberPrivacySubject subject, PrivacyLevel level)
{ {
// what do you mean switch expressions can't be statements >.> // what do you mean switch expressions can't be statements >.>
_ = subject switch _ = subject switch
{ {
MemberPrivacySubject.Name => member.NamePrivacy = Partial<PrivacyLevel>.Present(level), MemberPrivacySubject.Name => member.NamePrivacy = level,
MemberPrivacySubject.Description => member.DescriptionPrivacy = Partial<PrivacyLevel>.Present(level), MemberPrivacySubject.Description => member.DescriptionPrivacy = level,
MemberPrivacySubject.Avatar => member.AvatarPrivacy = Partial<PrivacyLevel>.Present(level), MemberPrivacySubject.Avatar => member.AvatarPrivacy = level,
MemberPrivacySubject.Pronouns => member.PronounPrivacy = Partial<PrivacyLevel>.Present(level), MemberPrivacySubject.Pronouns => member.PronounPrivacy = level,
MemberPrivacySubject.Birthday => member.BirthdayPrivacy= Partial<PrivacyLevel>.Present(level), MemberPrivacySubject.Birthday => member.BirthdayPrivacy = level,
MemberPrivacySubject.Metadata => member.MetadataPrivacy = Partial<PrivacyLevel>.Present(level), MemberPrivacySubject.Metadata => member.MetadataPrivacy = level,
MemberPrivacySubject.Visibility => member.Visibility = Partial<PrivacyLevel>.Present(level), MemberPrivacySubject.Visibility => member.Visibility = level,
_ => throw new ArgumentOutOfRangeException($"Unknown privacy subject {subject}") _ => throw new ArgumentOutOfRangeException($"Unknown privacy subject {subject}")
}; };
return member;
} }
public static void SetAllPrivacy(this MemberPatch member, PrivacyLevel level) public static MemberPatch WithAllPrivacy(this MemberPatch member, PrivacyLevel level)
{ {
member.NamePrivacy = Partial<PrivacyLevel>.Present(level); foreach (var subject in Enum.GetValues(typeof(MemberPrivacySubject)))
member.DescriptionPrivacy = Partial<PrivacyLevel>.Present(level); member.WithPrivacy((MemberPrivacySubject) subject, level);
member.AvatarPrivacy = Partial<PrivacyLevel>.Present(level); return member;
member.PronounPrivacy = Partial<PrivacyLevel>.Present(level);
member.BirthdayPrivacy = Partial<PrivacyLevel>.Present(level);
member.MetadataPrivacy = Partial<PrivacyLevel>.Present(level);
member.Visibility = Partial<PrivacyLevel>.Present(level);
} }
public static bool TryParseMemberPrivacy(string input, out MemberPrivacySubject subject) public static bool TryParseMemberPrivacy(string input, out MemberPrivacySubject subject)
{ {
switch (input.ToLowerInvariant()) switch (input.ToLowerInvariant())
@ -89,7 +76,7 @@ namespace PluralKit.Core
subject = MemberPrivacySubject.Metadata; subject = MemberPrivacySubject.Metadata;
break; break;
case "visibility": case "visibility":
case "hidden": case "hidden":
case "shown": case "shown":
case "visible": case "visible":
case "list": case "list":
@ -99,7 +86,8 @@ namespace PluralKit.Core
subject = MemberPrivacySubject.Name; subject = MemberPrivacySubject.Name;
return false; return false;
} }
return true; return true;
} }
} }
} }

View File

@ -1,11 +1,7 @@
namespace PluralKit.Core using System;
{
public enum PrivacyLevel
{
Public = 1,
Private = 2
}
namespace PluralKit.Core
{
public static class PrivacyExt public static class PrivacyExt
{ {
public static bool CanAccess(this PrivacyLevel level, LookupContext ctx) => public static bool CanAccess(this PrivacyLevel level, LookupContext ctx) =>
@ -16,6 +12,14 @@
public static T Get<T>(this PrivacyLevel level, LookupContext ctx, T input, T fallback = default) => public static T Get<T>(this PrivacyLevel level, LookupContext ctx, T input, T fallback = default) =>
level.CanAccess(ctx) ? input : fallback; level.CanAccess(ctx) ? input : fallback;
public static string Explanation(this PrivacyLevel level) =>
level switch
{
PrivacyLevel.Private => "**Private** (visible only when queried by you)",
PrivacyLevel.Public => "**Public** (visible to everyone)",
_ => throw new ArgumentOutOfRangeException(nameof(level), level, null)
};
public static bool TryGet<T>(this PrivacyLevel level, LookupContext ctx, T input, out T output, T absentValue = default) public static bool TryGet<T>(this PrivacyLevel level, LookupContext ctx, T input, out T output, T absentValue = default)
{ {
@ -29,11 +33,4 @@
return true; return true;
} }
} }
public enum LookupContext
{
ByOwner,
ByNonOwner,
API
}
} }

View File

@ -0,0 +1,8 @@
namespace PluralKit.Core
{
public enum PrivacyLevel
{
Public = 1,
Private = 2
}
}

View File

@ -0,0 +1,71 @@
using System;
namespace PluralKit.Core
{
public enum SystemPrivacySubject
{
Description,
MemberList,
Front,
FrontHistory
}
public static class SystemPrivacyUtils
{
public static SystemPatch WithPrivacy(this SystemPatch system, SystemPrivacySubject subject, PrivacyLevel level)
{
// what do you mean switch expressions can't be statements >.>
_ = subject switch
{
SystemPrivacySubject.Description => system.DescriptionPrivacy = level,
SystemPrivacySubject.Front => system.FrontPrivacy = level,
SystemPrivacySubject.FrontHistory => system.FrontHistoryPrivacy = level,
SystemPrivacySubject.MemberList => system.MemberListPrivacy = level,
_ => throw new ArgumentOutOfRangeException($"Unknown privacy subject {subject}")
};
return system;
}
public static SystemPatch WithAllPrivacy(this SystemPatch system, PrivacyLevel level)
{
foreach (var subject in Enum.GetValues(typeof(SystemPrivacySubject)))
WithPrivacy(system, (SystemPrivacySubject) subject, level);
return system;
}
public static bool TryParseSystemPrivacy(string input, out SystemPrivacySubject subject)
{
switch (input.ToLowerInvariant())
{
case "description":
case "desc":
case "text":
case "info":
subject = SystemPrivacySubject.Description;
break;
case "members":
case "memberlist":
case "list":
case "mlist":
subject = SystemPrivacySubject.MemberList;
break;
case "fronter":
case "fronters":
case "front":
subject = SystemPrivacySubject.Front;
break;
case "switch":
case "switches":
case "fronthistory":
case "fh":
subject = SystemPrivacySubject.FrontHistory;
break;
default:
subject = default;
return false;
}
return true;
}
}
}