pubsub.lazy_guilds: fix role_delete not finding group for role

- pubsub.lazy_guilds: add presence reassignment on role_delete
 - pubsub.lazy_guilds: fix getting role_range due to incorrect operators
This commit is contained in:
Luna Mendes 2018-11-09 17:18:35 -03:00
parent 58c818bb68
commit f34c3f6296
2 changed files with 30 additions and 6 deletions

View File

@ -1,6 +1,7 @@
from typing import List, Dict, Any, Union from typing import List, Dict, Any, Union
from quart import Blueprint, request, current_app as app, jsonify from quart import Blueprint, request, current_app as app, jsonify
from logging import Logger
from litecord.auth import token_check from litecord.auth import token_check
@ -15,6 +16,7 @@ from litecord.snowflake import get_snowflake
from litecord.utils import dict_get from litecord.utils import dict_get
DEFAULT_EVERYONE_PERMS = 104324161 DEFAULT_EVERYONE_PERMS = 104324161
log = Logger(__name__)
bp = Blueprint('guild_roles', __name__) bp = Blueprint('guild_roles', __name__)
@ -265,6 +267,8 @@ async def update_guild_role_positions(guild_id):
# extract the list out # extract the list out
j = j['roles'] j = j['roles']
log.debug('role stuff: {!r}', j)
all_roles = await app.storage.get_role_data(guild_id) all_roles = await app.storage.get_role_data(guild_id)
# we'll have to calculate pairs of changing roles, # we'll have to calculate pairs of changing roles,

View File

@ -13,6 +13,7 @@ from litecord.permissions import (
Permissions, overwrite_find_mix, get_permissions, role_permissions Permissions, overwrite_find_mix, get_permissions, role_permissions
) )
from litecord.utils import index_by_func from litecord.utils import index_by_func
from litecord.storage import str_
log = Logger(__name__) log = Logger(__name__)
@ -460,13 +461,16 @@ class GuildMemberList:
"""Send a GUILD_MEMBER_LIST_UPDATE event """Send a GUILD_MEMBER_LIST_UPDATE event
for a shard that is querying about the member list. for a shard that is querying about the member list.
For the purposes of documentation:
Range = Union[List, Tuple]
Paramteters Paramteters
----------- -----------
session_id: str session_id: str
The Session ID querying information. The Session ID querying information.
channel_id: int channel_id: int
The Channel ID that we want information on. The Channel ID that we want information on.
ranges: List[List[int]] ranges: List[Range[int, int]]
ranges of the list that we want. ranges of the list that we want.
""" """
@ -850,7 +854,7 @@ class GuildMemberList:
async def role_delete(self, role_id: int): async def role_delete(self, role_id: int):
"""Called when a role is deleted, so we should """Called when a role is deleted, so we should
delete it off the list.""" delete it off the list and reassign presences."""
if not self.list: if not self.list:
return return
@ -859,7 +863,7 @@ class GuildMemberList:
# find the item id for the group info # find the item id for the group info
role_item_index = index_by_func( role_item_index = index_by_func(
lambda d: d.get('group', {}).get('id') == role_id, lambda d: str_(d.get('group', {}).get('id')) == str(role_id),
self.items self.items
) )
@ -896,7 +900,17 @@ class GuildMemberList:
# now the data info # now the data info
try: try:
self.list.data.pop(role_id) # we need to reassign those orphan presences
# into a new group
presences = self.list.data.pop(role_id)
# by calling the same functions we'd be calling
# when generating the guild, we can reassign
# the presences into new groups and sort
# the new presences so we achieve the correct state
log.debug('reassigning {} presences', len(presences))
await self._pass_1(presences)
await self._sort_groups()
except KeyError: except KeyError:
log.warning('list unstable: {} not in data dict', role_id) log.warning('list unstable: {} not in data dict', role_id)
@ -914,6 +928,10 @@ class GuildMemberList:
log.info('role_delete rid={} (gid={}, cid={})', log.info('role_delete rid={} (gid={}, cid={})',
role_id, self.guild_id, self.channel_id) role_id, self.guild_id, self.channel_id)
pprint.pprint(self.state)
log.debug('there are {} session ids to resync (for item {})',
len(sess_ids_resync), role_item_index)
for session_id in sess_ids_resync: for session_id in sess_ids_resync:
# find the list range that the group was on # find the list range that the group was on
# so we resync only the given range, instead # so we resync only the given range, instead
@ -923,13 +941,15 @@ class GuildMemberList:
try: try:
# get the only range where the group is in # get the only range where the group is in
role_range = next((r_min, r_max) for r_min, r_max in ranges role_range = next((r_min, r_max) for r_min, r_max in ranges
if r_min < role_item_index < r_max) if r_min <= role_item_index <= r_max)
except StopIteration: except StopIteration:
log.debug('ignoring sess_id={}, no range for item {}, {}',
session_id, role_item_index, ranges)
continue continue
# do resync-ing in the background # do resync-ing in the background
self.loop.create_task( self.loop.create_task(
self.shard_query(session_id, role_range) self.shard_query(session_id, [role_range])
) )