guild, channels: add dummy implementation for search

- schemas: add SEARCH_CHANNEL
 - migration.scripts: add 5_add_messages_guild_id
 - schema.sql: add messages.guild_id
This commit is contained in:
Luna Mendes 2018-11-20 04:15:03 -03:00
parent 432244263d
commit 93e00315df
5 changed files with 81 additions and 7 deletions

View File

@ -7,7 +7,7 @@ from litecord.auth import token_check
from litecord.enums import ChannelType, GUILD_CHANS
from litecord.errors import ChannelNotFound
from litecord.schemas import (
validate, CHAN_UPDATE, CHAN_OVERWRITE
validate, CHAN_UPDATE, CHAN_OVERWRITE, SEARCH_CHANNEL
)
from litecord.blueprints.checks import channel_check, channel_perm_check
@ -490,3 +490,41 @@ async def delete_read_state(channel_id):
""", user_id, channel_id)
return '', 204
@bp.route('/<int:channel_id>/messages/search', methods=['GET'])
async def _search_channel(channel_id):
"""Search in DMs or group DMs"""
user_id = await token_check()
await channel_check(user_id, channel_id)
await channel_perm_check(user_id, channel_id, 'read_messages')
j = validate(request.args, SEARCH_CHANNEL)
# main message ids
rows = await app.db.fetch(f"""
SELECT message_id,
COUNT(*) OVER() as total_results
FROM messages
WHERE channel_id = $1 AND content LIKE '%'||$3||'%'
ORDER BY
LIMIT 50
OFFSET $2
""", channel_id, j['offset'], j['content'])
results = 0 if not rows else rows[0]['total_results']
main_messages = [r['message_id'] for r in rows]
# fetch contexts for each message
# (2 messages before, 2 messages after).
# TODO: actual contexts
res = []
for message_id in main_messages:
res.append([await app.storage.get_message(message_id)])
return jsonify({
'total_results': results,
'messages': res,
'analytics_id': '',
})

View File

@ -9,7 +9,7 @@ from ..auth import token_check
from ..snowflake import get_snowflake
from ..enums import ChannelType
from ..schemas import (
validate, GUILD_CREATE, GUILD_UPDATE
validate, GUILD_CREATE, GUILD_UPDATE, SEARCH_CHANNEL
)
from .channels import channel_ack
from .checks import guild_check, guild_owner_check
@ -277,7 +277,7 @@ async def delete_guild(guild_id):
return '', 204
@bp.route('/<int:guild_id>/messages/search')
@bp.route('/<int:guild_id>/messages/search', methods=['GET'])
async def search_messages(guild_id):
"""Search messages in a guild.
@ -286,12 +286,37 @@ async def search_messages(guild_id):
user_id = await token_check()
await guild_check(user_id, guild_id)
# TODO: implement route
j = validate(request.args, SEARCH_CHANNEL)
# main message ids
# TODO: filter only channels where user can
# read messages to prevent leaking
rows = await app.db.fetch(f"""
SELECT message_id,
COUNT(*) OVER() as total_results
FROM messages
WHERE guild_id = $1
ORDER BY
LIMIT 50
OFFSET $2
""", guild_id, j['offset'])
results = 0 if not rows else rows[0]['total_results']
main_messages = [r['message_id'] for r in rows]
# fetch contexts for each message
# (2 messages before, 2 messages after).
# TODO: actual contexts
res = []
for message_id in main_messages:
res.append([await app.storage.get_message(message_id)])
return jsonify({
'total_results': 0,
'messages': [],
'analytics_id': 'ass',
'total_results': results,
'messages': res,
'analytics_id': '',
})

View File

@ -591,3 +591,10 @@ PATCH_EMOJI = {
'type': 'string', 'minlength': 1, 'maxlength': 256, 'required': True},
'roles': {'type': 'list', 'schema': {'coerce': int}}
}
SEARCH_CHANNEL = {
'content': {'type': 'string', 'minlength': 1},
'include_nsfw': {'type': 'boolean'},
'offset': {'coerce': int}
}

View File

@ -0,0 +1 @@
ALTER TABLE messages ADD COLUMN guild_id bigint REFERENCES guilds (id) ON DELETE CASCADE;

View File

@ -590,6 +590,9 @@ CREATE TABLE IF NOT EXISTS messages (
id bigint PRIMARY KEY,
channel_id bigint REFERENCES channels (id) ON DELETE CASCADE,
-- this is good for search.
guild_id bigint REFERENCES guilds (id) ON DELETE CASCADE,
-- those are mutually exclusive, only one of them
-- can NOT be NULL at a time.