From 9b63db31fc9b6fe6a726f711383cb38b2c44bd40 Mon Sep 17 00:00:00 2001 From: Den4200 Date: Sat, 3 Oct 2020 20:38:46 -0400 Subject: Replace `map` with a more pythonic list comprehension. --- bot/exts/info/site.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/info/site.py b/bot/exts/info/site.py index 2d3a3d9f3..9e7f6b0a5 100644 --- a/bot/exts/info/site.py +++ b/bot/exts/info/site.py @@ -129,7 +129,7 @@ class Site(Cog): ) if invalid_indices: - indices = ', '.join(map(str, invalid_indices)) + indices = ', '.join(str(index) for index in invalid_indices) await ctx.send(f":x: Invalid rule indices: {indices}") return -- cgit v1.2.3 From bfcd4689b8cf8f0d1a26ffc1e1b0b4b9b9e9b59d Mon Sep 17 00:00:00 2001 From: Den4200 Date: Sat, 3 Oct 2020 20:40:37 -0400 Subject: Remove duplicates from given rule indices and sort them in order. --- bot/exts/info/site.py | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/bot/exts/info/site.py b/bot/exts/info/site.py index 9e7f6b0a5..c8ae8dc96 100644 --- a/bot/exts/info/site.py +++ b/bot/exts/info/site.py @@ -122,10 +122,14 @@ class Site(Cog): return full_rules = await self.bot.api_client.get('rules', params={'link_format': 'md'}) - invalid_indices = tuple( - pick - for pick in rules - if pick < 1 or pick > len(full_rules) + + # Remove duplicates and sort the invalid rule indices + invalid_indices = sorted( + set( + pick + for pick in rules + if pick < 1 or pick > len(full_rules) + ) ) if invalid_indices: @@ -136,6 +140,9 @@ class Site(Cog): for rule in rules: self.bot.stats.incr(f"rule_uses.{rule}") + # Remove duplicates and sort the rule indices + rules = sorted(set(rules)) + final_rules = tuple(f"**{pick}.** {full_rules[pick - 1]}" for pick in rules) await LinePaginator.paginate(final_rules, ctx, rules_embed, max_lines=3) -- cgit v1.2.3 From 6cc110cf93dd109e371dfae7ad93520920883ca8 Mon Sep 17 00:00:00 2001 From: Den4200 Date: Sat, 3 Oct 2020 20:41:17 -0400 Subject: Use `Greedy` converter instead of the splat operator. --- bot/exts/info/site.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/exts/info/site.py b/bot/exts/info/site.py index c8ae8dc96..12c1737a2 100644 --- a/bot/exts/info/site.py +++ b/bot/exts/info/site.py @@ -1,7 +1,7 @@ import logging from discord import Colour, Embed -from discord.ext.commands import Cog, Context, group +from discord.ext.commands import Cog, Context, Greedy, group from bot.bot import Bot from bot.constants import URLs @@ -105,7 +105,7 @@ class Site(Cog): await ctx.send(embed=embed) @site_group.command(name="rules", aliases=("r", "rule"), root_aliases=("rules", "rule")) - async def site_rules(self, ctx: Context, *rules: int) -> None: + async def site_rules(self, ctx: Context, rules: Greedy[int]) -> None: """Provides a link to all rules or, if specified, displays specific rule(s).""" rules_embed = Embed(title='Rules', color=Colour.blurple()) rules_embed.url = f"{PAGES_URL}/rules" -- cgit v1.2.3 From dcad46fd4637fadc16f69da6bb92dd3513f68d76 Mon Sep 17 00:00:00 2001 From: Den4200 Date: Sat, 3 Oct 2020 21:10:10 -0400 Subject: Use `url` argument instead of setting it outside. --- bot/exts/info/site.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bot/exts/info/site.py b/bot/exts/info/site.py index 12c1737a2..bf2547895 100644 --- a/bot/exts/info/site.py +++ b/bot/exts/info/site.py @@ -107,8 +107,7 @@ class Site(Cog): @site_group.command(name="rules", aliases=("r", "rule"), root_aliases=("rules", "rule")) async def site_rules(self, ctx: Context, rules: Greedy[int]) -> None: """Provides a link to all rules or, if specified, displays specific rule(s).""" - rules_embed = Embed(title='Rules', color=Colour.blurple()) - rules_embed.url = f"{PAGES_URL}/rules" + rules_embed = Embed(title='Rules', color=Colour.blurple(), url=f'{PAGES_URL}/rules') if not rules: # Rules were not submitted. Return the default description. -- cgit v1.2.3 From 2553a1d35bf52681dc8b28327e15fbd3ec14910e Mon Sep 17 00:00:00 2001 From: Den4200 Date: Sun, 4 Oct 2020 11:20:08 -0400 Subject: Sort rules before determining invalid indices. This is to avoid sorting twice - once for invalid indices and again for send the rules. --- bot/exts/info/site.py | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/bot/exts/info/site.py b/bot/exts/info/site.py index bf2547895..fb5b99086 100644 --- a/bot/exts/info/site.py +++ b/bot/exts/info/site.py @@ -122,26 +122,17 @@ class Site(Cog): full_rules = await self.bot.api_client.get('rules', params={'link_format': 'md'}) - # Remove duplicates and sort the invalid rule indices - invalid_indices = sorted( - set( - pick - for pick in rules - if pick < 1 or pick > len(full_rules) - ) - ) + # Remove duplicates and sort the rule indices + rules = sorted(set(rules)) + invalid = ', '.join(str(index) for index in rules if index < 1 or index > len(full_rules)) - if invalid_indices: - indices = ', '.join(str(index) for index in invalid_indices) - await ctx.send(f":x: Invalid rule indices: {indices}") + if invalid: + await ctx.send(f":x: Invalid rule indices: {invalid}") return for rule in rules: self.bot.stats.incr(f"rule_uses.{rule}") - # Remove duplicates and sort the rule indices - rules = sorted(set(rules)) - final_rules = tuple(f"**{pick}.** {full_rules[pick - 1]}" for pick in rules) await LinePaginator.paginate(final_rules, ctx, rules_embed, max_lines=3) -- cgit v1.2.3 From 233f63551bf1945d83f0418e506f9ec9a9381ac6 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Tue, 6 Oct 2020 00:15:20 +0100 Subject: Support users with alternate gating methods --- bot/exts/moderation/verification.py | 42 +++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index 206556483..1d1dacb37 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -53,6 +53,23 @@ If you'd like to unsubscribe from the announcement notifications, simply send `! <#{constants.Channels.bot_commands}>. """ +ALTERNATE_VERIFIED_MESSAGE = f""" +Thanks for accepting our rules! + +You can find a copy of our rules for reference at . + +Additionally, if you'd like to receive notifications for the announcements \ +we post in <#{constants.Channels.announcements}> +from time to time, you can send `!subscribe` to <#{constants.Channels.bot_commands}> at any time \ +to assign yourself the **Announcements** role. We'll mention this role every time we make an announcement. + +If you'd like to unsubscribe from the announcement notifications, simply send `!unsubscribe` to \ +<#{constants.Channels.bot_commands}>. + +To introduce you to our community, we've made the following video: +https://youtu.be/ZH26PuX3re0 +""" + # Sent via DMs to users kicked for failing to verify KICKED_MESSAGE = f""" Hi! You have been automatically kicked from Python Discord as you have failed to accept our rules \ @@ -156,6 +173,9 @@ class Verification(Cog): # ] task_cache = RedisCache() + # Cache who needs to receive an alternate verified DM. + member_gating_cache = RedisCache() + def __init__(self, bot: Bot) -> None: """Start internal tasks.""" self.bot = bot @@ -519,12 +539,34 @@ class Verification(Cog): if member.guild.id != constants.Guild.id: return # Only listen for PyDis events + raw_member = await self.bot.http.get_member(member.guild.id, member.id) + + # Only send the message to users going through our gating system + if raw_member["is_pending"]: + await self.member_gating_cache.set(raw_member.id, True) + return + log.trace(f"Sending on join message to new member: {member.id}") try: await safe_dm(member.send(ON_JOIN_MESSAGE)) except discord.HTTPException: log.exception("DM dispatch failed on unexpected error code") + @Cog.listener() + async def on_member_update(self, before: discord.Member, after: discord.Member): + """Check if we need to send a verification DM to a gated user.""" + before_roles = [r.id for r in before.roles] + after_roles = [r.id for r in after.roles] + + if constants.Roles.verified not in before_roles and constants.Roles.verified in after_roles: + if await self.member_gating_cache.get(after.id): + try: + await safe_dm(after.send(ALTERNATE_VERIFIED_MESSAGE)) + except discord.HTTPException: + log.exception("DM dispatch failed on unexpected error code") + finally: + self.member_gating_cache.pop(after.id) + @Cog.listener() async def on_message(self, message: discord.Message) -> None: """Check new message event for messages to the checkpoint channel & process.""" -- cgit v1.2.3 From 2f18813a08c544f5d8973ba0f3a7d0e78a3dc6eb Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Tue, 6 Oct 2020 00:23:29 +0100 Subject: Add type annotation to on_member_update listener --- bot/exts/moderation/verification.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index 1d1dacb37..b86a67225 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -553,7 +553,7 @@ class Verification(Cog): log.exception("DM dispatch failed on unexpected error code") @Cog.listener() - async def on_member_update(self, before: discord.Member, after: discord.Member): + async def on_member_update(self, before: discord.Member, after: discord.Member) -> None: """Check if we need to send a verification DM to a gated user.""" before_roles = [r.id for r in before.roles] after_roles = [r.id for r in after.roles] -- cgit v1.2.3 From 880b936faf83d8fa3d7489e1f9eaab89b93af1b8 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Tue, 6 Oct 2020 00:36:13 +0100 Subject: Merge get and pop into one conditional --- bot/exts/moderation/verification.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index b86a67225..d5eb61f13 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -559,13 +559,11 @@ class Verification(Cog): after_roles = [r.id for r in after.roles] if constants.Roles.verified not in before_roles and constants.Roles.verified in after_roles: - if await self.member_gating_cache.get(after.id): + if await self.member_gating_cache.pop(after.id): try: await safe_dm(after.send(ALTERNATE_VERIFIED_MESSAGE)) except discord.HTTPException: log.exception("DM dispatch failed on unexpected error code") - finally: - self.member_gating_cache.pop(after.id) @Cog.listener() async def on_message(self, message: discord.Message) -> None: -- cgit v1.2.3 From 406da780c06a6797b860d816c4a418def9a3f116 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Tue, 6 Oct 2020 00:39:54 +0100 Subject: Use clearer variable names in list comprehensions --- bot/exts/moderation/verification.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index d5eb61f13..8ad42a035 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -555,8 +555,8 @@ class Verification(Cog): @Cog.listener() async def on_member_update(self, before: discord.Member, after: discord.Member) -> None: """Check if we need to send a verification DM to a gated user.""" - before_roles = [r.id for r in before.roles] - after_roles = [r.id for r in after.roles] + before_roles = [role.id for role in before.roles] + after_roles = [role.id for role in after.roles] if constants.Roles.verified not in before_roles and constants.Roles.verified in after_roles: if await self.member_gating_cache.pop(after.id): -- cgit v1.2.3 From ceffe46a0d5136308c8f0684c2c406dd34e758fb Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Tue, 6 Oct 2020 00:41:16 +0100 Subject: Reword cache creation comment --- bot/exts/moderation/verification.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index 8ad42a035..c675b8db9 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -173,7 +173,7 @@ class Verification(Cog): # ] task_cache = RedisCache() - # Cache who needs to receive an alternate verified DM. + # Create a cache for storing recipients of the alternate welcome DM. member_gating_cache = RedisCache() def __init__(self, bot: Bot) -> None: -- cgit v1.2.3 From 8d6d3ef56d29c2eff372c858fa0a228eeefdbfb8 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Tue, 6 Oct 2020 00:43:50 +0100 Subject: Clear up comment around DM send --- bot/exts/moderation/verification.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index c675b8db9..89e1cdd7e 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -561,6 +561,10 @@ class Verification(Cog): if constants.Roles.verified not in before_roles and constants.Roles.verified in after_roles: if await self.member_gating_cache.pop(after.id): try: + # If the member has not received a DM from our !accept command + # and has gone through the alternate gating system we should send + # our alternate welcome DM which includes info such as our welcome + # video. await safe_dm(after.send(ALTERNATE_VERIFIED_MESSAGE)) except discord.HTTPException: log.exception("DM dispatch failed on unexpected error code") -- cgit v1.2.3 From ea3217effacc02e06444ea0b21985cd7439a13e7 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Tue, 6 Oct 2020 00:45:31 +0100 Subject: Reword on_join comment for alternate gate members --- bot/exts/moderation/verification.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index 89e1cdd7e..659c7414f 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -541,7 +541,10 @@ class Verification(Cog): raw_member = await self.bot.http.get_member(member.guild.id, member.id) - # Only send the message to users going through our gating system + # If the user has the is_pending flag set, they will be using the alternate + # gate and will not need a welcome DM with verification instructions. + # We will send them an alternate DM once they verify with the welcome + # video. if raw_member["is_pending"]: await self.member_gating_cache.set(raw_member.id, True) return -- cgit v1.2.3 From 082e26342eb3faf104523334cdb87e07eda03db3 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Tue, 6 Oct 2020 00:46:09 +0100 Subject: Correct raw_member to member in verification on_join --- bot/exts/moderation/verification.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index 659c7414f..3b5d7e58b 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -546,7 +546,7 @@ class Verification(Cog): # We will send them an alternate DM once they verify with the welcome # video. if raw_member["is_pending"]: - await self.member_gating_cache.set(raw_member.id, True) + await self.member_gating_cache.set(member.id, True) return log.trace(f"Sending on join message to new member: {member.id}") -- cgit v1.2.3 From 42697e85354223fc1c678bfaf7e273274a9c81bc Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Tue, 6 Oct 2020 00:50:38 +0100 Subject: Use .get() instead of index for fetching is_pending property --- bot/exts/moderation/verification.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/moderation/verification.py b/bot/exts/moderation/verification.py index 3b5d7e58b..c3ad8687e 100644 --- a/bot/exts/moderation/verification.py +++ b/bot/exts/moderation/verification.py @@ -545,7 +545,7 @@ class Verification(Cog): # gate and will not need a welcome DM with verification instructions. # We will send them an alternate DM once they verify with the welcome # video. - if raw_member["is_pending"]: + if raw_member.get("is_pending"): await self.member_gating_cache.set(member.id, True) return -- cgit v1.2.3 From d69804ee73391dc7c95d1d743615ba4b7a1de7d8 Mon Sep 17 00:00:00 2001 From: Boris Muratov Date: Tue, 6 Oct 2020 11:43:10 +0300 Subject: Fix old nick in superstarify reason --- bot/exts/moderation/infraction/superstarify.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/bot/exts/moderation/infraction/superstarify.py b/bot/exts/moderation/infraction/superstarify.py index eec63f5b3..adfe42fcd 100644 --- a/bot/exts/moderation/infraction/superstarify.py +++ b/bot/exts/moderation/infraction/superstarify.py @@ -135,7 +135,8 @@ class Superstarify(InfractionScheduler, Cog): return # Post the infraction to the API - reason = reason or f"old nick: {member.display_name}" + old_nick = member.display_name + reason = reason or f"old nick: {old_nick}" infraction = await _utils.post_infraction(ctx, member, "superstar", reason, duration, active=True) id_ = infraction["id"] @@ -148,7 +149,7 @@ class Superstarify(InfractionScheduler, Cog): await member.edit(nick=forced_nick, reason=reason) self.schedule_expiration(infraction) - old_nick = escape_markdown(member.display_name) + old_nick = escape_markdown(old_nick) forced_nick = escape_markdown(forced_nick) # Send a DM to the user to notify them of their new infraction. -- cgit v1.2.3 From 672704841ddfe79d393a621e8c934bdb362f4ef0 Mon Sep 17 00:00:00 2001 From: Numerlor <25886452+Numerlor@users.noreply.github.com> Date: Tue, 6 Oct 2020 21:36:34 +0200 Subject: Include rolled over logs in gitignore RotatingFileHandler appends .# to log names when rolling over to a new file. --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index fb3156ab1..2074887ad 100644 --- a/.gitignore +++ b/.gitignore @@ -110,6 +110,7 @@ ENV/ # Logfiles log.* +*.log.* # Custom user configuration config.yml -- cgit v1.2.3