mirror of https://gitlab.com/litecord/litecord.git
litecord: add embed namespace
- embed: add embed.schemas - channel.messages: split some functions for readability
This commit is contained in:
parent
d87ff940f6
commit
8b97195404
|
|
@ -139,34 +139,10 @@ async def _dm_pre_dispatch(channel_id, peer_id):
|
||||||
await try_dm_state(peer_id, channel_id)
|
await try_dm_state(peer_id, channel_id)
|
||||||
|
|
||||||
|
|
||||||
@bp.route('/<int:channel_id>/messages', methods=['POST'])
|
async def create_message(channel_id: int, actual_guild_id: int,
|
||||||
async def create_message(channel_id):
|
author_id: int, data: dict) -> int:
|
||||||
user_id = await token_check()
|
|
||||||
ctype, guild_id = await channel_check(user_id, channel_id)
|
|
||||||
|
|
||||||
actual_guild_id = None
|
|
||||||
|
|
||||||
if ctype in GUILD_CHANS:
|
|
||||||
await channel_perm_check(user_id, channel_id, 'send_messages')
|
|
||||||
actual_guild_id = guild_id
|
|
||||||
|
|
||||||
j = validate(await request.get_json(), MESSAGE_CREATE)
|
|
||||||
message_id = get_snowflake()
|
message_id = get_snowflake()
|
||||||
|
|
||||||
# TODO: check connection to the gateway
|
|
||||||
|
|
||||||
can_everyone = await channel_perm_check(
|
|
||||||
user_id, channel_id, 'mention_everyone', False
|
|
||||||
)
|
|
||||||
|
|
||||||
mentions_everyone = ('@everyone' in j['content']) and can_everyone
|
|
||||||
mentions_here = ('@here' in j['content']) and can_everyone
|
|
||||||
|
|
||||||
is_tts = (j.get('tts', False) and
|
|
||||||
await channel_perm_check(
|
|
||||||
user_id, channel_id, 'send_tts_messages', False
|
|
||||||
))
|
|
||||||
|
|
||||||
await app.db.execute(
|
await app.db.execute(
|
||||||
"""
|
"""
|
||||||
INSERT INTO messages (id, channel_id, guild_id, author_id,
|
INSERT INTO messages (id, channel_id, guild_id, author_id,
|
||||||
|
|
@ -176,33 +152,22 @@ async def create_message(channel_id):
|
||||||
message_id,
|
message_id,
|
||||||
channel_id,
|
channel_id,
|
||||||
actual_guild_id,
|
actual_guild_id,
|
||||||
user_id,
|
author_id,
|
||||||
j['content'],
|
data['content'],
|
||||||
|
|
||||||
is_tts,
|
data['tts'],
|
||||||
mentions_everyone or mentions_here,
|
data['everyone_mention'],
|
||||||
|
|
||||||
int(j.get('nonce', 0)),
|
data['nonce'],
|
||||||
MessageType.DEFAULT.value
|
MessageType.DEFAULT.value
|
||||||
)
|
)
|
||||||
|
|
||||||
payload = await app.storage.get_message(message_id, user_id)
|
return message_id
|
||||||
|
|
||||||
if ctype == ChannelType.DM:
|
async def _guild_text_mentions(payload: dict, guild_id: int,
|
||||||
# guild id here is the peer's ID.
|
mentions_everyone: bool, mentions_here: bool):
|
||||||
await _dm_pre_dispatch(channel_id, user_id)
|
channel_id = int(payload['channel_id'])
|
||||||
await _dm_pre_dispatch(channel_id, guild_id)
|
|
||||||
|
|
||||||
await app.dispatcher.dispatch('channel', channel_id,
|
|
||||||
'MESSAGE_CREATE', payload)
|
|
||||||
|
|
||||||
await app.db.execute("""
|
|
||||||
UPDATE user_read_state
|
|
||||||
SET last_message_id = $1
|
|
||||||
WHERE channel_id = $2 AND user_id = $3
|
|
||||||
""", message_id, channel_id, user_id)
|
|
||||||
|
|
||||||
if ctype == ChannelType.GUILD_TEXT:
|
|
||||||
# calculate the user ids we'll bump the mention count for
|
# calculate the user ids we'll bump the mention count for
|
||||||
uids = set()
|
uids = set()
|
||||||
|
|
||||||
|
|
@ -252,6 +217,64 @@ async def create_message(channel_id):
|
||||||
AND channel_id = $2
|
AND channel_id = $2
|
||||||
""", user_id, channel_id)
|
""", user_id, channel_id)
|
||||||
|
|
||||||
|
|
||||||
|
@bp.route('/<int:channel_id>/messages', methods=['POST'])
|
||||||
|
async def _create_message(channel_id):
|
||||||
|
"""Create a message."""
|
||||||
|
user_id = await token_check()
|
||||||
|
ctype, guild_id = await channel_check(user_id, channel_id)
|
||||||
|
|
||||||
|
actual_guild_id = None
|
||||||
|
|
||||||
|
if ctype in GUILD_CHANS:
|
||||||
|
await channel_perm_check(user_id, channel_id, 'send_messages')
|
||||||
|
actual_guild_id = guild_id
|
||||||
|
|
||||||
|
j = validate(await request.get_json(), MESSAGE_CREATE)
|
||||||
|
message_id = get_snowflake()
|
||||||
|
|
||||||
|
# TODO: check connection to the gateway
|
||||||
|
|
||||||
|
can_everyone = await channel_perm_check(
|
||||||
|
user_id, channel_id, 'mention_everyone', False
|
||||||
|
)
|
||||||
|
|
||||||
|
mentions_everyone = ('@everyone' in j['content']) and can_everyone
|
||||||
|
mentions_here = ('@here' in j['content']) and can_everyone
|
||||||
|
|
||||||
|
is_tts = (j.get('tts', False) and
|
||||||
|
await channel_perm_check(
|
||||||
|
user_id, channel_id, 'send_tts_messages', False
|
||||||
|
))
|
||||||
|
|
||||||
|
await create_message(channel_id, actual_guild_id, user_id, {
|
||||||
|
'content': j['content'],
|
||||||
|
'tts': is_tts,
|
||||||
|
'nonce': int(j.get('nonce', 0)),
|
||||||
|
'everyone_mention': mentions_everyone or mentions_here,
|
||||||
|
})
|
||||||
|
|
||||||
|
payload = await app.storage.get_message(message_id, user_id)
|
||||||
|
|
||||||
|
if ctype == ChannelType.DM:
|
||||||
|
# guild id here is the peer's ID.
|
||||||
|
await _dm_pre_dispatch(channel_id, user_id)
|
||||||
|
await _dm_pre_dispatch(channel_id, guild_id)
|
||||||
|
|
||||||
|
await app.dispatcher.dispatch('channel', channel_id,
|
||||||
|
'MESSAGE_CREATE', payload)
|
||||||
|
|
||||||
|
# update read state for the author
|
||||||
|
await app.db.execute("""
|
||||||
|
UPDATE user_read_state
|
||||||
|
SET last_message_id = $1
|
||||||
|
WHERE channel_id = $2 AND user_id = $3
|
||||||
|
""", message_id, channel_id, user_id)
|
||||||
|
|
||||||
|
if ctype == ChannelType.GUILD_TEXT:
|
||||||
|
await _guild_text_mentions(payload, guild_id,
|
||||||
|
mentions_everyone, mentions_here)
|
||||||
|
|
||||||
return jsonify(payload)
|
return jsonify(payload)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,108 @@
|
||||||
|
"""
|
||||||
|
litecord.embed.schemas - embed input validators.
|
||||||
|
"""
|
||||||
|
import urllib.parse
|
||||||
|
|
||||||
|
from litecord.types import Color
|
||||||
|
|
||||||
|
|
||||||
|
class EmbedURL:
|
||||||
|
def __init__(self, url: str):
|
||||||
|
parsed = urllib.parse.urlparse(url)
|
||||||
|
|
||||||
|
if parsed.scheme not in ('http', 'https', 'attachment'):
|
||||||
|
raise ValueError('Invalid URL scheme')
|
||||||
|
|
||||||
|
self.raw_url = url
|
||||||
|
self.parsed = parsed
|
||||||
|
|
||||||
|
@property
|
||||||
|
def url(self):
|
||||||
|
"""Return the URL."""
|
||||||
|
return urllib.parse.urlunparse(self.parsed)
|
||||||
|
|
||||||
|
|
||||||
|
EMBED_FOOTER = {
|
||||||
|
'text': {
|
||||||
|
'type': 'string', 'minlength': 1, 'maxlength': 128, 'required': True},
|
||||||
|
|
||||||
|
'icon_url': {
|
||||||
|
'coerce': EmbedURL, 'required': False,
|
||||||
|
},
|
||||||
|
|
||||||
|
# NOTE: proxy_icon_url set by us
|
||||||
|
}
|
||||||
|
|
||||||
|
EMBED_IMAGE = {
|
||||||
|
'url': {'coerce': EmbedURL, 'required': True},
|
||||||
|
|
||||||
|
# NOTE: proxy_url, width, height set by us
|
||||||
|
}
|
||||||
|
|
||||||
|
EMBED_THUMBNAIL = EMBED_IMAGE
|
||||||
|
|
||||||
|
EMBED_AUTHOR = {
|
||||||
|
'name': {
|
||||||
|
'type': 'string', 'minlength': 1, 'maxlength': 128, 'required': False
|
||||||
|
},
|
||||||
|
'url': {
|
||||||
|
'type': EmbedURL, 'required': False,
|
||||||
|
},
|
||||||
|
'icon_url': {
|
||||||
|
'coerce': EmbedURL, 'required': False,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
EMBED_OBJECT = {
|
||||||
|
'title': {
|
||||||
|
'type': 'string', 'minlength': 1, 'maxlength': 128, 'required': False},
|
||||||
|
'type': {
|
||||||
|
'type': 'string', 'allowed': ['rich'], 'required': False,
|
||||||
|
'default': 'rich'
|
||||||
|
},
|
||||||
|
'description': {
|
||||||
|
'type': 'string', 'minlength': 1, 'maxlength': 1024, 'required': False,
|
||||||
|
},
|
||||||
|
'url': {
|
||||||
|
'coerce': EmbedURL, 'required': False,
|
||||||
|
},
|
||||||
|
'timestamp': {
|
||||||
|
# TODO: an ISO 8601 type
|
||||||
|
# TODO: maybe replace the default in here with now().isoformat?
|
||||||
|
'type': 'string', 'required': False
|
||||||
|
},
|
||||||
|
|
||||||
|
'color': {
|
||||||
|
'coerce': Color, 'required': False
|
||||||
|
},
|
||||||
|
|
||||||
|
'footer': {
|
||||||
|
'type': 'dict',
|
||||||
|
'schema': EMBED_FOOTER,
|
||||||
|
'required': False,
|
||||||
|
},
|
||||||
|
'image': {
|
||||||
|
'type': 'dict',
|
||||||
|
'schema': EMBED_IMAGE,
|
||||||
|
'required': False,
|
||||||
|
},
|
||||||
|
'thumbnail': {
|
||||||
|
'type': 'dict',
|
||||||
|
'schema': EMBED_THUMBNAIL,
|
||||||
|
'required': False,
|
||||||
|
},
|
||||||
|
|
||||||
|
# NOTE: 'video' set by us
|
||||||
|
# NOTE: 'provider' set by us
|
||||||
|
|
||||||
|
'author': {
|
||||||
|
'type': 'dict',
|
||||||
|
'schema': EMBED_AUTHOR,
|
||||||
|
'required': False,
|
||||||
|
},
|
||||||
|
'fields': {
|
||||||
|
'type': 'list',
|
||||||
|
'schema': EMBED_AUTHOR,
|
||||||
|
'required': False,
|
||||||
|
},
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue