blueprints.channels: fix channel deletion

- blueprints.guilds: fix channel creation
 - blueprints.relationships: add POST /api/v6/users/@me/relationships
 - storage: add Storage.search_user, for ^
 - storage: fix bug with last_message_id returning "None" (as a str)
This commit is contained in:
Luna Mendes 2018-10-10 17:09:39 -03:00
parent adc6a58179
commit 737129bd20
6 changed files with 129 additions and 32 deletions

View File

@ -99,6 +99,40 @@ async def _update_guild_chan_cat(guild_id: int, channel_id: int):
) )
async def delete_messages(channel_id):
await app.db.execute("""
DELETE FROM channel_pins
WHERE channel_id = $1
""", channel_id)
await app.db.execute("""
DELETE FROM user_read_state
WHERE channel_id = $1
""", channel_id)
await app.db.execute("""
DELETE FROM messages
WHERE channel_id = $1
""", channel_id)
async def guild_cleanup(channel_id):
await app.db.execute("""
DELETE FROM channel_overwrites
WHERE channel_id = $1
""", channel_id)
await app.db.execute("""
DELETE FROM invites
WHERE channel_id = $1
""", channel_id)
await app.db.execute("""
DELETE FROM webhooks
WHERE channel_id = $1
""", channel_id)
@bp.route('/<int:channel_id>', methods=['DELETE']) @bp.route('/<int:channel_id>', methods=['DELETE'])
async def close_channel(channel_id): async def close_channel(channel_id):
user_id = await token_check() user_id = await token_check()
@ -118,15 +152,37 @@ async def close_channel(channel_id):
ChannelType.GUILD_CATEGORY: _update_guild_chan_cat, ChannelType.GUILD_CATEGORY: _update_guild_chan_cat,
}[ctype] }[ctype]
main_tbl = {
ChannelType.GUILD_TEXT: 'guild_text_channels',
ChannelType.GUILD_VOICE: 'guild_voice_channels',
# TODO: categories?
}[ctype]
await _update_func(guild_id, channel_id) await _update_func(guild_id, channel_id)
# this should take care of deleting all messages as well # for some reason ON DELETE CASCADE
# (if any) # didn't work on my setup, so I delete
# everything before moving to the main
# channel table deletes
await delete_messages(channel_id)
await guild_cleanup(channel_id)
await app.db.execute(f"""
DELETE FROM {main_tbl}
WHERE id = $1
""", channel_id)
await app.db.execute(""" await app.db.execute("""
DELETE FROM guild_channels DELETE FROM guild_channels
WHERE id = $1 WHERE id = $1
""", channel_id) """, channel_id)
await app.db.execute("""
DELETE FROM channels
WHERE id = $1
""", channel_id)
await app.dispatcher.dispatch_guild( await app.dispatcher.dispatch_guild(
guild_id, 'CHANNEL_DELETE', chan) guild_id, 'CHANNEL_DELETE', chan)
return jsonify(chan) return jsonify(chan)

View File

@ -209,22 +209,12 @@ async def create_channel(guild_id):
VALUES ($1, $2) VALUES ($1, $2)
""", new_channel_id, channel_type.value) """, new_channel_id, channel_type.value)
max_pos = await app.db.fetch(""" max_pos = await app.db.fetchval("""
SELECT MAX(position) SELECT MAX(position)
FROM guild_channels FROM guild_channels
WHERE guild_id = $1 WHERE guild_id = $1
""", guild_id) """, guild_id)
channel = {
'id': str(new_channel_id),
'type': channel_type,
'guild_id': str(guild_id),
'position': max_pos + 1,
'permission_overwrites': [],
'nsfw': False,
'name': j['name'],
}
if channel_type == ChannelType.GUILD_TEXT: if channel_type == ChannelType.GUILD_TEXT:
await app.db.execute(""" await app.db.execute("""
INSERT INTO guild_channels (id, guild_id, name, position) INSERT INTO guild_channels (id, guild_id, name, position)
@ -236,15 +226,12 @@ async def create_channel(guild_id):
VALUES ($1) VALUES ($1)
""", new_channel_id) """, new_channel_id)
channel['topic'] = None
elif channel_type == ChannelType.GUILD_VOICE: elif channel_type == ChannelType.GUILD_VOICE:
channel['user_limit'] = 0
channel['bitrate'] = 64
raise NotImplementedError() raise NotImplementedError()
await app.dispatcher.dispatch_guild(guild_id, 'CHANNEL_CREATE', channel) chan = await app.storage.get_channel(new_channel_id)
return jsonify(channel) await app.dispatcher.dispatch_guild(guild_id, 'CHANNEL_CREATE', chan)
return jsonify(chan)
@bp.route('/<int:guild_id>/channels', methods=['PATCH']) @bp.route('/<int:guild_id>/channels', methods=['PATCH'])

View File

@ -2,7 +2,7 @@ from quart import Blueprint, jsonify, request, current_app as app
from asyncpg import UniqueViolationError from asyncpg import UniqueViolationError
from ..auth import token_check from ..auth import token_check
from ..schemas import validate, RELATIONSHIP from ..schemas import validate, RELATIONSHIP, SPECIFIC_FRIEND
from ..enums import RelationshipType from ..enums import RelationshipType
@ -15,12 +15,8 @@ async def get_me_relationships():
return jsonify(await app.storage.get_relationships(user_id)) return jsonify(await app.storage.get_relationships(user_id))
@bp.route('/@me/relationships/<int:peer_id>', methods=['PUT']) async def make_friend(user_id: int, peer_id: int,
async def add_relationship(peer_id: int): rel_type=RelationshipType.FRIEND.value):
"""Add a relationship to the peer."""
user_id = await token_check()
payload = validate(await request.get_json(), RELATIONSHIP)
rel_type = payload['type']
_friend = RelationshipType.FRIEND.value _friend = RelationshipType.FRIEND.value
await app.db.execute(""" await app.db.execute("""
@ -76,7 +72,44 @@ async def add_relationship(peer_id: int):
return '', 204 return '', 204
# its a block. return
@bp.route('/@me/relationships', methods=['POST'])
async def post_relationship():
user_id = await token_check()
j = validate(await request.get_json(), SPECIFIC_FRIEND)
uid = await app.storage.search_user(j['username'],
str(j['discriminator']))
if not uid:
return '', 404
res = await make_friend(user_id, uid)
# NOTE: don't know what status code should I send
if res is None:
return '', 500
return '', 204
@bp.route('/@me/relationships/<int:peer_id>', methods=['PUT'])
async def add_relationship(peer_id: int):
"""Add a relationship to the peer."""
user_id = await token_check()
payload = validate(await request.get_json(), RELATIONSHIP)
rel_type = payload['type']
res = await make_friend(user_id, peer_id, rel_type)
if res is not None:
return res
# make_friend did not succeed, so we
# assume it is a block and dispatch
# the respective RELATIONSHIP_ADD.
await app.dispatcher.dispatch_user(user_id, 'RELATIONSHIP_ADD', { await app.dispatcher.dispatch_user(user_id, 'RELATIONSHIP_ADD', {
'id': str(peer_id), 'id': str(peer_id),
'type': RelationshipType.BLOCK.value, 'type': RelationshipType.BLOCK.value,

View File

@ -292,3 +292,8 @@ CREATE_GROUP_DM = {
'required': True, 'required': True,
'schema': {'type': 'snowflake'} 'schema': {'type': 'snowflake'}
} }
SPECIFIC_FRIEND = {
'username': {'type': 'username'},
'discriminator': {'type': 'number'}
}

View File

@ -91,6 +91,17 @@ class Storage:
return duser return duser
async def search_user(self, username: str, discriminator: str) -> int:
"""Search a user"""
if len(discriminator) < 4:
# how do we do this in f-strings again..?
discriminator = '%04d' % discriminator
return await self.db.fetchval("""
SELECT id FROM users
WHERE username = $1 AND discriminator = $2
""", username, discriminator)
async def get_guild(self, guild_id: int, user_id=None) -> Dict: async def get_guild(self, guild_id: int, user_id=None) -> Dict:
"""Get gulid payload.""" """Get gulid payload."""
row = await self.db.fetchrow(""" row = await self.db.fetchrow("""
@ -232,6 +243,10 @@ class Storage:
WHERE channel_id = $1 WHERE channel_id = $1
""", channel_id) """, channel_id)
async def chan_last_message_str(self, channel_id: int) -> int:
last_msg = await self.chan_last_message(channel_id)
return str(last_msg) if last_msg is not None else None
async def _channels_extra(self, row) -> Dict: async def _channels_extra(self, row) -> Dict:
"""Fill in more information about a channel.""" """Fill in more information about a channel."""
channel_type = row['type'] channel_type = row['type']
@ -244,10 +259,11 @@ class Storage:
WHERE id = $1 WHERE id = $1
""", row['id']) """, row['id'])
last_msg = await self.chan_last_message_str(row['id'])
return {**row, **{ return {**row, **{
'topic': topic, 'topic': topic,
'last_message_id': str( 'last_message_id': last_msg,
await self.chan_last_message(row['id']))
}} }}
elif chan_type == ChannelType.GUILD_VOICE: elif chan_type == ChannelType.GUILD_VOICE:
vrow = await self.db.fetchval(""" vrow = await self.db.fetchval("""
@ -328,8 +344,8 @@ class Storage:
drow = dict(dm_row) drow = dict(dm_row)
drow['type'] = chan_type drow['type'] = chan_type
drow['last_message_id'] = str( drow['last_message_id'] = await self.chan_last_message_str(
await self.chan_last_message(channel_id)) channel_id)
# dms have just two recipients. # dms have just two recipients.
drow['recipients'] = [ drow['recipients'] = [

View File

@ -298,7 +298,7 @@ CREATE TABLE IF NOT EXISTS group_dm_members (
CREATE TABLE IF NOT EXISTS channel_overwrites ( CREATE TABLE IF NOT EXISTS channel_overwrites (
channel_id bigint REFERENCES channels (id), channel_id bigint REFERENCES channels (id) ON DELETE CASCADE,
-- target_type = 0 -> use target_user -- target_type = 0 -> use target_user
-- target_type = 1 -> user target_role -- target_type = 1 -> user target_role