From 79f91cd774972fba5baf74497246dd7e2ed405c4 Mon Sep 17 00:00:00 2001 From: Luna Mendes Date: Fri, 19 Oct 2018 17:36:54 -0300 Subject: [PATCH] blueprints.users: fix user guild settings - blueprints.users: make sure a row exists on guild_settings when patching - schemas: fix all 'bool' types to 'boolean' - schemas: fix GUILD_SETTINGS_CHAN_OVERRIDE - storage: add Storage.get_guild_settings_one - storage: fix Storage.get_guild_settings --- litecord/blueprints/users.py | 19 ++++++--- litecord/gateway/websocket.py | 2 +- litecord/schemas.py | 27 ++++++------ litecord/storage.py | 77 ++++++++++++++++++++++++++++------- 4 files changed, 93 insertions(+), 32 deletions(-) diff --git a/litecord/blueprints/users.py b/litecord/blueprints/users.py index 0b37e54..8ab4706 100644 --- a/litecord/blueprints/users.py +++ b/litecord/blueprints/users.py @@ -422,6 +422,10 @@ async def patch_guild_settings(guild_id: int): j = validate(await request.get_json(), GUILD_SETTINGS) + # querying the guild settings information before modifying + # will make sure they exist in the table. + await app.storage.get_guild_settings_one(user_id, guild_id) + for field in (k for k in j.keys() if k != 'channel_overrides'): await app.db.execute(f""" UPDATE guild_settings @@ -440,7 +444,7 @@ async def patch_guild_settings(guild_id: int): continue for field in chan_overrides: - await app.db.execute(f""" + res = await app.db.execute(f""" UPDATE guild_settings_channel_overrides SET {field} = $1 WHERE user_id = $2 @@ -448,11 +452,16 @@ async def patch_guild_settings(guild_id: int): AND channel_id = $4 """, chan_overrides[field], user_id, guild_id, chan_id) + if res == 'UPDATE 0': + await app.db.execute(f""" + INSERT INTO guild_settings_channel_overrides + (user_id, guild_id, channel_id, {field}) + VALUES ($1, $2, $3, $4) + """, user_id, guild_id, chan_id, chan_overrides[field]) + settings = await app.storage.get_guild_settings_one(user_id, guild_id) - await app.dispatcher.dispatch_user(user_id, 'USER_GUILD_SETTINGS_UPDATE', { - **settings, - **{'guild_id': guild_id} - }) + await app.dispatcher.dispatch_user( + user_id, 'USER_GUILD_SETTINGS_UPDATE', settings) return jsonify(settings) diff --git a/litecord/gateway/websocket.py b/litecord/gateway/websocket.py index 5281dda..9c6bd4d 100644 --- a/litecord/gateway/websocket.py +++ b/litecord/gateway/websocket.py @@ -86,7 +86,7 @@ class GatewayWebsocket: encoded = self.encoder(payload) if len(encoded) < 1024: - log.debug('sending {}', pprint.pformat(payload)) + log.debug('sending\n{}', pprint.pformat(payload)) else: log.debug('sending {}', pprint.pformat(payload)) log.debug('sending op={} s={} t={} (too big)', diff --git a/litecord/schemas.py b/litecord/schemas.py index 2c6687e..1c3eda3 100644 --- a/litecord/schemas.py +++ b/litecord/schemas.py @@ -180,8 +180,8 @@ MEMBER_UPDATE = { 'required': False, }, 'roles': {'type': 'list', 'required': False}, - 'mute': {'type': 'bool', 'required': False}, - 'deaf': {'type': 'bool', 'required': False}, + 'mute': {'type': 'boolean', 'required': False}, + 'deaf': {'type': 'boolean', 'required': False}, 'channel_id': {'type': 'snowflake', 'required': False}, } @@ -366,27 +366,30 @@ SPECIFIC_FRIEND = { } GUILD_SETTINGS_CHAN_OVERRIDE = { - 'muted': { - 'type': 'bool', 'required': False}, - 'message_notifications': { - 'type': 'msg_notifications', - 'required': False, + 'type': 'dict', + 'schema': { + 'muted': { + 'type': 'boolean', 'required': False}, + 'message_notifications': { + 'type': 'msg_notifications', + 'required': False, + } } } GUILD_SETTINGS = { 'channel_overrides': { 'type': 'dict', - 'schema': GUILD_SETTINGS_CHAN_OVERRIDE, + 'valueschema': GUILD_SETTINGS_CHAN_OVERRIDE, 'keyschema': {'type': 'snowflake'}, 'required': False, }, - 'supress_everyone': { - 'type': 'bool', 'required': False}, + 'suppress_everyone': { + 'type': 'boolean', 'required': False}, 'muted': { - 'type': 'bool', 'required': False}, + 'type': 'boolean', 'required': False}, 'mobile_push': { - 'type': 'bool', 'required': False}, + 'type': 'boolean', 'required': False}, 'message_notifications': { 'type': 'msg_notifications', 'required': False, diff --git a/litecord/storage.py b/litecord/storage.py index 7804d4c..a7e37eb 100644 --- a/litecord/storage.py +++ b/litecord/storage.py @@ -909,6 +909,49 @@ class Storage: return parties[0] + async def get_guild_settings_one(self, user_id: int, + guild_id: int) -> dict: + """Get guild settings information for a single guild.""" + row = await self.db.fetchrow(""" + SELECT guild_id::text, suppress_everyone, muted, + message_notifications, mobile_push + FROM guild_settings + WHERE user_id = $1 AND guild_id = $2 + """, user_id, guild_id) + + if not row: + await self.db.execute(""" + INSERT INTO guild_settings (user_id, guild_id) + VALUES ($1, $2) + """, user_id, guild_id) + + return await self.get_guild_settings_one(user_id, guild_id) + + gid = int(row['guild_id']) + drow = dict(row) + + chan_overrides = {} + + overrides = await self.db.fetch(""" + SELECT channel_id::text, muted, message_notifications + FROM guild_settings_channel_overrides + WHERE + user_id = $1 + AND guild_id = $2 + """, user_id, gid) + + for chan_row in overrides: + dcrow = dict(chan_row) + + chan_id = dcrow['channel_id'] + dcrow.pop('channel_id') + + chan_overrides[chan_id] = dcrow + + return {**drow, **{ + 'channel_overrides': chan_overrides + }} + async def get_guild_settings(self, user_id: int): """Get the specific User Guild Settings, for all guilds a user is on.""" @@ -916,31 +959,37 @@ class Storage: res = [] settings = await self.db.fetch(""" - SELECT guild_id, suppress_everyone, muted + SELECT guild_id::text, suppress_everyone, muted, message_notifications, mobile_push FROM guild_settings WHERE user_id = $1 """, user_id) for row in settings: - gid = row['guild_id'] + print(dict(row)) + gid = int(row['guild_id']) drow = dict(row) - chan_ids = await self.get_channel_ids(gid) - chan_overrides = {} - for chan_id in chan_ids: - chan_row = await self.db.fetchrow(""" - SELECT muted, message_notifications - FROM guild_setting_channel_overrides - WHERE - guild_id = $1 - AND user_id = $2 - AND channel_id = $3 - """, gid, user_id, chan_id) + overrides = await self.db.fetch(""" + SELECT channel_id::text, muted, message_notifications + FROM guild_settings_channel_overrides + WHERE + user_id = $1 + AND guild_id = $2 + """, user_id, gid) - chan_overrides[str(chan_id)] = dict(chan_row) + for chan_row in overrides: + dcrow = dict(chan_row) + + # channel_id isn't on the value of the dict + # so we query it (for the key) then pop + # from the value + chan_id = dcrow['channel_id'] + dcrow.pop('channel_id') + + chan_overrides[chan_id] = dcrow res.append({**drow, **{ 'channel_overrides': chan_overrides