blueprints: add guilds blueprint

- gateway.websocket: merge get_guild and get_guild_extra
 - gateway.websocket: only apply too many shards close when
     guilds > 2500
 - storage: detach state usage
 - storage: fix large calc on get_guild_extra
This commit is contained in:
Luna Mendes 2018-06-21 03:16:13 -03:00
parent f5ea44c8d7
commit 183013f8f9
7 changed files with 87 additions and 16 deletions

View File

@ -1,3 +1,4 @@
from .gateway import bp as gateway
from .auth import bp as auth
from .users import bp as users
from .guilds import bp as guilds

View File

@ -0,0 +1,60 @@
from quart import Blueprint, request, current_app as app, jsonify
from ..auth import token_check
from ..snowflake import get_snowflake
from ..enums import ChannelType
bp = Blueprint('guilds', __name__)
@bp.route('', methods=['POST'])
async def create_guild():
user_id = await token_check()
j = await request.get_json()
guild_id = get_snowflake()
await app.db.execute(
"""
INSERT INTO guilds (id, name, region, icon, owner_id,
verification_level, default_message_notifications,
explicit_content_filter)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8)
""", guild_id, j['name'], j['region'], j['icon'], user_id,
j.get('verification_level', 0),
j.get('default_message_notifications', 0),
j.get('explicit_content_filter', 0))
await app.db.execute("""
INSERT INTO members (user_id, guild_id)
VALUES ($1, $2)
""", user_id, guild_id)
everyone_role_id = get_snowflake()
await app.db.execute("""
INSERT INTO roles (id, guild_id, name, position, permissions)
VALUES ($1, $2, $3, $4, $5)
""", everyone_role_id, guild_id, '@everyone', 0, 104324161)
general_id = get_snowflake()
await app.db.execute("""
INSERT INTO channels (id, channel_type)
VALUES ($1, $2)
""", general_id, ChannelType.GUILD_TEXT)
await app.db.execute("""
INSERT INTO guild_channels (id, guild_id, name, position)
VALUES ($1, $2, $3, $4)
""", general_id, guild_id, 'general', 0)
await app.db.execute("""
INSERT INTO guild_text_channels (id)
VALUES ($1)
""", general_id)
guild_json = await app.storage.get_guild(guild_id, user_id)
guild_extra = await app.storage.get_guild_extra(guild_id, user_id, 250)
return jsonify({**guild_json, **guild_extra})

View File

@ -96,7 +96,7 @@ async def leave_guild(guild_id):
return '', 204
@bp.route('/@me/connections', methods=['GET'])
# @bp.route('/@me/connections', methods=['GET'])
async def get_connections():
pass

4
litecord/dispatcher.py Normal file
View File

@ -0,0 +1,4 @@
class EventDispatcher:
"""Pub/Sub routines for litecord."""
pass

View File

@ -109,7 +109,11 @@ class GatewayWebsocket:
} for row in guild_ids]
return [
await self.storage.get_guild(row[0], self.state)
{
**await self.storage.get_guild(row[0], user_id),
**await self.storage.get_guild_extra(row[0], user_id,
self.state.large)
}
for row in guild_ids
]
@ -122,7 +126,7 @@ class GatewayWebsocket:
for guild_obj in unavailable_guilds:
guild = await self.storage.get_guild(guild_obj['id'],
self.state)
self.state.user_id)
if not guild:
continue
@ -162,8 +166,9 @@ class GatewayWebsocket:
raise ShardingRequired('Too many guilds for shard '
f'{current_shard}')
if guilds / shard_count > 0.8:
raise ShardingRequired('Too many shards.')
if guilds > 2500 and guilds / shard_count > 0.8:
raise ShardingRequired('Too many shards. '
f'(g={guilds} sc={shard_count})')
if current_shard > shard_count:
raise InvalidShard('Shard count > Total shards')

View File

@ -28,11 +28,10 @@ class Storage:
duser.pop('email')
duser.pop('mfa_enabled')
duser.pop('verified')
duser.pop('mfa_enabled')
return duser
async def get_guild(self, guild_id: int, state=None) -> Dict:
async def get_guild(self, guild_id: int, user_id=None) -> Dict:
"""Get gulid payload."""
row = await self.db.fetchrow("""
SELECT *
@ -45,8 +44,8 @@ class Storage:
drow = dict(row)
if state:
drow['owner'] = drow['owner_id'] == state.user_id
if user_id:
drow['owner'] = drow['owner_id'] == user_id
# TODO: Probably a really bad idea to repeat str() calls
# Any ideas to make this simpler?
@ -76,7 +75,7 @@ class Storage:
async def get_member_data(self, guild_id) -> List[Dict[str, Any]]:
"""Get member information on a guild."""
members_basic = await self.db.fetch("""
SELECT user_id, nickname, joined_at
SELECT user_id, nickname, joined_at, deafened, muted
FROM members
WHERE guild_id = $1
""", guild_id)
@ -145,7 +144,7 @@ class Storage:
# type is a SQL keyword, so we can't do
# 'overwrite_type AS type'
overwrite_rows = await self.db.fetch("""
SELECT user_id::text AS id, overwrite_type, allow, deny
SELECT target_id::text AS id, overwrite_type, allow, deny
FROM channel_overwrites
WHERE channel_id = $1
""", row['id'])
@ -165,7 +164,8 @@ class Storage:
return channels
async def get_guild_extra(self, guild_id: int, state=None) -> Dict:
async def get_guild_extra(self, guild_id: int,
user_id=None, large=None) -> Dict:
"""Get extra information about a guild."""
res = {}
@ -175,14 +175,14 @@ class Storage:
WHERE guild_id = $1
""", guild_id)
if state:
if user_id and large:
joined_at = await self.db.fetchval("""
SELECT joined_at
FROM members
WHERE guild_id = $1 AND user_id = $2
""", guild_id, state.user_id)
""", guild_id, user_id)
res['large'] = state.large > member_count
res['large'] = member_count > large
res['joined_at'] = joined_at.isoformat()
members = await self.get_member_data(guild_id)

3
run.py
View File

@ -8,7 +8,7 @@ from quart import Quart, g, jsonify
from logbook import StreamHandler, Logger
import config
from litecord.blueprints import gateway, auth, users
from litecord.blueprints import gateway, auth, users, guilds
from litecord.gateway import websocket_handler
from litecord.errors import LitecordError
from litecord.gateway.state_manager import StateManager
@ -36,6 +36,7 @@ app = make_app()
app.register_blueprint(gateway, url_prefix='/api/v6')
app.register_blueprint(auth, url_prefix='/api/v6')
app.register_blueprint(users, url_prefix='/api/v6/users')
app.register_blueprint(guilds, url_prefix='/api/v6/guilds')
@app.before_serving