コード例 #1
0
        private async Task DoSwitchCommand(Context ctx, ICollection <PKMember> members)
        {
            // Make sure there are no dupes in the list
            // We do this by checking if removing duplicate member IDs results in a list of different length
            if (members.Select(m => m.Id).Distinct().Count() != members.Count)
            {
                throw Errors.DuplicateSwitchMembers;
            }

            // Find the last switch and its members if applicable
            await using var conn = await _db.Obtain();

            var lastSwitch = await _repo.GetLatestSwitch(conn, ctx.System.Id);

            if (lastSwitch != null)
            {
                var lastSwitchMembers = _repo.GetSwitchMembers(conn, lastSwitch.Id);
                // Make sure the requested switch isn't identical to the last one
                if (await lastSwitchMembers.Select(m => m.Id).SequenceEqualAsync(members.Select(m => m.Id).ToAsyncEnumerable()))
                {
                    throw Errors.SameSwitch(members, ctx.LookupContextFor(ctx.System));
                }
            }

            await _repo.AddSwitch(conn, ctx.System.Id, members.Select(m => m.Id).ToList());

            if (members.Count == 0)
            {
                await ctx.Reply($"{Emojis.Success} Switch-out registered.");
            }
            else
            {
                await ctx.Reply($"{Emojis.Success} Switch registered. Current fronter is now {string.Join(", ", members.Select(m => m.NameFor(ctx)))}.");
            }
        }
コード例 #2
0
ファイル: SystemController.cs プロジェクト: xSke/PluralKit
    public async Task <IActionResult> PostSwitch([FromBody] PostSwitchParams param)
    {
        if (param.Members.Distinct().Count() != param.Members.Count)
        {
            return(BadRequest("Duplicate members in member list."));
        }

        await using var conn = await _db.Obtain();

        // We get the current switch, if it exists
        var latestSwitch = await _repo.GetLatestSwitch(User.CurrentSystem());

        if (latestSwitch != null)
        {
            var latestSwitchMembers = _repo.GetSwitchMembers(conn, latestSwitch.Id);

            // Bail if this switch is identical to the latest one
            if (await latestSwitchMembers.Select(m => m.Hid).SequenceEqualAsync(param.Members.ToAsyncEnumerable()))
            {
                return(BadRequest("New members identical to existing fronters."));
            }
        }

        // Resolve member objects for all given IDs
        var membersList =
            (await conn.QueryAsync <PKMember>("select * from members where hid = any(@Hids)",
                                              new { Hids = param.Members })).ToList();

        foreach (var member in membersList)
        {
            if (member.System != User.CurrentSystem())
            {
                return(BadRequest($"Cannot switch to member '{member.Hid}' not in system."));
            }
        }

        // membersList is in DB order, and we want it in actual input order
        // so we go through a dict and map the original input appropriately
        var membersDict = membersList.ToDictionary(m => m.Hid);

        var membersInOrder = new List <PKMember>();

        // We do this without .Select() since we want to have the early return bail if it doesn't find the member
        foreach (var givenMemberId in param.Members)
        {
            if (!membersDict.TryGetValue(givenMemberId, out var member))
            {
                return(BadRequest($"Member '{givenMemberId}' not found."));
            }
            membersInOrder.Add(member);
        }

        // Finally, log the switch (yay!)
        await _repo.AddSwitch(conn, User.CurrentSystem(), membersInOrder.Select(m => m.Id).ToList());

        return(NoContent());
    }