diff --git a/litecord/blueprints/channel/__init__.py b/litecord/blueprints/channel/__init__.py index de5839a..4337684 100644 --- a/litecord/blueprints/channel/__init__.py +++ b/litecord/blueprints/channel/__init__.py @@ -1,2 +1,3 @@ from .messages import bp as channel_messages from .reactions import bp as channel_reactions +from .pins import bp as channel_pins diff --git a/litecord/blueprints/channel/pins.py b/litecord/blueprints/channel/pins.py new file mode 100644 index 0000000..7d5b42b --- /dev/null +++ b/litecord/blueprints/channel/pins.py @@ -0,0 +1,93 @@ +from quart import Blueprint, current_app as app, request, jsonify + +from litecord.auth import token_check +from litecord.blueprints.checks import channel_check +from litecord.snowflake import snowflake_datetime + +bp = Blueprint('channel_pins', __name__) + + +@bp.route('//pins', methods=['GET']) +async def get_pins(channel_id): + """Get the pins for a channel""" + user_id = await token_check() + await channel_check(user_id, channel_id) + + ids = await app.db.fetch(""" + SELECT message_id + FROM channel_pins + WHERE channel_id = $1 + ORDER BY message_id ASC + """, channel_id) + + ids = [r['message_id'] for r in ids] + res = [] + + for message_id in ids: + message = await app.storage.get_message(message_id) + if message is not None: + res.append(message) + + return jsonify(res) + + +@bp.route('//pins/', methods=['PUT']) +async def add_pin(channel_id, message_id): + """Add a pin to a channel""" + user_id = await token_check() + _ctype, guild_id = await channel_check(user_id, channel_id) + + # TODO: check MANAGE_MESSAGES permission + + await app.db.execute(""" + INSERT INTO channel_pins (channel_id, message_id) + VALUES ($1, $2) + """, channel_id, message_id) + + row = await app.db.fetchrow(""" + SELECT message_id + FROM channel_pins + WHERE channel_id = $1 + ORDER BY message_id ASC + LIMIT 1 + """, channel_id) + + timestamp = snowflake_datetime(row['message_id']) + + await app.dispatcher.dispatch_guild(guild_id, 'CHANNEL_PINS_UPDATE', { + 'channel_id': str(channel_id), + 'last_pin_timestamp': timestamp.isoformat() + }) + + return '', 204 + + +@bp.route('//pins/', methods=['DELETE']) +async def delete_pin(channel_id, message_id): + user_id = await token_check() + _ctype, guild_id = await channel_check(user_id, channel_id) + + # TODO: check MANAGE_MESSAGES permission + + await app.db.execute(""" + DELETE FROM channel_pins + WHERE channel_id = $1 AND message_id = $2 + """, channel_id, message_id) + + row = await app.db.fetchrow(""" + SELECT message_id + FROM channel_pins + WHERE channel_id = $1 + ORDER BY message_id ASC + LIMIT 1 + """, channel_id) + + timestamp = snowflake_datetime(row['message_id']) + + await app.dispatcher.dispatch( + 'channel', channel_id, 'CHANNEL_PINS_UPDATE', { + 'channel_id': str(channel_id), + 'last_pin_timestamp': timestamp.isoformat() + }) + + return '', 204 diff --git a/litecord/blueprints/channels.py b/litecord/blueprints/channels.py index dea2411..85282ec 100644 --- a/litecord/blueprints/channels.py +++ b/litecord/blueprints/channels.py @@ -4,7 +4,6 @@ from quart import Blueprint, request, current_app as app, jsonify from logbook import Logger from ..auth import token_check -from ..snowflake import snowflake_datetime from ..enums import ChannelType, GUILD_CHANS from ..errors import ChannelNotFound @@ -214,90 +213,6 @@ async def close_channel(channel_id): raise ChannelNotFound() -@bp.route('//pins', methods=['GET']) -async def get_pins(channel_id): - user_id = await token_check() - await channel_check(user_id, channel_id) - - ids = await app.db.fetch(""" - SELECT message_id - FROM channel_pins - WHERE channel_id = $1 - ORDER BY message_id ASC - """, channel_id) - - ids = [r['message_id'] for r in ids] - res = [] - - for message_id in ids: - message = await app.storage.get_message(message_id) - if message is not None: - res.append(message) - - return jsonify(res) - - -@bp.route('//pins/', methods=['PUT']) -async def add_pin(channel_id, message_id): - user_id = await token_check() - _ctype, guild_id = await channel_check(user_id, channel_id) - - # TODO: check MANAGE_MESSAGES permission - - await app.db.execute(""" - INSERT INTO channel_pins (channel_id, message_id) - VALUES ($1, $2) - """, channel_id, message_id) - - row = await app.db.fetchrow(""" - SELECT message_id - FROM channel_pins - WHERE channel_id = $1 - ORDER BY message_id ASC - LIMIT 1 - """, channel_id) - - timestamp = snowflake_datetime(row['message_id']) - - await app.dispatcher.dispatch_guild(guild_id, 'CHANNEL_PINS_UPDATE', { - 'channel_id': str(channel_id), - 'last_pin_timestamp': timestamp.isoformat() - }) - - return '', 204 - - -@bp.route('//pins/', methods=['DELETE']) -async def delete_pin(channel_id, message_id): - user_id = await token_check() - _ctype, guild_id = await channel_check(user_id, channel_id) - - # TODO: check MANAGE_MESSAGES permission - - await app.db.execute(""" - DELETE FROM channel_pins - WHERE channel_id = $1 AND message_id = $2 - """, channel_id, message_id) - - row = await app.db.fetchrow(""" - SELECT message_id - FROM channel_pins - WHERE channel_id = $1 - ORDER BY message_id ASC - LIMIT 1 - """, channel_id) - - timestamp = snowflake_datetime(row['message_id']) - - await app.dispatcher.dispatch( - 'channel', channel_id, 'CHANNEL_PINS_UPDATE', { - 'channel_id': str(channel_id), - 'last_pin_timestamp': timestamp.isoformat() - }) - - return '', 204 - - @bp.route('//typing', methods=['POST']) async def trigger_typing(channel_id): user_id = await token_check() diff --git a/litecord/schemas.py b/litecord/schemas.py index 182420c..901961f 100644 --- a/litecord/schemas.py +++ b/litecord/schemas.py @@ -251,6 +251,57 @@ GUILD_UPDATE = { } +CHAN_OVERWRITE = { + 'type': 'dict', + 'schema': { + 'id': {'coerce': int}, + 'type': {'type': 'string', 'allowed': ['role', 'member']}, + 'allow': {'coerce': Permissions}, + 'deny': {'coerce': Permissions} + } +} + + +CHAN_UPDATE = { + 'name': { + 'type': 'string', 'minlength': 2, + 'maxlength': 100, 'required': False}, + + 'position': {'coerce': int, 'required': False}, + + 'topic': { + 'type': 'string', 'minlength': 0, + 'maxlength': 1024, 'required': False}, + + 'nsfw': {'type': 'boolean', 'required': False}, + 'rate_limit_per_user': { + 'coerce': int, 'min': 0, + 'max': 120, 'required': False}, + + 'bitrate': { + 'coerce': int, 'min': 8000, + + # NOTE: 'max' is 96000 for non-vip guilds + 'max': 128000, 'required': False}, + + 'user_limit': { + # user_limit being 0 means infinite. + 'coerce': int, 'min': 0, + 'max': 99, 'required': False + }, + + 'permission_overwrites': { + 'type': 'list', + 'schema': CHAN_OVERWRITE, + 'required': False + }, + + 'parent_id': {'coerce': int, 'required': False, 'nullable': True} + + +} + + ROLE_CREATE = { 'name': {'type': 'string', 'default': 'new role'}, 'permissions': {'coerce': Permissions, 'nullable': True}, diff --git a/run.py b/run.py index bbdf701..48a630c 100644 --- a/run.py +++ b/run.py @@ -25,7 +25,7 @@ from litecord.blueprints.guild import ( ) from litecord.blueprints.channel import ( - channel_messages, channel_reactions + channel_messages, channel_reactions, channel_pins ) from litecord.ratelimits.handler import ratelimit_handler @@ -79,6 +79,7 @@ bps = { channels: '/channels', channel_messages: '/channels', channel_reactions: '/channels', + channel_pins: '/channels', webhooks: None, science: None,