Loading cog/actions.py +7 −6 Original line number Diff line number Diff line Loading @@ -331,7 +331,7 @@ class Admin(Action): top_all = await self.bot.loop.run_in_executor( None, cogdb.query.users_with_all_merits, self.session, ) top_recruits, top_members = filter_top_dusers(self.msg.guild, top_all, exclude_roles, limit=arg_limit) top_recruits, top_members = await filter_top_dusers(self.msg.guild, top_all, exclude_roles, limit=arg_limit) lines = [["Top {} Recruits".format(limit), "Merits", "Top {} Members".format(limit), "Merits"]] lines += [[rec[0], rec[1], mem[0], mem[1]] for rec, mem in zip(top_recruits, top_members)] parts += cog.tbl.format_table(lines, header=True, prefix=prefix, suffix="\n\n") Loading @@ -339,7 +339,7 @@ class Admin(Action): top_fort = await self.bot.loop.run_in_executor( None, cogdb.query.users_with_fort_merits, self.session, ) top_recruits, top_members = filter_top_dusers(self.msg.guild, top_fort, exclude_roles, limit=arg_limit) top_recruits, top_members = await filter_top_dusers(self.msg.guild, top_fort, exclude_roles, limit=arg_limit) lines = [["Top {} Fort Recruits".format(limit), "Merits", "Top Fort {} Members".format(limit), "Merits"]] lines += [[rec[0], rec[1], mem[0], mem[1]] for rec, mem in zip(top_recruits, top_members)] parts += cog.tbl.format_table(lines, header=True, suffix="\n\n") Loading @@ -347,7 +347,7 @@ class Admin(Action): top_um = await self.bot.loop.run_in_executor( None, cogdb.query.users_with_um_merits, self.session, ) top_recruits, top_members = filter_top_dusers(self.msg.guild, top_um, exclude_roles, limit=arg_limit) top_recruits, top_members = await filter_top_dusers(self.msg.guild, top_um, exclude_roles, limit=arg_limit) lines = [["Top {} UM Recruits".format(limit), "Merits", "Top UM {} Members".format(limit), "Merits"]] lines += [[rec[0], rec[1], mem[0], mem[1]] for rec, mem in zip(top_recruits, top_members)] parts += cog.tbl.format_table(lines, header=True, suffix="\n\n") Loading Loading @@ -2026,7 +2026,7 @@ def process_system_args(args): return system_names.split(',') def filter_top_dusers(guild, dusers, exclude_roles, limit=5): async def filter_top_dusers(guild, dusers, exclude_roles, limit=5): """ Generate a top N list from existing DiscordUser list. Both lists are guaranteed to be at least limit long and will be Loading @@ -2044,14 +2044,15 @@ def filter_top_dusers(guild, dusers, exclude_roles, limit=5): """ top_recruits, top_members = [], [] await guild.chunk() # Force refresh of local members cache for duser, merits in dusers: member = guild.get_member(duser.id) member = guild.get_member(int(duser.id)) if not member: continue # User left or wrong discord id role_names = [x.name for x in member.roles] # If has an exclude role, ignore if len(list(set(role_names) - set(exclude_roles))) != len(role_names): if len(set(role_names) - set(exclude_roles)) != len(role_names): continue if "FRC Member" in role_names and len(top_members) != limit: top_members += [(duser.pref_name, merits)] Loading cogdb/query.py +3 −0 Original line number Diff line number Diff line Loading @@ -115,6 +115,7 @@ def users_with_all_merits(session): outerjoin(FortUser, DiscordUser.pref_name == FortUser.name).\ outerjoin(UMUser, DiscordUser.pref_name == UMUser.name).\ order_by(sqla.desc("total")).\ limit(100).\ all() Loading @@ -131,6 +132,7 @@ def users_with_fort_merits(session): return session.query(DiscordUser, FortUser.dropped).\ join(FortUser, FortUser.name == DiscordUser.pref_name).\ order_by(FortUser.dropped.desc()).\ limit(100).\ all() Loading @@ -148,6 +150,7 @@ def users_with_um_merits(session): join(UMUser, UMUser.name == DiscordUser.pref_name).\ filter(UMUser.sheet_src == EUMSheet.main).\ order_by(sqla.desc('um_merits')).\ limit(100).\ all() Loading tests/cog/test_actions.py +12 −4 Original line number Diff line number Diff line Loading @@ -1739,7 +1739,8 @@ def test_process_system_args(): assert results == ['this', 'is', 'an', 'example.'] def test_filter_top_dusers(session, f_dusers, f_fort_testbed, f_um_testbed): @pytest.mark.asyncio async def test_filter_top_dusers(session, f_dusers, f_fort_testbed, f_um_testbed): top_fort = cogdb.query.users_with_fort_merits(session) mapped = { 1: tc.Member(top_fort[2][0].pref_name, roles=[tc.Role("FRC Recruit"), tc.Role("Something")]), Loading @@ -1749,9 +1750,12 @@ def test_filter_top_dusers(session, f_dusers, f_fort_testbed, f_um_testbed): def get_member_(did): return mapped[did] async def chunk_(_=None): return None guild = aiomock.Mock() guild.get_member = get_member_ guild.chunk = chunk_ expected_rec = [ ('User3', 1800), Loading @@ -1767,12 +1771,13 @@ def test_filter_top_dusers(session, f_dusers, f_fort_testbed, f_um_testbed): ('', ''), ('', '') ] rec, mem = cog.actions.filter_top_dusers(guild, top_fort, []) rec, mem = await cog.actions.filter_top_dusers(guild, top_fort, []) assert rec == expected_rec assert mem == expected_mem def test_filter_top_dusers_exclude(session, f_dusers, f_fort_testbed, f_um_testbed): @pytest.mark.asyncio async def test_filter_top_dusers_exclude(session, f_dusers, f_fort_testbed, f_um_testbed): top_fort = cogdb.query.users_with_fort_merits(session) mapped = { 1: tc.Member(top_fort[2][0].pref_name, roles=[tc.Role("FRC Recruit"), tc.Role("Filter")]), Loading @@ -1782,9 +1787,12 @@ def test_filter_top_dusers_exclude(session, f_dusers, f_fort_testbed, f_um_testb def get_member_(did): return mapped[did] async def chunk_(_=None): return None guild = aiomock.Mock() guild.get_member = get_member_ guild.chunk = chunk_ expected_rec = [ ('', ''), Loading @@ -1794,7 +1802,7 @@ def test_filter_top_dusers_exclude(session, f_dusers, f_fort_testbed, f_um_testb ('User2', 2000), ('', ''), ] rec, mem = cog.actions.filter_top_dusers(guild, top_fort, ["Filter"], 2) rec, mem = await cog.actions.filter_top_dusers(guild, top_fort, ["Filter"], 2) assert rec == expected_rec assert mem == expected_mem Loading tests/conftest.py +3 −0 Original line number Diff line number Diff line Loading @@ -432,6 +432,9 @@ class Guild(FakeObject): found = [x for x in self.mapped.values() if nick in x.display_name] return found[0] if found else None async def chunk(self): return None # def __repr__(self): # channels = "\n Channels: " + ", ".join([cha.name for cha in self.channels]) # return super().__repr__() + channels Loading Loading
cog/actions.py +7 −6 Original line number Diff line number Diff line Loading @@ -331,7 +331,7 @@ class Admin(Action): top_all = await self.bot.loop.run_in_executor( None, cogdb.query.users_with_all_merits, self.session, ) top_recruits, top_members = filter_top_dusers(self.msg.guild, top_all, exclude_roles, limit=arg_limit) top_recruits, top_members = await filter_top_dusers(self.msg.guild, top_all, exclude_roles, limit=arg_limit) lines = [["Top {} Recruits".format(limit), "Merits", "Top {} Members".format(limit), "Merits"]] lines += [[rec[0], rec[1], mem[0], mem[1]] for rec, mem in zip(top_recruits, top_members)] parts += cog.tbl.format_table(lines, header=True, prefix=prefix, suffix="\n\n") Loading @@ -339,7 +339,7 @@ class Admin(Action): top_fort = await self.bot.loop.run_in_executor( None, cogdb.query.users_with_fort_merits, self.session, ) top_recruits, top_members = filter_top_dusers(self.msg.guild, top_fort, exclude_roles, limit=arg_limit) top_recruits, top_members = await filter_top_dusers(self.msg.guild, top_fort, exclude_roles, limit=arg_limit) lines = [["Top {} Fort Recruits".format(limit), "Merits", "Top Fort {} Members".format(limit), "Merits"]] lines += [[rec[0], rec[1], mem[0], mem[1]] for rec, mem in zip(top_recruits, top_members)] parts += cog.tbl.format_table(lines, header=True, suffix="\n\n") Loading @@ -347,7 +347,7 @@ class Admin(Action): top_um = await self.bot.loop.run_in_executor( None, cogdb.query.users_with_um_merits, self.session, ) top_recruits, top_members = filter_top_dusers(self.msg.guild, top_um, exclude_roles, limit=arg_limit) top_recruits, top_members = await filter_top_dusers(self.msg.guild, top_um, exclude_roles, limit=arg_limit) lines = [["Top {} UM Recruits".format(limit), "Merits", "Top UM {} Members".format(limit), "Merits"]] lines += [[rec[0], rec[1], mem[0], mem[1]] for rec, mem in zip(top_recruits, top_members)] parts += cog.tbl.format_table(lines, header=True, suffix="\n\n") Loading Loading @@ -2026,7 +2026,7 @@ def process_system_args(args): return system_names.split(',') def filter_top_dusers(guild, dusers, exclude_roles, limit=5): async def filter_top_dusers(guild, dusers, exclude_roles, limit=5): """ Generate a top N list from existing DiscordUser list. Both lists are guaranteed to be at least limit long and will be Loading @@ -2044,14 +2044,15 @@ def filter_top_dusers(guild, dusers, exclude_roles, limit=5): """ top_recruits, top_members = [], [] await guild.chunk() # Force refresh of local members cache for duser, merits in dusers: member = guild.get_member(duser.id) member = guild.get_member(int(duser.id)) if not member: continue # User left or wrong discord id role_names = [x.name for x in member.roles] # If has an exclude role, ignore if len(list(set(role_names) - set(exclude_roles))) != len(role_names): if len(set(role_names) - set(exclude_roles)) != len(role_names): continue if "FRC Member" in role_names and len(top_members) != limit: top_members += [(duser.pref_name, merits)] Loading
cogdb/query.py +3 −0 Original line number Diff line number Diff line Loading @@ -115,6 +115,7 @@ def users_with_all_merits(session): outerjoin(FortUser, DiscordUser.pref_name == FortUser.name).\ outerjoin(UMUser, DiscordUser.pref_name == UMUser.name).\ order_by(sqla.desc("total")).\ limit(100).\ all() Loading @@ -131,6 +132,7 @@ def users_with_fort_merits(session): return session.query(DiscordUser, FortUser.dropped).\ join(FortUser, FortUser.name == DiscordUser.pref_name).\ order_by(FortUser.dropped.desc()).\ limit(100).\ all() Loading @@ -148,6 +150,7 @@ def users_with_um_merits(session): join(UMUser, UMUser.name == DiscordUser.pref_name).\ filter(UMUser.sheet_src == EUMSheet.main).\ order_by(sqla.desc('um_merits')).\ limit(100).\ all() Loading
tests/cog/test_actions.py +12 −4 Original line number Diff line number Diff line Loading @@ -1739,7 +1739,8 @@ def test_process_system_args(): assert results == ['this', 'is', 'an', 'example.'] def test_filter_top_dusers(session, f_dusers, f_fort_testbed, f_um_testbed): @pytest.mark.asyncio async def test_filter_top_dusers(session, f_dusers, f_fort_testbed, f_um_testbed): top_fort = cogdb.query.users_with_fort_merits(session) mapped = { 1: tc.Member(top_fort[2][0].pref_name, roles=[tc.Role("FRC Recruit"), tc.Role("Something")]), Loading @@ -1749,9 +1750,12 @@ def test_filter_top_dusers(session, f_dusers, f_fort_testbed, f_um_testbed): def get_member_(did): return mapped[did] async def chunk_(_=None): return None guild = aiomock.Mock() guild.get_member = get_member_ guild.chunk = chunk_ expected_rec = [ ('User3', 1800), Loading @@ -1767,12 +1771,13 @@ def test_filter_top_dusers(session, f_dusers, f_fort_testbed, f_um_testbed): ('', ''), ('', '') ] rec, mem = cog.actions.filter_top_dusers(guild, top_fort, []) rec, mem = await cog.actions.filter_top_dusers(guild, top_fort, []) assert rec == expected_rec assert mem == expected_mem def test_filter_top_dusers_exclude(session, f_dusers, f_fort_testbed, f_um_testbed): @pytest.mark.asyncio async def test_filter_top_dusers_exclude(session, f_dusers, f_fort_testbed, f_um_testbed): top_fort = cogdb.query.users_with_fort_merits(session) mapped = { 1: tc.Member(top_fort[2][0].pref_name, roles=[tc.Role("FRC Recruit"), tc.Role("Filter")]), Loading @@ -1782,9 +1787,12 @@ def test_filter_top_dusers_exclude(session, f_dusers, f_fort_testbed, f_um_testb def get_member_(did): return mapped[did] async def chunk_(_=None): return None guild = aiomock.Mock() guild.get_member = get_member_ guild.chunk = chunk_ expected_rec = [ ('', ''), Loading @@ -1794,7 +1802,7 @@ def test_filter_top_dusers_exclude(session, f_dusers, f_fort_testbed, f_um_testb ('User2', 2000), ('', ''), ] rec, mem = cog.actions.filter_top_dusers(guild, top_fort, ["Filter"], 2) rec, mem = await cog.actions.filter_top_dusers(guild, top_fort, ["Filter"], 2) assert rec == expected_rec assert mem == expected_mem Loading
tests/conftest.py +3 −0 Original line number Diff line number Diff line Loading @@ -432,6 +432,9 @@ class Guild(FakeObject): found = [x for x in self.mapped.values() if nick in x.display_name] return found[0] if found else None async def chunk(self): return None # def __repr__(self): # channels = "\n Channels: " + ", ".join([cha.name for cha in self.channels]) # return super().__repr__() + channels Loading