#nullable enable using System.Text.RegularExpressions; using Newtonsoft.Json.Linq; namespace PluralKit.Core { public class SystemPatch: PatchObject { public Partial Name { get; set; } public Partial Hid { get; set; } public Partial Description { get; set; } public Partial Tag { get; set; } public Partial AvatarUrl { get; set; } public Partial BannerImage { get; set; } public Partial Color { get; set; } public Partial Token { get; set; } public Partial UiTz { get; set; } public Partial DescriptionPrivacy { get; set; } public Partial MemberListPrivacy { get; set; } public Partial GroupListPrivacy { get; set; } public Partial FrontPrivacy { get; set; } public Partial FrontHistoryPrivacy { get; set; } public Partial PingsEnabled { get; set; } public Partial LatchTimeout { get; set; } public Partial MemberLimitOverride { get; set; } public Partial GroupLimitOverride { get; set; } public override UpdateQueryBuilder Apply(UpdateQueryBuilder b) => b .With("name", Name) .With("hid", Hid) .With("description", Description) .With("tag", Tag) .With("avatar_url", AvatarUrl) .With("banner_image", BannerImage) .With("color", Color) .With("token", Token) .With("ui_tz", UiTz) .With("description_privacy", DescriptionPrivacy) .With("member_list_privacy", MemberListPrivacy) .With("group_list_privacy", GroupListPrivacy) .With("front_privacy", FrontPrivacy) .With("front_history_privacy", FrontHistoryPrivacy) .With("pings_enabled", PingsEnabled) .With("latch_timeout", LatchTimeout) .With("member_limit_override", MemberLimitOverride) .With("group_limit_override", GroupLimitOverride); public new void CheckIsValid() { if (AvatarUrl.Value != null && !MiscUtils.TryMatchUri(AvatarUrl.Value, out var avatarUri)) throw new InvalidPatchException("avatar_url"); if (BannerImage.Value != null && !MiscUtils.TryMatchUri(BannerImage.Value, out var bannerImage)) throw new InvalidPatchException("banner"); if (Color.Value != null && (!Regex.IsMatch(Color.Value, "^[0-9a-fA-F]{6}$"))) throw new InvalidPatchException("color"); } public static SystemPatch FromJSON(JObject o) { var patch = new SystemPatch(); if (o.ContainsKey("name")) patch.Name = o.Value("name").NullIfEmpty().BoundsCheckField(Limits.MaxSystemNameLength, "System name"); if (o.ContainsKey("description")) patch.Description = o.Value("description").NullIfEmpty().BoundsCheckField(Limits.MaxDescriptionLength, "System description"); if (o.ContainsKey("tag")) patch.Tag = o.Value("tag").NullIfEmpty().BoundsCheckField(Limits.MaxSystemTagLength, "System tag"); if (o.ContainsKey("avatar_url")) patch.AvatarUrl = o.Value("avatar_url").NullIfEmpty().BoundsCheckField(Limits.MaxUriLength, "System avatar URL"); if (o.ContainsKey("banner")) patch.BannerImage = o.Value("banner").NullIfEmpty().BoundsCheckField(Limits.MaxUriLength, "System banner URL"); if (o.ContainsKey("timezone")) patch.UiTz = o.Value("tz") ?? "UTC"; // legacy: APIv1 uses "tz" instead of "timezone" // todo: remove in APIv2 if (o.ContainsKey("tz")) patch.UiTz = o.Value("tz") ?? "UTC"; if (o.ContainsKey("description_privacy")) patch.DescriptionPrivacy = o.Value("description_privacy").ParsePrivacy("description"); if (o.ContainsKey("member_list_privacy")) patch.MemberListPrivacy = o.Value("member_list_privacy").ParsePrivacy("member list"); if (o.ContainsKey("front_privacy")) patch.FrontPrivacy = o.Value("front_privacy").ParsePrivacy("front"); if (o.ContainsKey("front_history_privacy")) patch.FrontHistoryPrivacy = o.Value("front_history_privacy").ParsePrivacy("front history"); return patch; } } }