From 2fdb0e5fce6d246cfc67962e235b4d53622f03d7 Mon Sep 17 00:00:00 2001 From: Anand Krishna <40204976+anand2312@users.noreply.github.com> Date: Fri, 5 Feb 2021 19:13:40 +0400 Subject: Make `KeyError` tag --- bot/resources/tags/keyerror.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 bot/resources/tags/keyerror.md diff --git a/bot/resources/tags/keyerror.md b/bot/resources/tags/keyerror.md new file mode 100644 index 000000000..d0c069004 --- /dev/null +++ b/bot/resources/tags/keyerror.md @@ -0,0 +1,17 @@ +Often while using dictionaries in Python, you may run into `KeyErrors`. This error is raised when you try to access a key that isn't present in your dictionary. \ +While you can use a `try` and `except` block to catch the `KeyError`, Python also gives you some other neat ways to handle them. +## __The `dict.get` method__ +The [dict.get](https://docs.python.org/3/library/stdtypes.html#dict.get) method will return the value for the key if it exists, or None (or a default value that you specify) if the key doesn't exist. Hence it will _never raise_ a KeyError. +```py +>>> my_dict = {"foo": 1, "bar": 2} +>>> print(my_dict.get("foo")) +1 +>>> print(my_dict.get("foobar")) +None +>>> print(my_dict.get("foobar", 3)) # here 3 is the default value to be returned, in case the key doesn't exist +3 +>>> print(my_dict) +{'foo': 1, 'bar': 2} # note that the new key was NOT added to the dictionary +``` +\ +Some other methods that can be used for handling KeyErrors gracefully are the [dict.setdefault](https://docs.python.org/3/library/stdtypes.html#dict.setdefault) method, or by using [collections.defaultdict](https://docs.python.org/3/library/collections.html#collections.defaultdict). -- cgit v1.2.3 From 2c4d7f41432bb620d83d3403fe4ab9317bc1129f Mon Sep 17 00:00:00 2001 From: Anand Krishna <40204976+anand2312@users.noreply.github.com> Date: Fri, 5 Feb 2021 19:39:36 +0400 Subject: Update and rename keyerror.md to dict-get.md --- bot/resources/tags/dict-get.md | 13 +++++++++++++ bot/resources/tags/keyerror.md | 17 ----------------- 2 files changed, 13 insertions(+), 17 deletions(-) create mode 100644 bot/resources/tags/dict-get.md delete mode 100644 bot/resources/tags/keyerror.md diff --git a/bot/resources/tags/dict-get.md b/bot/resources/tags/dict-get.md new file mode 100644 index 000000000..b22db7af5 --- /dev/null +++ b/bot/resources/tags/dict-get.md @@ -0,0 +1,13 @@ +Often while using dictionaries in Python, you may run into `KeyErrors`. This error is raised when you try to access a key that isn't present in your dictionary.\ +While you can use a `try` and `except` block to catch the `KeyError`, Python also gives you some other neat ways to handle them. +__**The `dict.get` method**__ +The [`dict.get`](https://docs.python.org/3/library/stdtypes.html#dict.get) method will return the value for the key if it exists, or None (or a default value that you specify) if the key doesn't exist. Hence it will _never raise_ a KeyError. +```py +>>> my_dict = {"foo": 1, "bar": 2} +>>> print(my_dict.get("foobar")) +None +>>> print(my_dict.get("foobar", 3)) # here 3 is the default value to be returned, in case the key doesn't exist +3 +``` + +Some other methods that can be used for handling KeyErrors gracefully are the [`dict.setdefault`](https://docs.python.org/3/library/stdtypes.html#dict.setdefault) method, or by using [`collections.defaultdict`](https://docs.python.org/3/library/collections.html#collections.defaultdict). diff --git a/bot/resources/tags/keyerror.md b/bot/resources/tags/keyerror.md deleted file mode 100644 index d0c069004..000000000 --- a/bot/resources/tags/keyerror.md +++ /dev/null @@ -1,17 +0,0 @@ -Often while using dictionaries in Python, you may run into `KeyErrors`. This error is raised when you try to access a key that isn't present in your dictionary. \ -While you can use a `try` and `except` block to catch the `KeyError`, Python also gives you some other neat ways to handle them. -## __The `dict.get` method__ -The [dict.get](https://docs.python.org/3/library/stdtypes.html#dict.get) method will return the value for the key if it exists, or None (or a default value that you specify) if the key doesn't exist. Hence it will _never raise_ a KeyError. -```py ->>> my_dict = {"foo": 1, "bar": 2} ->>> print(my_dict.get("foo")) -1 ->>> print(my_dict.get("foobar")) -None ->>> print(my_dict.get("foobar", 3)) # here 3 is the default value to be returned, in case the key doesn't exist -3 ->>> print(my_dict) -{'foo': 1, 'bar': 2} # note that the new key was NOT added to the dictionary -``` -\ -Some other methods that can be used for handling KeyErrors gracefully are the [dict.setdefault](https://docs.python.org/3/library/stdtypes.html#dict.setdefault) method, or by using [collections.defaultdict](https://docs.python.org/3/library/collections.html#collections.defaultdict). -- cgit v1.2.3 From 721472352f05c561625932a88bcf3c10c98c130d Mon Sep 17 00:00:00 2001 From: Anand Krishna <40204976+anand2312@users.noreply.github.com> Date: Fri, 5 Feb 2021 19:43:29 +0400 Subject: Fix faulty heading --- bot/resources/tags/dict-get.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/bot/resources/tags/dict-get.md b/bot/resources/tags/dict-get.md index b22db7af5..d9cc6a691 100644 --- a/bot/resources/tags/dict-get.md +++ b/bot/resources/tags/dict-get.md @@ -1,6 +1,8 @@ Often while using dictionaries in Python, you may run into `KeyErrors`. This error is raised when you try to access a key that isn't present in your dictionary.\ -While you can use a `try` and `except` block to catch the `KeyError`, Python also gives you some other neat ways to handle them. +While you can use a `try` and `except` block to catch the `KeyError`, Python also gives you some other neat ways to handle them.\ + __**The `dict.get` method**__ + The [`dict.get`](https://docs.python.org/3/library/stdtypes.html#dict.get) method will return the value for the key if it exists, or None (or a default value that you specify) if the key doesn't exist. Hence it will _never raise_ a KeyError. ```py >>> my_dict = {"foo": 1, "bar": 2} -- cgit v1.2.3 From a6d65fd04e932a8cc860f5e8ab07f05a4a2f51d1 Mon Sep 17 00:00:00 2001 From: Anand Krishna <40204976+anand2312@users.noreply.github.com> Date: Fri, 5 Feb 2021 19:53:49 +0400 Subject: Refer to `defaultdict` tag in `dict-get` --- bot/resources/tags/dict-get.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/resources/tags/dict-get.md b/bot/resources/tags/dict-get.md index d9cc6a691..6f8299dc7 100644 --- a/bot/resources/tags/dict-get.md +++ b/bot/resources/tags/dict-get.md @@ -12,4 +12,4 @@ None 3 ``` -Some other methods that can be used for handling KeyErrors gracefully are the [`dict.setdefault`](https://docs.python.org/3/library/stdtypes.html#dict.setdefault) method, or by using [`collections.defaultdict`](https://docs.python.org/3/library/collections.html#collections.defaultdict). +Some other methods that can be used for handling KeyErrors gracefully are the [`dict.setdefault`](https://docs.python.org/3/library/stdtypes.html#dict.setdefault) method, or by using [`collections.defaultdict`](https://docs.python.org/3/library/collections.html#collections.defaultdict) (check out the `!defaultdict` tag). -- cgit v1.2.3 From c346c2becd2967058a73bc900800afbfb8dbe6d5 Mon Sep 17 00:00:00 2001 From: Senjan21 <53477086+Senjan21@users.noreply.github.com> Date: Fri, 5 Feb 2021 19:12:14 +0100 Subject: Fix #1371 error via adding errors. --- bot/errors.py | 17 ++++++++++++++++- bot/exts/backend/error_handler.py | 4 +++- bot/exts/moderation/infraction/_utils.py | 5 +++++ 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/bot/errors.py b/bot/errors.py index 65d715203..016d9bd17 100644 --- a/bot/errors.py +++ b/bot/errors.py @@ -1,4 +1,5 @@ -from typing import Hashable +from typing import Hashable, Union +from discord import Member, User class LockedResourceError(RuntimeError): @@ -18,3 +19,17 @@ class LockedResourceError(RuntimeError): f"Cannot operate on {self.type.lower()} `{self.id}`; " "it is currently locked and in use by another operation." ) + + +class InvalidInfractedUser(Exception): + """ + Exception raised upon attempt of infracting an invalid user." + + Attributes: + `user` -- User or Member which is invalid + """ + + def __init__(self, user: Union[Member, User], reason: str = "User infracted is a bot."): + self.user = user + + super().__init__(reason) diff --git a/bot/exts/backend/error_handler.py b/bot/exts/backend/error_handler.py index ed7962b06..d2cce5558 100644 --- a/bot/exts/backend/error_handler.py +++ b/bot/exts/backend/error_handler.py @@ -12,7 +12,7 @@ from bot.api import ResponseCodeError from bot.bot import Bot from bot.constants import Colours, ERROR_REPLIES, Icons, MODERATION_ROLES from bot.converters import TagNameConverter -from bot.errors import LockedResourceError +from bot.errors import InvalidInfractedUser, LockedResourceError from bot.exts.backend.branding._errors import BrandingError from bot.utils.checks import InWhitelistCheckFailure @@ -82,6 +82,8 @@ class ErrorHandler(Cog): elif isinstance(e.original, BrandingError): await ctx.send(embed=self._get_error_embed(random.choice(ERROR_REPLIES), str(e.original))) return + elif isinstance(e.original, InvalidInfractedUser): + await ctx.send(f"Cannot infract that user. {e.original.reason}") else: await self.handle_unexpected_error(ctx, e.original) return # Exit early to avoid logging. diff --git a/bot/exts/moderation/infraction/_utils.py b/bot/exts/moderation/infraction/_utils.py index d0dc3f0a1..e766c1e5c 100644 --- a/bot/exts/moderation/infraction/_utils.py +++ b/bot/exts/moderation/infraction/_utils.py @@ -7,6 +7,7 @@ from discord.ext.commands import Context from bot.api import ResponseCodeError from bot.constants import Colours, Icons +from bot.errors import InvalidInfractedUser log = logging.getLogger(__name__) @@ -79,6 +80,10 @@ async def post_infraction( active: bool = True ) -> t.Optional[dict]: """Posts an infraction to the API.""" + if isinstance(user, (discord.Member, discord.User)) and user.bot: + log.trace(f"Posting of {infr_type} infraction for {user} to the API aborted. User is a bot.") + raise InvalidInfractedUser(user) + log.trace(f"Posting {infr_type} infraction for {user} to the API.") payload = { -- cgit v1.2.3 From 4f1f45652ab980502098b98e5534d64f810b4b53 Mon Sep 17 00:00:00 2001 From: Senjan21 <53477086+Senjan21@users.noreply.github.com> Date: Fri, 5 Feb 2021 19:19:02 +0100 Subject: Linting fix. --- bot/errors.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bot/errors.py b/bot/errors.py index 016d9bd17..a6fc33312 100644 --- a/bot/errors.py +++ b/bot/errors.py @@ -1,4 +1,5 @@ from typing import Hashable, Union + from discord import Member, User @@ -23,7 +24,7 @@ class LockedResourceError(RuntimeError): class InvalidInfractedUser(Exception): """ - Exception raised upon attempt of infracting an invalid user." + Exception raised upon attempt of infracting an invalid user. Attributes: `user` -- User or Member which is invalid -- cgit v1.2.3 From 1a9d820638acce176f73867b6b321c8c1dbfb479 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 6 Feb 2021 13:38:39 +0200 Subject: Ignore attachment-only messages for duplicates antispam rule --- bot/rules/duplicates.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bot/rules/duplicates.py b/bot/rules/duplicates.py index 455764b53..23aefd3dc 100644 --- a/bot/rules/duplicates.py +++ b/bot/rules/duplicates.py @@ -13,6 +13,7 @@ async def apply( if ( msg.author == last_message.author and msg.content == last_message.content + and (msg.content and not msg.attachments) ) ) -- cgit v1.2.3 From 84a46c9ab27f0a593c413f5ee09ba19cf5fb1d1b Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 6 Feb 2021 13:45:07 +0200 Subject: Lower max attachments per 10 seconds to 3 --- config-default.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config-default.yml b/config-default.yml index d3b267159..d323a946d 100644 --- a/config-default.yml +++ b/config-default.yml @@ -367,7 +367,7 @@ anti_spam: rules: attachments: interval: 10 - max: 9 + max: 3 burst: interval: 10 -- cgit v1.2.3 From 174f70e216e327e30a9df6902619944f47eea5ad Mon Sep 17 00:00:00 2001 From: Senjan21 <53477086+Senjan21@users.noreply.github.com> Date: Sat, 6 Feb 2021 18:10:17 +0100 Subject: add reason attribute --- bot/errors.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bot/errors.py b/bot/errors.py index a6fc33312..ab0adcd42 100644 --- a/bot/errors.py +++ b/bot/errors.py @@ -32,5 +32,6 @@ class InvalidInfractedUser(Exception): def __init__(self, user: Union[Member, User], reason: str = "User infracted is a bot."): self.user = user + self.reason = reason super().__init__(reason) -- cgit v1.2.3 From 255f2215279d08386152b12dc8adec037538cba7 Mon Sep 17 00:00:00 2001 From: Anand Krishna <40204976+anand2312@users.noreply.github.com> Date: Sat, 6 Feb 2021 21:16:23 +0400 Subject: Reword comment in example --- bot/resources/tags/dict-get.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/resources/tags/dict-get.md b/bot/resources/tags/dict-get.md index 6f8299dc7..7657f420a 100644 --- a/bot/resources/tags/dict-get.md +++ b/bot/resources/tags/dict-get.md @@ -1,5 +1,5 @@ Often while using dictionaries in Python, you may run into `KeyErrors`. This error is raised when you try to access a key that isn't present in your dictionary.\ -While you can use a `try` and `except` block to catch the `KeyError`, Python also gives you some other neat ways to handle them.\ +While you can use a `try` and `except` block to catch the `KeyError`, Python also gives you some other neat ways to handle them. __**The `dict.get` method**__ @@ -8,7 +8,7 @@ The [`dict.get`](https://docs.python.org/3/library/stdtypes.html#dict.get) metho >>> my_dict = {"foo": 1, "bar": 2} >>> print(my_dict.get("foobar")) None ->>> print(my_dict.get("foobar", 3)) # here 3 is the default value to be returned, in case the key doesn't exist +>>> print(my_dict.get("foobar", 3)) # here 3 is the default value to be returned, because the key doesn't exist 3 ``` -- cgit v1.2.3 From 9d8162a688023a3b5e830057b09c2ab2e132582f Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Wed, 10 Feb 2021 01:07:43 +0000 Subject: Migrate API utilities to use internal DNS routing --- bot/api.py | 2 +- bot/constants.py | 1 + config-default.yml | 3 ++- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/bot/api.py b/bot/api.py index d93f9f2ba..6ce9481f4 100644 --- a/bot/api.py +++ b/bot/api.py @@ -53,7 +53,7 @@ class APIClient: @staticmethod def _url_for(endpoint: str) -> str: - return f"{URLs.site_schema}{URLs.site_api}/{quote_url(endpoint)}" + return f"{URLs.site_api_schema}{URLs.site_api}/{quote_url(endpoint)}" async def close(self) -> None: """Close the aiohttp session.""" diff --git a/bot/constants.py b/bot/constants.py index 95e22513f..91e41e334 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -530,6 +530,7 @@ class URLs(metaclass=YAMLGetter): site: str site_api: str site_schema: str + site_api_schema: str # Site endpoints site_logs_view: str diff --git a/config-default.yml b/config-default.yml index d3b267159..c585151c9 100644 --- a/config-default.yml +++ b/config-default.yml @@ -335,9 +335,10 @@ keys: urls: # PyDis site vars site: &DOMAIN "pythondiscord.com" - site_api: &API !JOIN ["api.", *DOMAIN] + site_api: &API "pydis-api.default.svc.cluster.local" site_paste: &PASTE !JOIN ["paste.", *DOMAIN] site_schema: &SCHEMA "https://" + site_api_schema: "http://" site_staff: &STAFF !JOIN ["staff.", *DOMAIN] paste_service: !JOIN [*SCHEMA, *PASTE, "/{key}"] -- cgit v1.2.3 From 578a0e48514fd9f902cde45db557fa1f3425c289 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Wed, 10 Feb 2021 01:07:54 +0000 Subject: Migrate ping command to ping internal API --- bot/exts/utils/ping.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/utils/ping.py b/bot/exts/utils/ping.py index 572fc934b..e62811b91 100644 --- a/bot/exts/utils/ping.py +++ b/bot/exts/utils/ping.py @@ -37,7 +37,7 @@ class Latency(commands.Cog): bot_ping = f"{bot_ping:.{ROUND_LATENCY}f} ms" try: - delay = await aioping.ping(URLs.site, family=socket.AddressFamily.AF_INET) * 1000 + delay = await aioping.ping(URLs.site_api, family=socket.AddressFamily.AF_INET) * 1000 site_ping = f"{delay:.{ROUND_LATENCY}f} ms" except TimeoutError: -- cgit v1.2.3 From 9111f9f247fb1292add29929c660e9633e4f31da Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Wed, 10 Feb 2021 01:57:00 +0000 Subject: Alphabetical sorting in config-default.yml --- config-default.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config-default.yml b/config-default.yml index c585151c9..d7415c821 100644 --- a/config-default.yml +++ b/config-default.yml @@ -336,9 +336,9 @@ urls: # PyDis site vars site: &DOMAIN "pythondiscord.com" site_api: &API "pydis-api.default.svc.cluster.local" + site_api_schema: "http://" site_paste: &PASTE !JOIN ["paste.", *DOMAIN] site_schema: &SCHEMA "https://" - site_api_schema: "http://" site_staff: &STAFF !JOIN ["staff.", *DOMAIN] paste_service: !JOIN [*SCHEMA, *PASTE, "/{key}"] -- cgit v1.2.3 From bafa6a9dbf61ae30ef235537408f0b073a88dd19 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Wed, 10 Feb 2021 02:13:42 +0000 Subject: ICMP is disabled in production, so we can't ping the API --- bot/exts/utils/ping.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/utils/ping.py b/bot/exts/utils/ping.py index e62811b91..572fc934b 100644 --- a/bot/exts/utils/ping.py +++ b/bot/exts/utils/ping.py @@ -37,7 +37,7 @@ class Latency(commands.Cog): bot_ping = f"{bot_ping:.{ROUND_LATENCY}f} ms" try: - delay = await aioping.ping(URLs.site_api, family=socket.AddressFamily.AF_INET) * 1000 + delay = await aioping.ping(URLs.site, family=socket.AddressFamily.AF_INET) * 1000 site_ping = f"{delay:.{ROUND_LATENCY}f} ms" except TimeoutError: -- cgit v1.2.3 From ea35aa9c77a81f46ea14acf36862c42f3ffe9016 Mon Sep 17 00:00:00 2001 From: Anand Krishna <40204976+anand2312@users.noreply.github.com> Date: Thu, 11 Feb 2021 09:37:33 +0400 Subject: Split example codeblock in two --- bot/resources/tags/dict-get.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/bot/resources/tags/dict-get.md b/bot/resources/tags/dict-get.md index 7657f420a..867f0b7d9 100644 --- a/bot/resources/tags/dict-get.md +++ b/bot/resources/tags/dict-get.md @@ -1,15 +1,17 @@ Often while using dictionaries in Python, you may run into `KeyErrors`. This error is raised when you try to access a key that isn't present in your dictionary.\ While you can use a `try` and `except` block to catch the `KeyError`, Python also gives you some other neat ways to handle them. -__**The `dict.get` method**__ +**The `dict.get` method** -The [`dict.get`](https://docs.python.org/3/library/stdtypes.html#dict.get) method will return the value for the key if it exists, or None (or a default value that you specify) if the key doesn't exist. Hence it will _never raise_ a KeyError. +The [`dict.get`](https://docs.python.org/3/library/stdtypes.html#dict.get) method will return the value for the key if it exists, and None (or a default value that you specify) if the key doesn't exist. Hence it will _never raise_ a KeyError. ```py >>> my_dict = {"foo": 1, "bar": 2} >>> print(my_dict.get("foobar")) None ->>> print(my_dict.get("foobar", 3)) # here 3 is the default value to be returned, because the key doesn't exist +``` +Below, 3 is the default value to be returned, because the key doesn't exist- +```py +>>> print(my_dict.get("foobar", 3)) 3 ``` - -Some other methods that can be used for handling KeyErrors gracefully are the [`dict.setdefault`](https://docs.python.org/3/library/stdtypes.html#dict.setdefault) method, or by using [`collections.defaultdict`](https://docs.python.org/3/library/collections.html#collections.defaultdict) (check out the `!defaultdict` tag). +Some other methods for handling `KeyError`s gracefully are the [`dict.setdefault`](https://docs.python.org/3/library/stdtypes.html#dict.setdefault) method and [`collections.defaultdict`](https://docs.python.org/3/library/collections.html#collections.defaultdict) (check out the `!defaultdict` tag). -- cgit v1.2.3 From a3749786c3ff90397427032ef219b590ee4e2837 Mon Sep 17 00:00:00 2001 From: Anand Krishna <40204976+anand2312@users.noreply.github.com> Date: Thu, 11 Feb 2021 10:20:06 +0400 Subject: Remove reference to `try - except` --- bot/resources/tags/dict-get.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/bot/resources/tags/dict-get.md b/bot/resources/tags/dict-get.md index 867f0b7d9..e02df03ab 100644 --- a/bot/resources/tags/dict-get.md +++ b/bot/resources/tags/dict-get.md @@ -1,5 +1,4 @@ -Often while using dictionaries in Python, you may run into `KeyErrors`. This error is raised when you try to access a key that isn't present in your dictionary.\ -While you can use a `try` and `except` block to catch the `KeyError`, Python also gives you some other neat ways to handle them. +Often while using dictionaries in Python, you may run into `KeyErrors`. This error is raised when you try to access a key that isn't present in your dictionary. Python gives you some neat ways to handle them. **The `dict.get` method** -- cgit v1.2.3 From 84c0aa4268f91027cd71016e01a00ffe59151cc2 Mon Sep 17 00:00:00 2001 From: xithrius Date: Thu, 11 Feb 2021 02:40:42 -0800 Subject: Added base of the pypi command. --- bot/exts/info/pypi.py | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 bot/exts/info/pypi.py diff --git a/bot/exts/info/pypi.py b/bot/exts/info/pypi.py new file mode 100644 index 000000000..9567516c2 --- /dev/null +++ b/bot/exts/info/pypi.py @@ -0,0 +1,35 @@ +from discord import Embed +from discord.ext.commands import Cog, Context, command + +from bot.bot import Bot +from bot.constants import NEGATIVE_REPLIES + +URL = "https://pypi.org/pypi/{package}/json" + + +class PyPi(Cog): + """Cog for getting information about PyPi packages.""" + + def __init__(self, bot: Bot): + self.bot = bot + + @command(name="pypi", aliases=("package", "pack")) + async def get_package_info(self, ctx: Context, package: str) -> None: + """Getting information about a specific package.""" + embed = Embed(title="PyPi package information") + + async with self.bot.http_session.get(URL.format(package_name=package)) as response: + if response.status == 404: + return await ctx.send(f"Package with name '{package}' could not be found.") + elif response.status == 200 and response.content_type == "application/json": + response_json = await response.json() + info = response_json["info"] + else: + return await ctx.send("There was an error when fetching your PyPi package.") + + await ctx.send(embed=embed) + + +def setup(bot: Bot) -> None: + """Load the PyPi cog.""" + bot.add_cog(PyPi(bot)) -- cgit v1.2.3 From 1610f330fbc583df2c161629b7d8d72b77b9253d Mon Sep 17 00:00:00 2001 From: xithrius Date: Thu, 11 Feb 2021 03:49:59 -0800 Subject: Added more fields and responses. --- bot/exts/info/pypi.py | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-) diff --git a/bot/exts/info/pypi.py b/bot/exts/info/pypi.py index 9567516c2..e4c90090d 100644 --- a/bot/exts/info/pypi.py +++ b/bot/exts/info/pypi.py @@ -1,10 +1,16 @@ +import logging +from random import choice + from discord import Embed from discord.ext.commands import Cog, Context, command from bot.bot import Bot -from bot.constants import NEGATIVE_REPLIES +from bot.constants import NEGATIVE_REPLIES, Colours URL = "https://pypi.org/pypi/{package}/json" +FIELDS = ["author", "requires_python", "description", "license"] + +log = logging.getLogger(__name__) class PyPi(Cog): @@ -16,16 +22,30 @@ class PyPi(Cog): @command(name="pypi", aliases=("package", "pack")) async def get_package_info(self, ctx: Context, package: str) -> None: """Getting information about a specific package.""" - embed = Embed(title="PyPi package information") + embed = Embed(title=choice(NEGATIVE_REPLIES), colour=Colours.soft_red) - async with self.bot.http_session.get(URL.format(package_name=package)) as response: + async with self.bot.http_session.get(URL.format(package=package)) as response: if response.status == 404: - return await ctx.send(f"Package with name '{package}' could not be found.") + embed.description = f"Package could not be found." + elif response.status == 200 and response.content_type == "application/json": response_json = await response.json() info = response_json["info"] + + embed.title = "Python Package Index" + embed.colour = Colours.soft_green + embed.description = f"[{info['name']} v{info['version']}]({info['download_url']})\n" + + for field in FIELDS: + embed.add_field( + name=field.replace("_", " ").title(), + value=info[field], + inline=False, + ) + else: - return await ctx.send("There was an error when fetching your PyPi package.") + embed.description = "There was an error when fetching your PyPi package." + log.trace(f"Error when fetching PyPi package: {response.status}.") await ctx.send(embed=embed) -- cgit v1.2.3 From ded34bc8ab063064fbd50199d07bbeec1db884ad Mon Sep 17 00:00:00 2001 From: xithrius Date: Thu, 11 Feb 2021 03:54:40 -0800 Subject: Made flake8 very happy. --- bot/exts/info/pypi.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/exts/info/pypi.py b/bot/exts/info/pypi.py index e4c90090d..544b52b49 100644 --- a/bot/exts/info/pypi.py +++ b/bot/exts/info/pypi.py @@ -5,7 +5,7 @@ from discord import Embed from discord.ext.commands import Cog, Context, command from bot.bot import Bot -from bot.constants import NEGATIVE_REPLIES, Colours +from bot.constants import Colours, NEGATIVE_REPLIES URL = "https://pypi.org/pypi/{package}/json" FIELDS = ["author", "requires_python", "description", "license"] @@ -26,7 +26,7 @@ class PyPi(Cog): async with self.bot.http_session.get(URL.format(package=package)) as response: if response.status == 404: - embed.description = f"Package could not be found." + embed.description = "Package could not be found." elif response.status == 200 and response.content_type == "application/json": response_json = await response.json() -- cgit v1.2.3 From ed7fde738db677ced25388a53ed9bd539f4490fb Mon Sep 17 00:00:00 2001 From: xithrius Date: Fri, 12 Feb 2021 00:14:48 -0800 Subject: Empty fields have been accounted for by getting usually non-empty ones. --- bot/exts/info/pypi.py | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/bot/exts/info/pypi.py b/bot/exts/info/pypi.py index 544b52b49..7a5d7f4b7 100644 --- a/bot/exts/info/pypi.py +++ b/bot/exts/info/pypi.py @@ -8,7 +8,7 @@ from bot.bot import Bot from bot.constants import Colours, NEGATIVE_REPLIES URL = "https://pypi.org/pypi/{package}/json" -FIELDS = ["author", "requires_python", "description", "license"] +FIELDS = ["author", "requires_python", "summary", "license"] log = logging.getLogger(__name__) @@ -34,14 +34,15 @@ class PyPi(Cog): embed.title = "Python Package Index" embed.colour = Colours.soft_green - embed.description = f"[{info['name']} v{info['version']}]({info['download_url']})\n" + embed.description = f"[{info['name']} v{info['version']}]({info['package_url']})\n" for field in FIELDS: - embed.add_field( - name=field.replace("_", " ").title(), - value=info[field], - inline=False, - ) + if field_value := info[field]: + embed.add_field( + name=field.replace("_", " ").title(), + value=field_value, + inline=False, + ) else: embed.description = "There was an error when fetching your PyPi package." -- cgit v1.2.3 From 2a9f349429694d48cca86af972ef327a57af552d Mon Sep 17 00:00:00 2001 From: xithrius Date: Fri, 12 Feb 2021 00:20:51 -0800 Subject: Accounting for completely empty fields that only contain whitespaces. --- bot/exts/info/pypi.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bot/exts/info/pypi.py b/bot/exts/info/pypi.py index 7a5d7f4b7..990a5c905 100644 --- a/bot/exts/info/pypi.py +++ b/bot/exts/info/pypi.py @@ -37,7 +37,8 @@ class PyPi(Cog): embed.description = f"[{info['name']} v{info['version']}]({info['package_url']})\n" for field in FIELDS: - if field_value := info[field]: + # Field could be completely empty, in some cases can be a string with whitespaces. + if field_value := info[field].strip(): embed.add_field( name=field.replace("_", " ").title(), value=field_value, -- cgit v1.2.3 From 889de9b678a044331f02eef647c7d1c963f37edd Mon Sep 17 00:00:00 2001 From: xithrius Date: Fri, 12 Feb 2021 00:49:27 -0800 Subject: Finalized logic to account for null cases. --- bot/exts/info/pypi.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/bot/exts/info/pypi.py b/bot/exts/info/pypi.py index 990a5c905..4ad72b673 100644 --- a/bot/exts/info/pypi.py +++ b/bot/exts/info/pypi.py @@ -37,11 +37,11 @@ class PyPi(Cog): embed.description = f"[{info['name']} v{info['version']}]({info['package_url']})\n" for field in FIELDS: - # Field could be completely empty, in some cases can be a string with whitespaces. - if field_value := info[field].strip(): + # Field could be completely empty, in some cases can be a string with whitespaces, or None. + if info[field] and not info[field].isspace(): embed.add_field( name=field.replace("_", " ").title(), - value=field_value, + value=info[field], inline=False, ) -- cgit v1.2.3 From bcab6614bba3ca71edeb134089846570e0e47547 Mon Sep 17 00:00:00 2001 From: xithrius Date: Fri, 12 Feb 2021 01:22:12 -0800 Subject: Moved hyperlink to title. --- bot/exts/info/pypi.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bot/exts/info/pypi.py b/bot/exts/info/pypi.py index 4ad72b673..c7ec22fc6 100644 --- a/bot/exts/info/pypi.py +++ b/bot/exts/info/pypi.py @@ -32,9 +32,9 @@ class PyPi(Cog): response_json = await response.json() info = response_json["info"] - embed.title = "Python Package Index" + embed.title = f"{info['name']} v{info['version']}" + embed.url = info['package_url'] embed.colour = Colours.soft_green - embed.description = f"[{info['name']} v{info['version']}]({info['package_url']})\n" for field in FIELDS: # Field could be completely empty, in some cases can be a string with whitespaces, or None. -- cgit v1.2.3 From 94ad4dd207226d7d1a2b080ffe47352e7c2b9e73 Mon Sep 17 00:00:00 2001 From: Xithrius <15021300+Xithrius@users.noreply.github.com> Date: Fri, 12 Feb 2021 02:09:17 -0800 Subject: Made docstring more specific. Co-authored-by: Shivansh-007 <69356296+Shivansh-007@users.noreply.github.com> --- bot/exts/info/pypi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/info/pypi.py b/bot/exts/info/pypi.py index c7ec22fc6..79931c665 100644 --- a/bot/exts/info/pypi.py +++ b/bot/exts/info/pypi.py @@ -21,7 +21,7 @@ class PyPi(Cog): @command(name="pypi", aliases=("package", "pack")) async def get_package_info(self, ctx: Context, package: str) -> None: - """Getting information about a specific package.""" + """Provide information about a specific package from PyPI.""" embed = Embed(title=choice(NEGATIVE_REPLIES), colour=Colours.soft_red) async with self.bot.http_session.get(URL.format(package=package)) as response: -- cgit v1.2.3 From 9ce9ab617ba0fdacb1922e2ed2007ed05e53c526 Mon Sep 17 00:00:00 2001 From: xithrius Date: Fri, 12 Feb 2021 13:10:25 -0800 Subject: Added colours yellow, blue, and white. --- bot/constants.py | 9 ++++++--- config-default.yml | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/bot/constants.py b/bot/constants.py index 91e41e334..8a93ff9cf 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -246,13 +246,16 @@ class Colours(metaclass=YAMLGetter): section = "style" subsection = "colours" + blue: int bright_green: int - soft_green: int - soft_orange: int - soft_red: int orange: int pink: int purple: int + soft_green: int + soft_orange: int + soft_red: int + white: int + yellow: int class DuckPond(metaclass=YAMLGetter): diff --git a/config-default.yml b/config-default.yml index d7415c821..25bbcc3c5 100644 --- a/config-default.yml +++ b/config-default.yml @@ -24,13 +24,16 @@ bot: style: colours: + blue: 0x3775a8 bright_green: 0x01d277 - soft_green: 0x68c290 - soft_orange: 0xf9cb54 - soft_red: 0xcd6d6d orange: 0xe67e22 pink: 0xcf84e0 purple: 0xb734eb + soft_green: 0x68c290 + soft_orange: 0xf9cb54 + soft_red: 0xcd6d6d + white: 0xfffffe + yellow: 0xffd241 emojis: badge_bug_hunter: "<:bug_hunter_lvl1:743882896372269137>" -- cgit v1.2.3 From aa0b60534d1b8cef2e34bbaf50709553c71a14ff Mon Sep 17 00:00:00 2001 From: xithrius Date: Fri, 12 Feb 2021 13:12:24 -0800 Subject: Rotating colours in embed, title now links to package. --- bot/exts/info/pypi.py | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/bot/exts/info/pypi.py b/bot/exts/info/pypi.py index c7ec22fc6..c7d4d321c 100644 --- a/bot/exts/info/pypi.py +++ b/bot/exts/info/pypi.py @@ -1,5 +1,6 @@ +import itertools import logging -from random import choice +import random from discord import Embed from discord.ext.commands import Cog, Context, command @@ -8,7 +9,9 @@ from bot.bot import Bot from bot.constants import Colours, NEGATIVE_REPLIES URL = "https://pypi.org/pypi/{package}/json" -FIELDS = ["author", "requires_python", "summary", "license"] +FIELDS = ("author", "requires_python", "summary", "license") +PYPI_ICON = "https://cdn.discordapp.com/emojis/766274397257334814.png" +PYPI_COLOURS = itertools.cycle((Colours.yellow, Colours.blue, Colours.white)) log = logging.getLogger(__name__) @@ -21,8 +24,12 @@ class PyPi(Cog): @command(name="pypi", aliases=("package", "pack")) async def get_package_info(self, ctx: Context, package: str) -> None: - """Getting information about a specific package.""" - embed = Embed(title=choice(NEGATIVE_REPLIES), colour=Colours.soft_red) + """Provide information about a specific package from PyPI.""" + embed = Embed( + title=random.choice(NEGATIVE_REPLIES), + colour=Colours.soft_red + ) + embed.set_thumbnail(url=PYPI_ICON) async with self.bot.http_session.get(URL.format(package=package)) as response: if response.status == 404: @@ -34,7 +41,7 @@ class PyPi(Cog): embed.title = f"{info['name']} v{info['version']}" embed.url = info['package_url'] - embed.colour = Colours.soft_green + embed.colour = next(PYPI_COLOURS) for field in FIELDS: # Field could be completely empty, in some cases can be a string with whitespaces, or None. -- cgit v1.2.3 From 059940b5ae3cc2921303579ebf161835fe09076d Mon Sep 17 00:00:00 2001 From: xithrius Date: Fri, 12 Feb 2021 15:47:06 -0800 Subject: Taking only the first line of multiline fields. --- bot/exts/info/pypi.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/bot/exts/info/pypi.py b/bot/exts/info/pypi.py index c7d4d321c..cf45b068f 100644 --- a/bot/exts/info/pypi.py +++ b/bot/exts/info/pypi.py @@ -44,11 +44,16 @@ class PyPi(Cog): embed.colour = next(PYPI_COLOURS) for field in FIELDS: + field_data = info[field] + # Field could be completely empty, in some cases can be a string with whitespaces, or None. - if info[field] and not info[field].isspace(): + if field_data and not field_data.isspace(): + if '\n' in field_data and field == "license": + field_data = field_data.split('\n')[0] + embed.add_field( name=field.replace("_", " ").title(), - value=info[field], + value=field_data, inline=False, ) -- cgit v1.2.3 From 8fcb4c6ee7718143c949aa41627064635b2b364b Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 13 Feb 2021 08:24:04 +0200 Subject: Move Git SHA defining at end of Dockerfile to re-enable caching Defining SHA at the beginning of build breaks caching, so this should be avoided. --- Dockerfile | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/Dockerfile b/Dockerfile index 5d0380b44..994b8ee49 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,14 +1,10 @@ FROM python:3.8-slim -# Define Git SHA build argument -ARG git_sha="development" - # Set pip to have cleaner logs and no saved cache ENV PIP_NO_CACHE_DIR=false \ PIPENV_HIDE_EMOJIS=1 \ PIPENV_IGNORE_VIRTUALENVS=1 \ - PIPENV_NOSPIN=1 \ - GIT_SHA=$git_sha + PIPENV_NOSPIN=1 RUN apt-get -y update \ && apt-get install -y \ @@ -25,6 +21,12 @@ WORKDIR /bot COPY Pipfile* ./ RUN pipenv install --system --deploy +# Define Git SHA build argument +ARG git_sha="development" + +# Set Git SHA environment variable here to enable caching +ENV GIT_SHA=$git_sha + # Copy the source code in last to optimize rebuilding the image COPY . . -- cgit v1.2.3 From 88b5b32696c876ee0aa5299eb78bb0d775c5b800 Mon Sep 17 00:00:00 2001 From: xithrius Date: Sat, 13 Feb 2021 00:25:09 -0800 Subject: Escaping markdown in all fields that are created. --- bot/exts/info/pypi.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/bot/exts/info/pypi.py b/bot/exts/info/pypi.py index cf45b068f..73ec31870 100644 --- a/bot/exts/info/pypi.py +++ b/bot/exts/info/pypi.py @@ -7,6 +7,7 @@ from discord.ext.commands import Cog, Context, command from bot.bot import Bot from bot.constants import Colours, NEGATIVE_REPLIES +from discord.utils import escape_markdown URL = "https://pypi.org/pypi/{package}/json" FIELDS = ("author", "requires_python", "summary", "license") @@ -53,7 +54,7 @@ class PyPi(Cog): embed.add_field( name=field.replace("_", " ").title(), - value=field_data, + value=escape_markdown(field_data), inline=False, ) -- cgit v1.2.3 From f14c391e3a1228953cda29be7993c9a5ec51ca6f Mon Sep 17 00:00:00 2001 From: xithrius Date: Sat, 13 Feb 2021 00:34:33 -0800 Subject: Made flake8 even happier. --- bot/exts/info/pypi.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/info/pypi.py b/bot/exts/info/pypi.py index 73ec31870..3e326e8bb 100644 --- a/bot/exts/info/pypi.py +++ b/bot/exts/info/pypi.py @@ -4,10 +4,10 @@ import random from discord import Embed from discord.ext.commands import Cog, Context, command +from discord.utils import escape_markdown from bot.bot import Bot from bot.constants import Colours, NEGATIVE_REPLIES -from discord.utils import escape_markdown URL = "https://pypi.org/pypi/{package}/json" FIELDS = ("author", "requires_python", "summary", "license") -- cgit v1.2.3 From 55f7e7085fe821b4af7e59e811148808a3a40738 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sun, 14 Feb 2021 22:06:44 +0000 Subject: Update Dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 994b8ee49..1a75e5669 100644 --- a/Dockerfile +++ b/Dockerfile @@ -24,7 +24,7 @@ RUN pipenv install --system --deploy # Define Git SHA build argument ARG git_sha="development" -# Set Git SHA environment variable here to enable caching +# Set Git SHA environment variable for Sentry ENV GIT_SHA=$git_sha # Copy the source code in last to optimize rebuilding the image -- cgit v1.2.3 From aa5e39c3866a9100fda242221106bf6d2caae38c Mon Sep 17 00:00:00 2001 From: Senjan21 <53477086+Senjan21@users.noreply.github.com> Date: Fri, 19 Feb 2021 10:07:35 +0100 Subject: Delete free.md Reasoning behind this is it is rarely used and when its used its often just to test something or as an attempt to close a help channel. --- bot/resources/tags/free.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 bot/resources/tags/free.md diff --git a/bot/resources/tags/free.md b/bot/resources/tags/free.md deleted file mode 100644 index 1493076c7..000000000 --- a/bot/resources/tags/free.md +++ /dev/null @@ -1,5 +0,0 @@ -**We have a new help channel system!** - -Please see <#704250143020417084> for further information. - -A more detailed guide can be found on [our website](https://pythondiscord.com/pages/resources/guides/help-channels/). -- cgit v1.2.3 From 0f4365e2430d40f17ab9a545d3e8614a4b3a9669 Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 20 Feb 2021 11:54:52 +0200 Subject: Remove attachments check in duplicates filter --- bot/rules/duplicates.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/rules/duplicates.py b/bot/rules/duplicates.py index 23aefd3dc..8e4fbc12d 100644 --- a/bot/rules/duplicates.py +++ b/bot/rules/duplicates.py @@ -13,7 +13,7 @@ async def apply( if ( msg.author == last_message.author and msg.content == last_message.content - and (msg.content and not msg.attachments) + and msg.content ) ) -- cgit v1.2.3 From 7f980be37a572f1998160ce6a2221504e414d285 Mon Sep 17 00:00:00 2001 From: Boris Muratov <8bee278@gmail.com> Date: Sat, 20 Feb 2021 11:55:09 +0200 Subject: Update CODEOWNERS --- .github/CODEOWNERS | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index ad813d893..7217cb443 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -7,11 +7,15 @@ bot/exts/utils/extensions.py @MarkKoz bot/exts/utils/snekbox.py @MarkKoz @Akarys42 bot/exts/help_channels/** @MarkKoz @Akarys42 bot/exts/moderation/** @Akarys42 @mbaruh @Den4200 @ks129 -bot/exts/info/** @Akarys42 @mbaruh @Den4200 +bot/exts/info/** @Akarys42 @Den4200 +bot/exts/info/information.py @mbaruh bot/exts/filters/** @mbaruh bot/exts/fun/** @ks129 bot/exts/utils/** @ks129 +# Rules +bot/rules/** @mbaruh + # Utils bot/utils/extensions.py @MarkKoz bot/utils/function.py @MarkKoz -- cgit v1.2.3 From e3b980e53c13fd5dcaf51408f97c99b629c1a6ec Mon Sep 17 00:00:00 2001 From: ks129 <45097959+ks129@users.noreply.github.com> Date: Sat, 20 Feb 2021 11:55:26 +0200 Subject: Set max attachment from 3 -> 6 --- config-default.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config-default.yml b/config-default.yml index d323a946d..e9dce7845 100644 --- a/config-default.yml +++ b/config-default.yml @@ -367,7 +367,7 @@ anti_spam: rules: attachments: interval: 10 - max: 3 + max: 6 burst: interval: 10 -- cgit v1.2.3 From 93c3327414dabd12236e47210be2be1151b71719 Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Sun, 21 Feb 2021 13:50:37 +0100 Subject: Show the last three characters of censored tokens --- bot/exts/filters/token_remover.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/filters/token_remover.py b/bot/exts/filters/token_remover.py index bd6a1f97a..33b39cc2d 100644 --- a/bot/exts/filters/token_remover.py +++ b/bot/exts/filters/token_remover.py @@ -147,7 +147,7 @@ class TokenRemover(Cog): channel=msg.channel.mention, user_id=token.user_id, timestamp=token.timestamp, - hmac='x' * len(token.hmac), + hmac='x' * (len(token.hmac) - 3) + token.hmac[-3:], ) @classmethod -- cgit v1.2.3 From 04e233685e163d1e513a21acd236c2385536b0b7 Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Sun, 21 Feb 2021 13:51:57 +0100 Subject: Ping the mods if a token present in the server is found no matter the kind --- bot/exts/filters/token_remover.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/filters/token_remover.py b/bot/exts/filters/token_remover.py index 33b39cc2d..93f1f3c33 100644 --- a/bot/exts/filters/token_remover.py +++ b/bot/exts/filters/token_remover.py @@ -135,7 +135,7 @@ class TokenRemover(Cog): user_id=user_id, user_name=str(user), kind="BOT" if user.bot else "USER", - ), not user.bot + ), True else: return UNKNOWN_USER_LOG_MESSAGE.format(user_id=user_id), False -- cgit v1.2.3 From 27e60e94bd1fe6784c2b7674433bb175255fa217 Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Sun, 21 Feb 2021 14:06:54 +0100 Subject: Update token remover unittests --- tests/bot/exts/filters/test_token_remover.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/bot/exts/filters/test_token_remover.py b/tests/bot/exts/filters/test_token_remover.py index f99cc3370..51feae9cb 100644 --- a/tests/bot/exts/filters/test_token_remover.py +++ b/tests/bot/exts/filters/test_token_remover.py @@ -291,7 +291,7 @@ class TokenRemoverTests(unittest.IsolatedAsyncioTestCase): channel=self.msg.channel.mention, user_id=token.user_id, timestamp=token.timestamp, - hmac="x" * len(token.hmac), + hmac="xxxxxxxxxxxxxxxxxxxxxxxxjf4", ) @autospec("bot.exts.filters.token_remover", "UNKNOWN_USER_LOG_MESSAGE") @@ -318,7 +318,7 @@ class TokenRemoverTests(unittest.IsolatedAsyncioTestCase): return_value = TokenRemover.format_userid_log_message(msg, token) - self.assertEqual(return_value, (known_user_log_message.format.return_value, False)) + self.assertEqual(return_value, (known_user_log_message.format.return_value, True)) known_user_log_message.format.assert_called_once_with( user_id=472265943062413332, -- cgit v1.2.3 From 584ed52c7107c7d3e3b838ee1e8df3a22ae95e35 Mon Sep 17 00:00:00 2001 From: Joe Banks Date: Sun, 21 Feb 2021 23:07:38 +0000 Subject: Update max available channels to 3 Partially resolves #1427 --- config-default.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config-default.yml b/config-default.yml index beaf89f2c..8e9a29a51 100644 --- a/config-default.yml +++ b/config-default.yml @@ -470,7 +470,7 @@ help_channels: deleted_idle_minutes: 5 # Maximum number of channels to put in the available category - max_available: 2 + max_available: 3 # Maximum number of channels across all 3 categories # Note Discord has a hard limit of 50 channels per category, so this shouldn't be > 50 -- cgit v1.2.3 From 0b11d7dfb408f4e5fe6248ae8377ddc7aa1aa5ee Mon Sep 17 00:00:00 2001 From: Gustav Odinger <65498475+gustavwilliam@users.noreply.github.com> Date: Tue, 23 Feb 2021 03:48:35 +0100 Subject: Add truncate_message util --- bot/utils/messages.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/bot/utils/messages.py b/bot/utils/messages.py index 077dd9569..c01fa5d0e 100644 --- a/bot/utils/messages.py +++ b/bot/utils/messages.py @@ -154,3 +154,12 @@ async def send_denial(ctx: Context, reason: str) -> None: def format_user(user: discord.abc.User) -> str: """Return a string for `user` which has their mention and ID.""" return f"{user.mention} (`{user.id}`)" + + +def truncate_message(message: discord.Message, limit: int) -> str: + """Returns a truncated version of the message content, up to the specified limit.""" + text = message.content + if len(text) > limit: + return text[:limit-3] + "..." + else: + return text -- cgit v1.2.3 From e1d269d82eed8a01d3d3b0ff33d05e3c79324007 Mon Sep 17 00:00:00 2001 From: Gustav Odinger <65498475+gustavwilliam@users.noreply.github.com> Date: Tue, 23 Feb 2021 04:00:01 +0100 Subject: Add function to DM users when opening help channel --- bot/exts/help_channels/_message.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/bot/exts/help_channels/_message.py b/bot/exts/help_channels/_message.py index 2bbd4bdd6..12ac4035d 100644 --- a/bot/exts/help_channels/_message.py +++ b/bot/exts/help_channels/_message.py @@ -8,6 +8,7 @@ import bot from bot import constants from bot.exts.help_channels import _caches from bot.utils.channel import is_in_category +from bot.utils.messages import truncate_message log = logging.getLogger(__name__) @@ -92,6 +93,38 @@ async def is_empty(channel: discord.TextChannel) -> bool: return False +async def dm_on_open(message: discord.Message) -> None: + """ + DM claimant with a link to the claimed channel's first message, with a 100 letter preview of the message. + + Does nothing if the user has DMs disabled. + """ + embed = discord.Embed( + title="Help channel opened", + description=f"You claimed {message.channel.mention}.", + colour=bot.constants.Colours.bright_green, + timestamp=message.created_at, + ) + + embed.set_thumbnail(url=constants.Icons.green_questionmark) + embed.add_field( + name="Your message", value=truncate_message(message, limit=100), inline=False + ) + embed.add_field( + name="Want to go there?", + value=f"[Jump to message!]({message.jump_url})", + inline=False, + ) + + try: + await message.author.send(embed=embed) + log.trace(f"Sent DM to {message.author.id} after claiming help channel.") + except discord.errors.Forbidden: + log.trace( + f"Ignoring to send DM to {message.author.id} after claiming help channel: DMs disabled." + ) + + async def notify(channel: discord.TextChannel, last_notification: t.Optional[datetime]) -> t.Optional[datetime]: """ Send a message in `channel` notifying about a lack of available help channels. -- cgit v1.2.3 From e6483d633ac6ecc2a88051442108d9c88e5f7745 Mon Sep 17 00:00:00 2001 From: Gustav Odinger <65498475+gustavwilliam@users.noreply.github.com> Date: Tue, 23 Feb 2021 04:00:58 +0100 Subject: Add green question mark to default config Add green question mark to default config Add green question mark to config --- bot/constants.py | 1 + config-default.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/bot/constants.py b/bot/constants.py index 8a93ff9cf..69bc82b89 100644 --- a/bot/constants.py +++ b/bot/constants.py @@ -326,6 +326,7 @@ class Icons(metaclass=YAMLGetter): filtering: str green_checkmark: str + green_questionmark: str guild_update: str hash_blurple: str diff --git a/config-default.yml b/config-default.yml index 8e9a29a51..7d9afaa0e 100644 --- a/config-default.yml +++ b/config-default.yml @@ -90,6 +90,7 @@ style: filtering: "https://cdn.discordapp.com/emojis/472472638594482195.png" green_checkmark: "https://raw.githubusercontent.com/python-discord/branding/master/icons/checkmark/green-checkmark-dist.png" + green_questionmark: "https://raw.githubusercontent.com/python-discord/branding/master/icons/checkmark/green-question-mark-dist.png" guild_update: "https://cdn.discordapp.com/emojis/469954765141442561.png" hash_blurple: "https://cdn.discordapp.com/emojis/469950142942806017.png" -- cgit v1.2.3 From e34ea2f1c108d1900e251d17b38563536345d2de Mon Sep 17 00:00:00 2001 From: Gustav Odinger <65498475+gustavwilliam@users.noreply.github.com> Date: Tue, 23 Feb 2021 04:07:05 +0100 Subject: Send DM when user claims help channel --- bot/exts/help_channels/_cog.py | 1 + 1 file changed, 1 insertion(+) diff --git a/bot/exts/help_channels/_cog.py b/bot/exts/help_channels/_cog.py index 0995c8a79..a18ddc900 100644 --- a/bot/exts/help_channels/_cog.py +++ b/bot/exts/help_channels/_cog.py @@ -102,6 +102,7 @@ class HelpChannels(commands.Cog): await _cooldown.revoke_send_permissions(message.author, self.scheduler) await _message.pin(message) + await _message.dm_on_open(message) # Add user with channel for dormant check. await _caches.claimants.set(message.channel.id, message.author.id) -- cgit v1.2.3 From bb9e56c3cb874ef76ab82db02ce8242117e0da92 Mon Sep 17 00:00:00 2001 From: Gustav Odinger <65498475+gustavwilliam@users.noreply.github.com> Date: Tue, 23 Feb 2021 11:08:41 +0100 Subject: Update embed field title to be more formal --- bot/exts/help_channels/_message.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/exts/help_channels/_message.py b/bot/exts/help_channels/_message.py index 12ac4035d..95aca067a 100644 --- a/bot/exts/help_channels/_message.py +++ b/bot/exts/help_channels/_message.py @@ -111,7 +111,7 @@ async def dm_on_open(message: discord.Message) -> None: name="Your message", value=truncate_message(message, limit=100), inline=False ) embed.add_field( - name="Want to go there?", + name="Conversation", value=f"[Jump to message!]({message.jump_url})", inline=False, ) -- cgit v1.2.3 From cae0d84757e026976f1a9e87d52c581669b7b8e8 Mon Sep 17 00:00:00 2001 From: Gustav Odinger <65498475+gustavwilliam@users.noreply.github.com> Date: Tue, 23 Feb 2021 11:14:31 +0100 Subject: Use textwrap.shorten instead of custom function This applies to the help channel DM embed, where the user is sent a truncated version of their message. --- bot/exts/help_channels/_message.py | 6 ++++-- bot/utils/messages.py | 9 --------- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/bot/exts/help_channels/_message.py b/bot/exts/help_channels/_message.py index 95aca067a..4113e51c5 100644 --- a/bot/exts/help_channels/_message.py +++ b/bot/exts/help_channels/_message.py @@ -1,4 +1,5 @@ import logging +import textwrap import typing as t from datetime import datetime @@ -8,7 +9,6 @@ import bot from bot import constants from bot.exts.help_channels import _caches from bot.utils.channel import is_in_category -from bot.utils.messages import truncate_message log = logging.getLogger(__name__) @@ -108,7 +108,9 @@ async def dm_on_open(message: discord.Message) -> None: embed.set_thumbnail(url=constants.Icons.green_questionmark) embed.add_field( - name="Your message", value=truncate_message(message, limit=100), inline=False + name="Your message", + value=textwrap.shorten(message.content, width=100, placeholder="..."), + inline=False, ) embed.add_field( name="Conversation", diff --git a/bot/utils/messages.py b/bot/utils/messages.py index c01fa5d0e..077dd9569 100644 --- a/bot/utils/messages.py +++ b/bot/utils/messages.py @@ -154,12 +154,3 @@ async def send_denial(ctx: Context, reason: str) -> None: def format_user(user: discord.abc.User) -> str: """Return a string for `user` which has their mention and ID.""" return f"{user.mention} (`{user.id}`)" - - -def truncate_message(message: discord.Message, limit: int) -> str: - """Returns a truncated version of the message content, up to the specified limit.""" - text = message.content - if len(text) > limit: - return text[:limit-3] + "..." - else: - return text -- cgit v1.2.3 From d71ac9f6e240ffd2d4195d9dbbf5740a0c2413a1 Mon Sep 17 00:00:00 2001 From: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> Date: Tue, 23 Feb 2021 19:24:18 +0300 Subject: Fixes Problems With Help Channel DM Signed-off-by: Hassan Abouelela <47495861+HassanAbouelela@users.noreply.github.com> --- bot/exts/help_channels/_cog.py | 5 ++++- bot/exts/help_channels/_message.py | 8 +++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/bot/exts/help_channels/_cog.py b/bot/exts/help_channels/_cog.py index a18ddc900..6abf99810 100644 --- a/bot/exts/help_channels/_cog.py +++ b/bot/exts/help_channels/_cog.py @@ -102,7 +102,10 @@ class HelpChannels(commands.Cog): await _cooldown.revoke_send_permissions(message.author, self.scheduler) await _message.pin(message) - await _message.dm_on_open(message) + try: + await _message.dm_on_open(message) + except Exception as e: + log.warning("Error occurred while sending DM:", exc_info=e) # Add user with channel for dormant check. await _caches.claimants.set(message.channel.id, message.author.id) diff --git a/bot/exts/help_channels/_message.py b/bot/exts/help_channels/_message.py index 4113e51c5..36388f9bd 100644 --- a/bot/exts/help_channels/_message.py +++ b/bot/exts/help_channels/_message.py @@ -107,11 +107,9 @@ async def dm_on_open(message: discord.Message) -> None: ) embed.set_thumbnail(url=constants.Icons.green_questionmark) - embed.add_field( - name="Your message", - value=textwrap.shorten(message.content, width=100, placeholder="..."), - inline=False, - ) + formatted_message = textwrap.shorten(message.content, width=100, placeholder="...") + if formatted_message: + embed.add_field(name="Your message", value=formatted_message, inline=False) embed.add_field( name="Conversation", value=f"[Jump to message!]({message.jump_url})", -- cgit v1.2.3 From 44eb00ca03dae1b3d5faf40be63fae04ca515790 Mon Sep 17 00:00:00 2001 From: Matteo Bertucci Date: Wed, 24 Feb 2021 18:27:25 +0100 Subject: Add off-topic etiquette to the off-topic tag --- bot/resources/tags/off-topic.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/bot/resources/tags/off-topic.md b/bot/resources/tags/off-topic.md index c7f98a813..6a864a1d5 100644 --- a/bot/resources/tags/off-topic.md +++ b/bot/resources/tags/off-topic.md @@ -6,3 +6,5 @@ There are three off-topic channels: • <#463035268514185226> Their names change randomly every 24 hours, but you can always find them under the `OFF-TOPIC/GENERAL` category in the channel list. + +Please read our [off-topic etiquette](https://pythondiscord.com/pages/resources/guides/off-topic-etiquette/) before participating in conversations. -- cgit v1.2.3