diff --git a/litecord/blueprints/guilds.py b/litecord/blueprints/guilds.py index abab226..691598d 100644 --- a/litecord/blueprints/guilds.py +++ b/litecord/blueprints/guilds.py @@ -4,7 +4,7 @@ from ..auth import token_check from ..snowflake import get_snowflake from ..enums import ChannelType from ..errors import Forbidden, GuildNotFound, BadRequest -from ..schemas import validate, GUILD_CREATE, GUILD_UPDATE +from ..schemas import validate, GUILD_CREATE, GUILD_UPDATE, ROLE_CREATE from ..utils import dict_get from .channels import channel_ack from .checks import guild_check @@ -67,6 +67,14 @@ async def create_role(guild_id, name: str, **kwargs): # TODO: use @everyone's perm number default_perms = dict_get(kwargs, 'default_perms', DEFAULT_EVERYONE_PERMS) + max_pos = await app.db.fetchval(""" + SELECT MAX(position) + FROM roles + WHERE guild_id = $1 + """, guild_id) + + max_pos = max_pos or 0 + await app.db.execute( """ INSERT INTO roles (id, guild_id, name, color, @@ -78,6 +86,7 @@ async def create_role(guild_id, name: str, **kwargs): name, dict_get(kwargs, 'color', 0), dict_get(kwargs, 'hoist', False), + max_pos + 1, dict_get(kwargs, 'permissions', default_perms), False, dict_get(kwargs, 'mentionable', False) @@ -90,6 +99,8 @@ async def create_role(guild_id, name: str, **kwargs): 'role': role, }) + return role + async def guild_create_roles_prep(guild_id: int, roles: list): """Create roles in preparation in guild create.""" @@ -365,6 +376,21 @@ async def modify_channel_pos(guild_id): raise NotImplementedError +@bp.route('//roles', methods=['POST']) +async def create_guild_role(guild_id: int): + """Add a role to a guild""" + user_id = await token_check() + + # TODO: use check_guild and MANAGE_ROLES permission + await guild_owner_check(user_id, guild_id) + + j = validate(await request.get_json(), ROLE_CREATE) + + role = await create_role(guild_id, j.get('name', 'new role'), **j) + + return jsonify(role) + + @bp.route('//members/', methods=['GET']) async def get_guild_member(guild_id, member_id): """Get a member's information in a guild.""" diff --git a/litecord/schemas.py b/litecord/schemas.py index 6526314..8eb4bfc 100644 --- a/litecord/schemas.py +++ b/litecord/schemas.py @@ -6,6 +6,7 @@ from logbook import Logger from .errors import BadRequest from .permissions import Permissions +from .types import Color from .enums import ( ActivityType, StatusType, ExplicitFilter, RelationshipType, MessageNotifications, ChannelType, VerificationLevel @@ -225,6 +226,7 @@ GUILD_CREATE = { 'type': 'list', 'default': [], 'schema': PARTIAL_CHANNEL_GUILD_CREATE}, } + GUILD_UPDATE = { 'name': { 'type': 'guild_name', @@ -249,13 +251,23 @@ GUILD_UPDATE = { } +ROLE_CREATE = { + 'name': {'type': 'string', 'default': 'new role'}, + 'permissions': {'coerce': Permissions, 'nullable': True}, + 'color': {'coerce': Color, 'default': 0}, + 'hoist': {'type': 'boolean', 'default': False}, + 'mentionable': {'type': 'boolean', 'default': False}, +} + + MEMBER_UPDATE = { 'nick': { 'type': 'nickname', 'minlength': 1, 'maxlength': 100, 'required': False, }, - 'roles': {'type': 'list', 'required': False}, + 'roles': {'type': 'list', 'required': False, + 'schema': {'coerce': int}}, 'mute': {'type': 'boolean', 'required': False}, 'deaf': {'type': 'boolean', 'required': False}, 'channel_id': {'type': 'snowflake', 'required': False}, diff --git a/litecord/types.py b/litecord/types.py new file mode 100644 index 0000000..4fddfff --- /dev/null +++ b/litecord/types.py @@ -0,0 +1,15 @@ + +class Color: + """Custom color class""" + def __init__(self, val: int): + self.blue = val & 255 + self.green = (val >> 8) & 255 + self.red = (val >> 16) & 255 + + @property + def value(self): + """Give the actual RGB integer encoding this color.""" + return int('%02x%02x%02x' % (self.red, self.green, self.blue), 16) + + def __int__(self): + return self.value