members: add role change impl

- lazy_guild: add to online/offline groups when role isnt hoisted
 - schemas: fix MEMBER_UPDATE.nick
This commit is contained in:
Luna Mendes 2018-10-27 21:50:15 -03:00
parent 72465abdcb
commit ce5b75921a
4 changed files with 68 additions and 6 deletions

View File

@ -3,6 +3,10 @@ from quart import Blueprint, request, current_app as app, jsonify
from litecord.blueprints.auth import token_check
from litecord.blueprints.checks import guild_check
from litecord.errors import BadRequest
from litecord.schemas import (
validate, MEMBER_UPDATE
)
from litecord.blueprints.checks import guild_owner_check
bp = Blueprint('guild_members', __name__)
@ -42,10 +46,61 @@ async def get_members(guild_id):
return jsonify(members)
async def _update_member_roles(guild_id: int, member_id: int,
wanted_roles: list):
"""Update the roles a member has."""
# first, fetch all current roles
roles = await app.db.fetch("""
SELECT role_id from member_roles
WHERE guild_id = $1 AND user_id = $2
""", guild_id, member_id)
roles = [r['role_id'] for r in roles]
roles = set(roles)
wanted_roles = set(wanted_roles)
# first, we need to find all added roles:
# roles that are on wanted_roles but
# not on roles
added_roles = wanted_roles - roles
# and then the removed roles
# which are roles in roles, but not
# in wanted_roles
removed_roles = roles - wanted_roles
conn = await app.db.acquire()
async with conn.transaction():
# add roles
await app.db.executemany("""
INSERT INTO member_roles (user_id, guild_id, role_id)
VALUES ($1, $2, $3)
""", [(member_id, guild_id, role_id)
for role_id in added_roles])
# remove roles
await app.db.executemany("""
DELETE FROM member_roles
WHERE
user_id = $1
AND guild_id = $2
AND role_id = $3
""", [(member_id, guild_id, role_id)
for role_id in removed_roles])
await app.db.release(conn)
@bp.route('/<int:guild_id>/members/<int:member_id>', methods=['PATCH'])
async def modify_guild_member(guild_id, member_id):
"""Modify a members' information in a guild."""
j = await request.get_json()
user_id = await token_check()
await guild_owner_check(user_id, guild_id)
j = validate(await request.get_json(), MEMBER_UPDATE)
if 'nick' in j:
# TODO: check MANAGE_NICKNAMES
@ -75,10 +130,14 @@ async def modify_guild_member(guild_id, member_id):
""", j['deaf'], member_id, guild_id)
if 'channel_id' in j:
# TODO: check MOVE_MEMBERS
# TODO: check MOVE_MEMBERS and CONNECT to the channel
# TODO: change the member's voice channel
pass
if 'roles' in j:
# TODO: check permissions
await _update_member_roles(guild_id, member_id, j['roles'])
member = await app.storage.get_member_data_one(guild_id, member_id)
member.pop('joined_at')

View File

@ -151,7 +151,10 @@ class GuildMemberList:
# this user has a best_role that isn't the
# @everyone role, so we'll put them in the respective group
group_data[best_role_id].append(presence)
try:
group_data[best_role_id].append(presence)
except KeyError:
group_data[simple_group].append(presence)
# go through each group and sort the resulting members by display name

View File

@ -284,7 +284,7 @@ ROLE_UPDATE_POSITION = {
MEMBER_UPDATE = {
'nick': {
'type': 'nickname',
'type': 'username',
'minlength': 1, 'maxlength': 100,
'required': False,
},

View File

@ -164,7 +164,7 @@ class Storage:
""", guild_id, member_id)
async def _member_dict(self, row, guild_id, member_id) -> Dict[str, Any]:
members_roles = await self.db.fetch("""
roles = await self.db.fetch("""
SELECT role_id::text
FROM member_roles
WHERE guild_id = $1 AND user_id = $2
@ -173,7 +173,7 @@ class Storage:
return {
'user': await self.get_user(member_id),
'nick': row['nickname'],
'roles': [row[0] for row in members_roles],
'roles': [r['role_id'] for r in roles],
'joined_at': row['joined_at'].isoformat(),
'deaf': row['deafened'],
'mute': row['muted'],