From 79ee2b0d574090e7f2c6006325742f1d7f9bb469 Mon Sep 17 00:00:00 2001 From: Amrou Bellalouna Date: Fri, 19 Aug 2022 15:10:13 +0100 Subject: fix "isistance" typo --- tests/test_helpers.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_helpers.py b/tests/test_helpers.py index f3040b305..b2686b1d0 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -14,7 +14,7 @@ class DiscordMocksTests(unittest.TestCase): """Test if the default initialization of MockRole results in the correct object.""" role = helpers.MockRole() - # The `spec` argument makes sure `isistance` checks with `discord.Role` pass + # The `spec` argument makes sure `isinstance` checks with `discord.Role` pass self.assertIsInstance(role, discord.Role) self.assertEqual(role.name, "role") -- cgit v1.2.3 From ddd829fc235b0484064fce0c4924e980659ec2bb Mon Sep 17 00:00:00 2001 From: Amrou Bellalouna Date: Fri, 19 Aug 2022 15:12:59 +0100 Subject: add support for keywords when using the "rules" command. This doesn't change the way the rules command originally worked and keeps the priority to rule numbers. But in case a number (or numbers) is not supplied, it will try to find a rule that maps to a the supplied keyword. --- bot/exts/info/information.py | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index e7d17c971..d53f4e323 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -518,12 +518,12 @@ class Information(Cog): await self.send_raw_content(ctx, message, json=True) @command(aliases=("rule",)) - async def rules(self, ctx: Context, rules: Greedy[int]) -> None: + async def rules(self, ctx: Context, rules: Greedy[int], keyword: Optional[str]) -> None: """Provides a link to all rules or, if specified, displays specific rule(s).""" rules_embed = Embed(title="Rules", color=Colour.og_blurple(), url="https://www.pythondiscord.com/pages/rules") - if not rules: - # Rules were not submitted. Return the default description. + if not rules and not keyword: + # Neither rules nor keywords were submitted. Return the default description. rules_embed.description = ( "The rules and guidelines that apply to this community can be found on" " our [rules page](https://www.pythondiscord.com/pages/rules). We expect" @@ -547,7 +547,21 @@ class Information(Cog): for rule in rules: self.bot.stats.incr(f"rule_uses.{rule}") - final_rules = tuple(f"**{pick}.** {full_rules[pick - 1]}" for pick in rules) + if rules: + final_rules = tuple(f"**{pick}.** {full_rules[pick - 1][0]}" for pick in rules) + else: + final_rules = tuple(f"**{pick + 1}** {full_rules[pick][0]}" for pick, rule in enumerate(full_rules) + if keyword in rule[1]) + + if not rules and not final_rules: + # This would mean that we didn't find a match for the used keyword + rules_embed.description = ( + f"There are currently no rules that correspond to keyword: {keyword}." + " If you think it should be added, please ask our admins and they'll take care of the rest." + ) + + await ctx.send(embed=rules_embed) + return await LinePaginator.paginate(final_rules, ctx, rules_embed, max_lines=3) -- cgit v1.2.3 From 357ed80e2a0f35172ca91ceda7a353a4a8f765dd Mon Sep 17 00:00:00 2001 From: Amrou Bellalouna Date: Thu, 8 Sep 2022 23:11:41 +0100 Subject: send the list of pre-defined keywords along with each invoked rule --- bot/exts/info/information.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index d53f4e323..54fa62d31 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -521,6 +521,7 @@ class Information(Cog): async def rules(self, ctx: Context, rules: Greedy[int], keyword: Optional[str]) -> None: """Provides a link to all rules or, if specified, displays specific rule(s).""" rules_embed = Embed(title="Rules", color=Colour.og_blurple(), url="https://www.pythondiscord.com/pages/rules") + keyword = keyword.lower() if not rules and not keyword: # Neither rules nor keywords were submitted. Return the default description. @@ -548,9 +549,13 @@ class Information(Cog): self.bot.stats.incr(f"rule_uses.{rule}") if rules: - final_rules = tuple(f"**{pick}.** {full_rules[pick - 1][0]}" for pick in rules) + final_rules = tuple(f"**{pick}.** {full_rules[pick - 1][0]}\n\n" + f"You can also invoke this rule with the following keywords: " + f"{', '.join(full_rules[pick -1][1])}" for pick in rules) else: - final_rules = tuple(f"**{pick + 1}** {full_rules[pick][0]}" for pick, rule in enumerate(full_rules) + final_rules = tuple(f"**{pick + 1}** {full_rules[pick][0]}\n\n" + f"You can also invoke this rule with the following keywords: " + f"{', '.join(full_rules[pick][1])}" for pick, rule in enumerate(full_rules) if keyword in rule[1]) if not rules and not final_rules: -- cgit v1.2.3 From f924dd24a6846dcc00f96c7158111cfffc092014 Mon Sep 17 00:00:00 2001 From: Amrou Bellalouna Date: Thu, 8 Sep 2022 23:17:25 +0100 Subject: send the "no-match" error message in pure text format --- bot/exts/info/information.py | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index 54fa62d31..9dd0a6d45 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -560,12 +560,9 @@ class Information(Cog): if not rules and not final_rules: # This would mean that we didn't find a match for the used keyword - rules_embed.description = ( + await ctx.send( f"There are currently no rules that correspond to keyword: {keyword}." - " If you think it should be added, please ask our admins and they'll take care of the rest." - ) - - await ctx.send(embed=rules_embed) + "If you think it should be added, please ask our admins and they'll take care of the rest.") return await LinePaginator.paginate(final_rules, ctx, rules_embed, max_lines=3) -- cgit v1.2.3 From c1ce6839ae4a944ee4207d8d283a738f64937b3a Mon Sep 17 00:00:00 2001 From: Amrou Bellalouna Date: Sun, 11 Sep 2022 09:30:31 +0100 Subject: accept keywords and rule numbers in any order --- bot/exts/info/information.py | 58 +++++++++++++++++++++++++++++--------------- 1 file changed, 39 insertions(+), 19 deletions(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index 9dd0a6d45..3dd12c005 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -8,7 +8,7 @@ from typing import Any, DefaultDict, Mapping, Optional, Tuple, Union import rapidfuzz from botcore.site_api import ResponseCodeError from discord import AllowedMentions, Colour, Embed, Guild, Message, Role -from discord.ext.commands import BucketType, Cog, Context, Greedy, Paginator, command, group, has_any_role +from discord.ext.commands import BucketType, Cog, Context, Paginator, command, group, has_any_role from discord.utils import escape_markdown from bot import constants @@ -518,12 +518,23 @@ class Information(Cog): await self.send_raw_content(ctx, message, json=True) @command(aliases=("rule",)) - async def rules(self, ctx: Context, rules: Greedy[int], keyword: Optional[str]) -> None: - """Provides a link to all rules or, if specified, displays specific rule(s).""" + async def rules(self, ctx: Context, *args: Optional[str]) -> None: + """ + Provides a link to all rules or, if specified, displays specific rules(s). + + It accepts either rule numbers or particular keywords that map to a particular rule. + Rule numbers and keywords can be sent in any order. + """ rules_embed = Embed(title="Rules", color=Colour.og_blurple(), url="https://www.pythondiscord.com/pages/rules") - keyword = keyword.lower() + keywords, rules = [], [] + + for word in args: + if word.isdigit(): + rules.append(int(word)) + else: + keywords.append(word.lower()) - if not rules and not keyword: + if not rules and not keywords: # Neither rules nor keywords were submitted. Return the default description. rules_embed.description = ( "The rules and guidelines that apply to this community can be found on" @@ -538,30 +549,39 @@ class Information(Cog): # Remove duplicates and sort the rule indices rules = sorted(set(rules)) + # Remove duplicate keywords + keywords = set(keywords) invalid = ", ".join(str(index) for index in rules if index < 1 or index > len(full_rules)) - if invalid: + if invalid and not keywords: await ctx.send(shorten(":x: Invalid rule indices: " + invalid, 75, placeholder=" ...")) return - for rule in rules: - self.bot.stats.incr(f"rule_uses.{rule}") + final_rules = set() - if rules: - final_rules = tuple(f"**{pick}.** {full_rules[pick - 1][0]}\n\n" - f"You can also invoke this rule with the following keywords: " - f"{', '.join(full_rules[pick -1][1])}" for pick in rules) - else: - final_rules = tuple(f"**{pick + 1}** {full_rules[pick][0]}\n\n" - f"You can also invoke this rule with the following keywords: " - f"{', '.join(full_rules[pick][1])}" for pick, rule in enumerate(full_rules) - if keyword in rule[1]) + for pick in rules: + self.bot.stats.incr(f"rule_uses.{pick}") + final_rules.add( + f"**{pick}.** {full_rules[pick - 1][0]}\n\n" + f"You can also invoke this rule with the following keywords: " + f"{', '.join(full_rules[pick -1][1])}") + + for keyword in keywords: + for pick, rule in enumerate(full_rules): + if keyword not in rule[1]: + continue + + self.bot.stats.incr(f"rule_uses.{pick + 1}") + final_rules.add( + f"**{pick + 1}.** {full_rules[pick][0]}\n\n" + f"You can also invoke this rule with the following keywords: " + f"{', '.join(full_rules[pick][1])}") if not rules and not final_rules: - # This would mean that we didn't find a match for the used keyword + # This would mean that only keywords where used and no match for them was found await ctx.send( - f"There are currently no rules that correspond to keyword: {keyword}." + f"There are currently no rules that correspond to keywords: {[', '.join(keywords)]}." "If you think it should be added, please ask our admins and they'll take care of the rest.") return -- cgit v1.2.3 From 6b3b18078d8f8a636c5c5908f41f9075ab1ebfac Mon Sep 17 00:00:00 2001 From: Amrou Bellalouna Date: Sun, 11 Sep 2022 10:29:35 +0100 Subject: add missing blank line --- bot/constants.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bot/constants.py b/bot/constants.py index db98e6f47..68a96876f 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -397,6 +397,7 @@ class Categories(metaclass=YAMLGetter): # 2021 Summer Code Jam summer_code_jam: int + class Channels(metaclass=YAMLGetter): section = "guild" subsection = "channels" -- cgit v1.2.3 From 8350f3641ff13da8f4d4849a2e44627f485e6a93 Mon Sep 17 00:00:00 2001 From: Amrou Bellalouna Date: Sun, 11 Sep 2022 10:35:41 +0100 Subject: suggest adding a keyword in dev & meta channels --- bot/exts/info/information.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/bot/exts/info/information.py b/bot/exts/info/information.py index 3dd12c005..5f996508f 100644 --- a/bot/exts/info/information.py +++ b/bot/exts/info/information.py @@ -19,7 +19,7 @@ from bot.errors import NonExistentRoleError from bot.log import get_logger from bot.pagination import LinePaginator from bot.utils import time -from bot.utils.channel import is_mod_channel, is_staff_channel +from bot.utils.channel import get_or_fetch_channel, is_mod_channel, is_staff_channel from bot.utils.checks import cooldown_with_role_bypass, has_no_roles_check, in_whitelist_check from bot.utils.members import get_or_fetch_member @@ -580,9 +580,12 @@ class Information(Cog): if not rules and not final_rules: # This would mean that only keywords where used and no match for them was found + dev_contrib_channel = await get_or_fetch_channel(constants.Channels.dev_contrib) + meta_channel = await get_or_fetch_channel(constants.Channels.meta) await ctx.send( - f"There are currently no rules that correspond to keywords: {[', '.join(keywords)]}." - "If you think it should be added, please ask our admins and they'll take care of the rest.") + f"There are currently no rules that correspond to keywords: **{', '.join(keywords)}**.\n" + f"If you think it should be added, please suggest it in either " + f"{meta_channel.mention} or {dev_contrib_channel.mention}") return await LinePaginator.paginate(final_rules, ctx, rules_embed, max_lines=3) -- cgit v1.2.3