diff --git a/litecord/blueprints/guild/mod.py b/litecord/blueprints/guild/mod.py index 0461da3..e88b555 100644 --- a/litecord/blueprints/guild/mod.py +++ b/litecord/blueprints/guild/mod.py @@ -17,13 +17,17 @@ async def remove_member(guild_id: int, member_id: int): WHERE guild_id = $1 AND user_id = $2 """, guild_id, member_id) - await app.dispatcher.dispatch_user(member_id, 'GUILD_DELETE', { - 'guild_id': guild_id, - 'unavailable': False, - }) + await app.dispatcher.dispatch_user_guild( + member_id, guild_id, 'GUILD_DELETE', { + 'guild_id': str(guild_id), + 'unavailable': False, + }) await app.dispatcher.unsub('guild', guild_id, member_id) + await app.dispatcher.dispatch( + 'lazy_guild', guild_id, 'remove_member', member_id) + await app.dispatcher.dispatch_guild(guild_id, 'GUILD_MEMBER_REMOVE', { 'guild_id': str(guild_id), 'user': await app.storage.get_user(member_id), diff --git a/litecord/blueprints/users.py b/litecord/blueprints/users.py index bf45206..f6e0e21 100644 --- a/litecord/blueprints/users.py +++ b/litecord/blueprints/users.py @@ -10,6 +10,7 @@ from ..schemas import validate, USER_UPDATE from .guilds import guild_check from .auth import check_password from litecord.auth import hash_data, check_username_usage +from litecord.blueprints.guild.mod import remove_member bp = Blueprint('user', __name__) @@ -245,27 +246,7 @@ async def leave_guild(guild_id: int): user_id = await token_check() await guild_check(user_id, guild_id) - await app.db.execute(""" - DELETE FROM members - WHERE user_id = $1 AND guild_id = $2 - """, user_id, guild_id) - - # first dispatch guild delete to the user, - # then remove from the guild, - # then tell the others that the member was removed - await app.dispatcher.dispatch_user_guild( - user_id, guild_id, 'GUILD_DELETE', { - 'id': str(guild_id), - 'unavailable': False, - } - ) - - await app.dispatcher.unsub('guild', guild_id, user_id) - - await app.dispatcher.dispatch_guild('GUILD_MEMBER_REMOVE', { - 'guild_id': str(guild_id), - 'user': await app.storage.get_user(user_id) - }) + await remove_member(guild_id, user_id) return '', 204 diff --git a/litecord/pubsub/lazy_guild.py b/litecord/pubsub/lazy_guild.py index 74c46da..2780877 100644 --- a/litecord/pubsub/lazy_guild.py +++ b/litecord/pubsub/lazy_guild.py @@ -860,6 +860,43 @@ class GuildMemberList: return await self.resync_by_item(user_index) + async def remove_member(self, user_id: int): + """Remove a member from the list.""" + if not self.list: + log.warning('lazy: unitialized, ignoring del uid {}', + user_id) + return + + # we need the old index to resync later on + old_idx = self.get_item_index(user_id) + + try: + pres = self.list.presences.pop(user_id) + except KeyError: + log.warning('lazy: unknown pres uid {}', user_id) + return + + try: + member = self.list.members.pop(user_id) + except KeyError: + log.warning('lazy: unknown member uid {}', user_id) + return + + group_id = await self.get_group_for_member( + user_id, member['roles'], pres['status']) + + if not group_id: + log.warning('lazy: unknown group uid {}', user_id) + return + + self.list.data[group_id].remove(user_id) + + if old_idx is None: + log.warning('lazy: unknown old idx uid {}', user_id) + return + + await self.resync_by_item(old_idx) + async def pres_update(self, user_id: int, partial_presence: Presence): """Update a presence inside the member list. @@ -1273,3 +1310,7 @@ class LazyGuildDispatcher(Dispatcher): async def _handle_new_member(self, guild_id, user_id: int): await self._call_all_lists( guild_id, 'new_member', user_id) + + async def _handle_remove_member(self, guild_id, user_id: int): + await self._call_all_lists( + guild_id, 'remove_member', user_id)